拓冰建站拓冰建站
首页 / 资讯中心 / 正文

TOPSIS多属性决策算法:原理、Python实现与熵权法实战

1. 从“选谁”到“怎么选”TOPSIS法的现实困境与价值做项目、评绩效、选方案甚至挑个餐厅我们总会遇到一个经典问题面对一堆各有优劣的选项到底哪个才是“最好”的这可不是拍脑袋就能决定的。比如公司要采购一批服务器A型号性能强但价格贵B型号价格便宜但稳定性一般C型号各方面均衡但售后一般。你怎么选给每个指标打个分然后简单加总那性能的“1分”和价格的“1分”能一样重要吗显然不能。这就是多属性决策的难题。而TOPSIS法全称“逼近理想解排序法”就是为解决这类问题而生的一个数学工具。它不告诉你“应该”选哪个而是帮你把一堆复杂的、量纲不一的指标通过一套严谨的数学流程转化成一个清晰的、可比较的优劣排序。简单说它帮你把“感觉”变成了“数据”。我第一次接触TOPSIS是在一个供应链供应商评估项目里。当时手头有十几家供应商评价指标多达二十几个成本、交货准时率、质量合格率、研发能力、地理位置等等单位五花八门。最初想用加权平均立刻被老同事叫停“成本和合格率能直接相加吗一万元和一个百分比这单位都不一样加出来是啥” 这才意识到没有经过标准化的数据直接运算就像把米和厘米直接相加一样荒谬。TOPSIS的核心魅力就在于它先通过数学方法把所有指标拉到同一个“赛场”上消除量纲影响再计算每个方案与“理想中最好方案”和“理想中最差方案”的距离最后根据相对接近度来排序。这个思路非常直观最好的方案不就是离所有好处最近、离所有坏处最远的那个吗2. TOPSIS法的核心原理寻找“理想”与“噩梦”的中间点理解TOPSIS关键在于理解它的名字Technique for Order Preference by Similarity to Ideal Solution。我们拆开来看。2.1 构建决策矩阵把现实问题装进表格首先我们需要把问题结构化。假设有m个待评价方案比如m家供应商n个评价指标比如价格、质量、服务等。那么我们就可以构建一个m行n列的矩阵这就是决策矩阵。每一行代表一个方案每一列代表一个指标。这是所有计算的基础。方案指标1成本/万元指标2合格率/%指标3交货期/天供应商A1009510供应商B809015供应商C120985这张表一目了然但也立刻暴露了问题成本是越小越好效益型合格率是越大越好成本型交货期也是越小越好。它们的单位万元、百分比、天也完全不同。直接比较毫无意义。2.2 指标同趋化与无量纲化统一比赛的“度量衡”这是TOPSIS的第一步也是最容易出错的一步。目的是把所有指标都转化为“越大越好”的类型并消除量纲。同趋化对于成本型指标越小越好常用的方法是取倒数或用最大值减去该值。例如对于成本我们可以用1 / 原值或max(成本列) - 原值使其转化为数值越大代表越好的指标。在实际编程中更稳健的做法是设置一个方向参数对成本型指标进行原值 * -1处理但后续标准化步骤会处理正负问题。更常见的做法是在构建矩阵时就明确每个指标的类型在后续计算中区别对待。标准化归一化这是消除量纲的关键。TOPSIS通常采用向量归一化法。对于决策矩阵中的每一个元素 \(x_{ij}\)第i个方案的第j个指标值其标准化值 \(z_{ij}\) 的计算公式为\[ z_{ij} \frac{x_{ij}}{\sqrt{\sum_{i1}^{m} x_{ij}^2}} \]这个公式的意思是将每个原始值除以该指标所在列所有值的平方和的平方根。经过这样处理每个指标下所有方案的标准化值其平方和等于1。这彻底消除了量纲并且将所有数值压缩到[0,1]区间严格来说由于分母是平方和的开方\(z_{ij}\) 的绝对值不会超过1。为什么用这个而不是常见的(x - min)/(max - min)因为向量归一化在几何上有一个非常好的性质它保持了各方案在n维空间中的相对位置关系。TOPSIS后续计算的是欧氏距离使用向量归一化后的数据能保证距离计算的几何意义不变。2.3 确定加权标准化矩阵给指标加上“重要性”砝码标准化后所有指标平等了但它们的“重要性”或“权重”显然不同。采购时成本可能比交货期更重要。因此我们需要给每个指标赋予一个权重 \(w_j\)且满足 \(\sum_{j1}^{n} w_j 1\)。加权标准化矩阵 \(V\) 的元素 \(v_{ij}\) 计算很简单 \[ v_{ij} w_j * z_{ij} \] 这样重要的指标在后续距离计算中就会占据更大的影响。权重的确定本身就是一个大学问。常见方法有主观赋权法如德尔菲法、层次分析法AHP。依赖专家经验但可能主观性强。客观赋权法如熵权法。根据各指标数据本身的离散程度信息熵来计算权重数据差异越大说明该指标区分方案的能力越强权重就越高。这也是“熵权TOPSIS”一词的由来它用熵权法来确定TOPSIS中的权重 \(w_j\)使得评价结果更依赖数据本身减少主观性。2.4 确定理想解与负理想解定义“天花板”和“地板”这是TOPSIS思想的精髓所在。理想解正理想解\(V^\)它是一个虚拟的方案由每个指标在加权标准化矩阵 \(V\) 中的最优值构成。对于效益型指标越大越好取该列最大值对于成本型指标经过同趋化后也已变为越大越好同样取该列最大值。 \[ V^ (v_1^, v_2^, ..., v_n^) (\max(v_{1j}), \max(v_{2j}), ..., \max(v_{mj})) \]负理想解最劣解\(V^-\)同样是一个虚拟方案由每个指标在 \(V\) 中的最差值构成即每列的最小值。 \[ V^- (v_1^-, v_2^-, ..., v_n^-) (\min(v_{1j}), \min(v_{2j}), ..., \min(v_{mj})) \]你可以把 \(V^\) 想象成所有方案优点的集合体是“理想中的完美方案”把 \(V^-\) 想象成所有方案缺点的集合体是“理想中的最差方案”。2.5 计算距离与相对贴近度测量与“完美”和“最差”的差距接下来计算每个真实方案与这两个虚拟方案的距离。TOPSIS默认使用欧氏距离。方案i到理想解的距离 \(S_i^\) \[ S_i^ \sqrt{\sum_{j1}^{n} (v_{ij} - v_j^)^2} \]方案i到负理想解的距离 \(S_i^-\) \[ S_i^- \sqrt{\sum_{j1}^{n} (v_{ij} - v_j^-)^2} \]最后计算每个方案的相对贴近度 \(C_i\) \[ C_i \frac{S_i^-}{S_i^ S_i^-} \]\(C_i\) 的取值范围在0到1之间。它的含义非常直观一个方案离理想解越近\(S_i^\) 越小同时离负理想解越远\(S_i^-\) 越大那么 \(C_i\) 值就越接近1。因此我们可以根据 \(C_i\) 的大小对所有方案进行排序\(C_i\) 值最大的方案就是最优方案。3. 从理论到代码手把手实现TOPSIS算法理解了原理我们用一个完整的Python示例来走一遍流程。假设我们要评价3个投资项目方案考虑4个指标投资回报率%越大越好、风险系数等级1-5越小越好、实施周期月越小越好、所需团队规模人越小越好。3.1 数据准备与同趋化import numpy as np import pandas as pd # 原始决策矩阵 data: [方案A, 方案B, 方案C] # 列顺序回报率 风险系数 周期 团队规模 data np.array([ [15, 2, 12, 8], # 方案A [12, 4, 8, 5], # 方案B [18, 3, 18, 10] # 方案C ]) # 定义指标类型1表示效益型越大越好0表示成本型越小越好 indicator_types np.array([1, 0, 0, 0]) # 同趋化处理将成本型指标转化为效益型这里采用最大值减去原值法 data_normalized data.copy().astype(float) for col in range(data.shape[1]): if indicator_types[col] 0: # 成本型指标 data_normalized[:, col] np.max(data[:, col]) - data[:, col] # 此时所有指标都是越大越好了 print(同趋化后矩阵\n, data_normalized)3.2 向量归一化标准化# 向量归一化 norms np.sqrt(np.sum(data_normalized**2, axis0)) # 计算每列的范数 Z data_normalized / norms # 标准化矩阵 Z print(标准化矩阵 Z\n, np.round(Z, 4))3.3 确定权重与计算加权矩阵假设我们通过AHP或熵权法得到权重为[0.4, 0.3, 0.2, 0.1]。weights np.array([0.4, 0.3, 0.2, 0.1]) V Z * weights # 加权标准化矩阵 V print(加权标准化矩阵 V\n, np.round(V, 4))3.4 确定理想解与负理想解# 因为经过同趋化所有指标都是效益型越大越好 V_positive np.max(V, axis0) # 理想解 V_negative np.min(V, axis0) # 负理想解 print(理想解 V: , np.round(V_positive, 4)) print(负理想解 V-: , np.round(V_negative, 4))3.5 计算距离与相对贴近度# 计算各方案到理想解和负理想解的距离 S_positive np.sqrt(np.sum((V - V_positive) ** 2, axis1)) S_negative np.sqrt(np.sum((V - V_negative) ** 2, axis1)) print(到理想解距离 S: , np.round(S_positive, 4)) print(到负理想解距离 S-: , np.round(S_negative, 4)) # 计算相对贴近度 C S_negative / (S_positive S_negative) print(相对贴近度 C: , np.round(C, 4)) # 排序 ranking np.argsort(-C) # 降序排列的索引 print(方案排序从优到劣: , ranking) print(对应贴近度: , C[ranking])运行这段代码你就能得到三个项目的优劣排序。这个完整的流程封装起来就是一个最基本的TOPSIS评价函数。注意在实际项目中原始数据的同趋化处理需要格外小心。对于“风险系数”这类已经是数值型的成本指标用max - x是可行的。但对于“品牌知名度”定性指标如高、中、低需要先量化为数值如3,2,1再进行同趋化。确保所有指标在数学处理前都具有合理的、方向明确的数值意义。4. 权重确定的核心熵权法原理与实现TOPSIS的权重 \(w_j\) 对结果影响巨大。熵权法是一种客观赋权法其核心思想是某个指标的信息熵越小表明其值的变异程度越大提供的信息量越多在综合评价中所起的作用越大权重也应越高。4.1 熵权法的计算步骤假设我们有标准化后的矩阵 \(Z\)m个方案n个指标其元素为 \(z_{ij}\)。计算第j项指标下第i个方案的比重 \(p_{ij}\) \[ p_{ij} \frac{z_{ij}}{\sum_{i1}^{m} z_{ij}} \] 这里要求 \(z_{ij}\) 非负。由于我们之前用的向量归一化可能产生负值如果原始数据有负值因此熵权法通常要求先对数据进行非负化处理比如采用“比重法”标准化\(z_{ij} \frac{x_{ij}}{\sum_{i1}^{m} x_{ij}}\)或者用(x - min)/(max - min)。这一点与TOPSIS本身的标准化方法可能不同需要特别注意。计算第j项指标的熵值 \(e_j\) \[ e_j -k \sum_{i1}^{m} p_{ij} \ln(p_{ij}) \] 其中\(k 1 / \ln(m)\)是为了保证 \(0 \le e_j \le 1\)。当某个指标下所有方案的值完全相同时\(p_{ij}1/m\)此时熵值 \(e_j\) 取最大值1意味着该指标毫无区分度提供的信息量为零。计算第j项指标的差异系数 \(g_j\) \[ g_j 1 - e_j \] \(g_j\) 越大说明该指标越重要。计算权重 \(w_j\) \[ w_j \frac{g_j}{\sum_{j1}^{n} g_j} \]4.2 Python实现熵权法def entropy_weight(data): 计算熵权法权重 data: 决策矩阵每行一个方案每列一个指标。假设所有指标均为效益型或已同趋化。 # 1. 数据非负化这里采用min-max归一化到[0,1]保证非负且和为1的性质 data data.astype(float) data_min np.min(data, axis0) data_max np.max(data, axis0) data_range data_max - data_min # 避免除零 data_range[data_range 0] 1 data_norm (data - data_min) / data_range # 2. 计算比重 p_ij p data_norm / np.sum(data_norm, axis0, keepdimsTrue) # 避免ln(0)的情况用一个极小值替换0 p np.where(p 0, 1e-10, p) # 3. 计算熵值 e_j m data.shape[0] k 1 / np.log(m) e -k * np.sum(p * np.log(p), axis0) # 4. 计算差异系数和权重 g 1 - e w g / np.sum(g) return w, e, g # 使用同趋化后的 data_normalized 计算熵权 weights_entropy, entropy_values, diff_coefficients entropy_weight(data_normalized) print(各指标熵值 e: , np.round(entropy_values, 4)) print(各指标差异系数 g: , np.round(diff_coefficients, 4)) print(熵权法计算所得权重 w: , np.round(weights_entropy, 4))将计算出的weights_entropy代入到前面TOPSIS流程的权重部分就完成了“熵权TOPSIS”模型。这种方法减少了主观随意性但当某个指标下数据差异极小时其权重会被压得非常低这有时可能与业务常识相悖需要结合实际情况判断。5. TOPSIS实战中的常见“坑”与应对策略TOPSIS原理清晰实现也不复杂但在实际业务应用中新手很容易踩进几个坑里。5.1 指标类型与同趋化处理的混淆这是最常见的错误。很多人拿到数据不管三七二十一就直接标准化完全忽略了指标本身的方向性。例如“故障率”是成本型指标越小越好如果你错误地把它当成效益型指标那么标准化后故障率低的方案反而会得到低分结果完全颠倒。实操心得在构建决策矩阵的第一步就明确记录每个指标的类型。可以定义一个数组如criteria_type [‘benefit’ ‘cost’ ‘cost’ ...]或直接用[1 0 0 ...]标记。在代码中根据这个标记数组进行同趋化处理。处理完成后务必打印出同趋化后的矩阵检查一遍确保所有指标数值大的方向都代表“好”。5.2 标准化方法的选择与误用TOPSIS的经典论文中使用的是向量归一化。但很多人会混淆使用Min-Max归一化(x-min)/(max-min)。这两种方法在数学性质上不同。Min-Max归一化后每个指标的最大值变为1最小值变为0这会改变各方案在空间中的相对距离比例。虽然有时也能用但已不是标准TOPSIS其几何解释和理论依据会发生变化。避坑指南除非有特殊理由否则在TOPSIS中坚持使用向量归一化。它的几何意义明确且能保持数据相对结构。如果你看到别人的代码或论文中用了其他标准化方法需要警惕其评价结果是否仍然严格符合TOPSIS的定义。5.3 权重的主观性与数据敏感性TOPSIS的结果对权重极其敏感。即使使用熵权法也存在问题。熵权法完全依赖数据本身的离散程度。假设“政治面貌”这个指标在所有方案中取值都一样比如都是“党员”那么它的熵值为1差异系数为0权重就是0。这从信息论角度看合理但从业务角度看这个指标可能非常重要是一个硬性门槛。此时就需要引入主观权重进行修正例如采用AHP-熵权组合赋权。经验技巧不要完全依赖某一种赋权方法。建议的流程是1用熵权法计算一组客观权重2邀请领域专家用AHP等方法得出一组主观权重3采用线性组合如各占50%或更复杂的博弈论组合方法得到综合权重。这样既能反映数据规律又能体现业务要求。5.4 理想解与负理想解的“极端性”问题TOPSIS寻找的是离“理想中最好”最近、离“理想中最差”最远的方案。但这个“理想最好”可能是一个在现实中根本无法实现的“超人”方案所有指标都取到极致。这可能导致评价结果偏向于“均衡型”方案而轻微惩罚了在某些指标上特别突出、但在另一些指标上稍弱的“偏科生”方案。在某些鼓励创新或需要长板的场景下这可能不是最优的评价思路。应对策略理解TOPSIS的这一特性。如果你的业务场景就是寻找“没有短板”的稳健方案那么TOPSIS很合适。如果你是在寻找“有颠覆性优势”的方案可能需要考虑其他方法如VIKOR侧重群体效用和个体遗憾的折中或结合TOPSIS与灰色关联分析。5.5 结果解读与可视化计算出贴近度 \(C_i\) 后不能只看排序。要分析每个方案的 \(S_i^\) 和 \(S_i^-\)。如果第一名和第二名的 \(C\) 值非常接近比如0.82 vs 0.81而第三名只有0.65那么前两名可以认为是同一梯队第三名则差距明显。可以用雷达图同时绘制多个方案的标准化后指标值直观看出各方案的优劣势分布。import matplotlib.pyplot as plt import numpy as np # 假设有3个方案4个指标数据为标准化后的值 labels [指标A, 指标B, 指标C, 指标D] data np.array([[0.9 0.7 0.8 0.6], [0.7 0.9 0.6 0.8], [0.8 0.6 0.9 0.7]]) angles np.linspace(0 2*np.pi len(labels) endpointFalse).tolist() data np.concatenate((data data[: [0]]) axis1) # 闭合 angles angles[:1] fig ax plt.subplots(figsize(66) subplot_kwdict(projectionpolar)) for i in range(len(data)-1): ax.plot(angles data[i] o-’ labelf‘方案{i1}’) ax.fill(angles data[i] alpha0.1) ax.set_xticks(angles[:-1]) ax.set_xticklabels(labels) ax.set_ylim(0 1) plt.legend(locupper right) plt.title(方案指标对比雷达图) plt.show()这张图能让你一眼看出方案1在指标A上优势明显方案2在指标B和D上突出方案3在指标C上领先。结合TOPSIS的排序决策就更有依据了。TOPSIS是一个强大而直观的工具但它不是“一键万能”的魔术。理解其原理谨慎处理数据明确权重来源合理解读结果才能让它真正成为你应对复杂决策问题的得力助手。在实际项目中我通常会先用TOPSIS跑出一个基准排序再结合业务部门的讨论和敏感性分析比如微调权重看排序是否稳定最终形成一个经得起推敲的推荐方案。记住模型是辅助决策的而不是代替决策。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门