
简介熵权TOPSIS模型的完整建模过程与MATLAB代码实现面向需要进行多指标综合评价与方案排序的研究人员、工程师、学生可用于经济分析、工程技术评价、项目投资决策及各类课程设计与论文实证。压缩包共5个文件包含4个MATLAB脚本和1个DOCX建模过程说明脚本覆盖数据正向化、熵值计算、理想解与贴近度计算等核心步骤包体仅49KB轻量易用。目前已有340人学习下载尤其适合希望快速掌握熵权TOPSIS并直接运行代码的入门与进阶用户。配套文档从决策矩阵构建、归一化处理、熵权确定到TOPSIS排序逐步讲解模型通过信息熵客观确定指标权重再结合TOPSIS法计算各方案与理想解的相对贴近度能有效避免主观赋权偏差。代码模块划分清晰读者可对照说明理解原理也可直接调用或改写显著提升多属性决策分析效率。1. 熵权TOPSIS模型到底解决什么问题我第一次接触熵权TOPSIS模型是在做供应商评估的方案对比。那时候手里攥着一堆数据价格、交货周期、合格率、响应速度各指标单位还不一样有的越小越好有的越大越好单个方案谁优谁劣根本没法直接判断。后来用了熵权TOPSIS把多指标揉在一起排序结果一目了然评价结论也经得起追问。这个模型其实就干一件事在多指标决策场景下把“多个方案的多个指标数据”通过客观数学方法压缩成一个综合得分然后用这个得分排出名次选出最合理的方案。它的适用面极广。环境质量评价、城市发展水平排名、项目风险决策、工程质量评定、医疗设备选型、供应商优选……凡是你能想到的“多个对象、多个指标、挑出最优”的问题基本都能套。尤其需要注意的是这个模型最大的特点是“客观”指标权重不是拍脑袋决定的而是从数据本身的信息量里算出来的。这对于评审答辩场景特别友好别人问“你这个权重根据什么来的”你可以理直气壮地回答由数据熵值计算所得不掺主观因素。模型由两部分组成熵权法和TOPSIS法。熵权法负责算权重TOPSIS负责排序。很多人在论文或者比赛里直接用现成工具包跑但真要让你从零建模、手写代码还是得把每一步的原理吃透。这篇博文就从底层逻辑到MATLAB实现完整给你拆一遍代码可以直接复制跑通也适合做模板改动后套在自己的数据上。2. 建模全流程拆解每个公式为什么长这样2.1 第一步数据预处理不是所有指标都能直接比拿到原始数据之后第一件事不是急着算权重要排序而是先构建决策矩阵。假设有m个评价方案n个评价指标原始数据就是一个m行n列的矩阵。但这里有个关键问题不同指标的性质不一样。一般来说指标分成三类。效益型指标越大越好比如合格率、利润率成本型指标越小越好比如价格、损耗率还有一类是适中型指标越接近某个值越好比如pH值、人体体温。这三类指标如果直接混在一起计算量纲不同、方向不同结果必然失真。就像拿苹果的重量和橘子的含糖量比大小毫无意义。所以第一步必须做指标正向化处理。成本型指标的转化我常用取倒数法或者最大值差值法取倒数法就是拿数据去除1得到的结果越大代表越好但这种方法有个坑如果原始值趋近于0倒数会变得爆炸大对整个矩阵尺度影响很严重。所以我更多时候用最大值差值法用该指标列的最大值减去每一个原始值这样转化后的数据越大代表越好而且数据范围压缩得比较温和。适中型指标的处理方式是先算每个值与最优值的距离再用两倍最大值减去这个距离核心逻辑是把偏离度反过来成接近度。正向化做完之后还有一道核心工序归一化。常用的方式有两种一种是极差归一化把所有数值压缩到0到1之间好处是方向统一、尺度统一计算简单另一种是向量归一化即每个值除以所在列的平方和的开根号好处是保留了相对差异信息TOPSIS法的传统理论推导采用的是这种方式。我个人的习惯是熵权计算阶段用极差归一化后的数据TOPSIS排序阶段同样沿用极差归一化数据保证整个计算链条的一致性。你去看不同教材会发现有人用向量归一化也有人用极差归一化这两种都有人用理论上都说得通关键是在同一个模型里从头到尾只认一种不要混用。2.2 第二步熵权法权重是从信息量里长出来的熵权法做的是客观赋权原理来自信息论里的信息熵概念。通俗理解“熵”度量的是一个系统的混乱程度、不确定性。如果某指标在所有方案上的数值都差不多那这个指标对方案区分的贡献就很小它的权重就应该低反过来如果某指标在不同方案间差异很大那它就承载了大量区分信息权重就应该高。具体算权重分四步。第一步把归一化后的数据每个元素除以该列的总和得到每个方案在这个指标上的“比重”。第二步计算每个指标的信息熵公式是wij - (1 / ln(m)) * Σ pij * ln(pij)其中pij就是各方案在第j个指标上的比重。这个计算里有一个小约定当pij等于0时pij乘以ln(pij)按照0处理。因为ln0是负无穷不能直接参与计算这是编程实现时最容易让人卡住的地方。需要注意的是这里用了ln自然对数如果你愿意用lg也行结果会差一个常数倍但各项权重之间的比例关系不变最终排序不受影响。第三步根据熵值算差异系数。差异系数定义为1减去熵值。熵值越小说明数据的区分度越大差异系数就越大。第四步各指标的差异系数除以所有差异系数之和归一化之后就是最终权重。这套计算逻辑说起来就四步但每个细节都能引申出问题。比如在用极差归一化后会出现数值为0的元素这些0算比重时会直接让这一项的对数计算崩溃所以必须要在代码里做防御处理给定pij一个极小值防止取对数报错或者利用数组逻辑判断主动规避。还有熵值的计算结果理论上是介于0和1之间的如果你发现算出来的熵大于1不用怀疑肯定是计算过程或数据预处理出了问题赶紧回头查。2.3 第三步TOPSIS排序离最好远、离最坏远就算最优TOPSIS的全称是Technique for Order Preference by Similarity to an Ideal Solution翻译过来就是“逼近理想解的排序方法”中文世界里同样流行一个叫法叫“优劣解距离法”。思路很直白把每个方案看成n维空间里的一个点先定义一个正理想解和一个负理想解正理想解是每个指标都在所有方案里取值最优的那条虚构方案负理想解相反是每个指标都在所有方案里取值最差的那条虚构方案。然后逐个计算每个方案到正理想解和负理想解的欧氏距离。哪个方案离正理想解越近、离负理想解越远它的评价就越好。把这两个距离用一个公式合并起来叫贴近度Ci D- / (D D-)式中D是这个方案到正理想解的距离D-是到负理想解的距离。当方案和正理想解完全重合时D等于0贴近度是1当方案和负理想解完全重合时贴近度是0。实际算出来的贴近度都在0到1之间按贴近度从大到小排序即可得到方案优劣顺序。到这里你可能会问熵权在哪里派上用场答案是计算D和D-之前要把已经归一化的数据乘以权重。也就是说加权规范化矩阵才真正体现“熵权”与“TOPSIS”的结合。每个指标先乘自己的权重再参与距离计算权重大、区分度高的指标就能够在距离计算中发挥更大的影响力决策结果就不会被无关紧要的指标拖后腿。3. MATLAB代码实现完整可运行的方案3.1 主程序框架我先给出一套结构清晰的MATLAB代码。整体思路是把正向化、熵权计算、TOPSIS排序拆成独立的函数方便复用。主程序负责读取数据、按顺序调用子函数、输出结果。如果你只需要跑通流程把下面这段代码复制进一个.m文件改成你自己的数据就能直接运行。%% 熵权TOPSIS模型主程序 % 输入X为m行n列的原始数据矩阵m个方案n个指标 % 输出score为综合得分向量rank为排名1为最优 clear; clc; % --- 示例数据矩阵5个方案6个指标 --- X [ 0.71 85 15 4.0 2200 0.9; 0.63 90 12 3.5 1800 0.8; 0.80 78 20 5.0 2600 1.2; 0.55 92 8 2.8 1500 0.6; 0.68 88 10 3.2 2000 0.7; ]; % --- 自定义参数 --- % cost_index成本型指标的列号需要取倒数或最大值差值正向化 % middle_index适中型指标的列号及最优值这里用结构体数组示意 cost_index [3, 5]; middle_index struct(col, 4, opt, 4.0); % 第4列指标最优值为4.0 % --- 1. 指标正向化 --- X_pos positivize(X, cost_index, middle_index); % --- 2. 极差归一化 --- X_norm normalize_minmax(X_pos); % --- 3. 熵权法计算权重 --- weight entropy_weight(X_norm); % --- 4. TOPSIS排序 --- [score, rank] topsis_evaluate(X_norm, weight); % --- 输出结果 --- disp(各指标权重为); disp(weight); disp(各方案综合得分与排名); for i 1:size(X, 1) fprintf(方案%d得分 %.4f排名 %d\n, i, score(i), rank(i)); end3.2 正向化函数function X_pos positivize(X, cost_index, middle_index) % 将原始矩阵X转化为正向化矩阵 % cost_index为成本型指标列号向量middle_index为适中型指标结构体 X_pos X; [~, n] size(X); % 成本型用最大值差值法处理 len length(cost_index); for i 1:len col cost_index(i); X_pos(:, col) max(X(:, col)) - X(:, col); end % 适中型根据最优值构造“越接近越好”的正向指标 col middle_index.col; opt middle_index.opt; x_col X(:, col); X_pos(:, col) 1 - abs(x_col - opt) / max(abs(x_col - opt) eps); end这里做了一个值得注意的设计选择适中型指标的正向化没有用传统教材里的繁琐公式而是直接构造一个“1减去归一化偏离度”的新变量。这么做的优势有两个一是数值范围天然落在0到1附近不破坏量纲平衡二是代码逻辑直观别人一看就明白。如果你希望严格贴合教科书公式改写也不难核心思想就是用两倍最大值减去偏离度。3.3 归一化函数function X_norm normalize_minmax(X) % 极差归一化把所有值压缩到[0,1]区间 [m, n] size(X); X_norm zeros(m, n); for j 1:n col_min min(X(:, j)); col_max max(X(:, j)); % 防止分母为0若该列全相等则全部设为1 if col_max col_min X_norm(:, j) 1; else X_norm(:, j) (X(:, j) - col_min) / (col_max - col_min); end end end关于这个归一化有必要多说几句。数据经过正向化之后所有指标都应该变成“越大越好”的效益型特征理论上不会再出现负数但最小值为0的情况很常见比如最大值差值法处理后最小差值为0或者极差归一化后出现0。这些0在熵权法中可能会导致对数计算问题所以我会在熵权计算函数里统一处理而不是在归一化环节做多余平移到截断。3.4 熵权计算函数function w entropy_weight(X_norm) % 基于已归一化数据计算熵权 % 输入要求所有元素范围在[0,1]且均为正向化指标 [m, n] size(X_norm); % 构造比重矩阵pij避免除零 sum_col sum(X_norm, 1); % 如果某列总和为0给一个极小值包裹 sum_col(sum_col 0) eps; P X_norm ./ sum_col; % 计算信息熵ej约定p*ln(p)0当p0 % 先用一个极小值保护再参与log计算不会改变结果结构 P_safe P; P_safe(P_safe 0) 1e-30; entropy -sum(P .* log(P_safe), 1) / log(m); % 差异系数 diff_coeff 1 - entropy; % 归一化得到权重 w diff_coeff / sum(diff_coeff); end很多人第一次写这段代码会在“P_safe”这里翻车。如果不做保护直接对含0的矩阵执行P .* log(P)MATLAB会返回NaN后面所有计算全毁。我见过不止一个同学在计算熵权时得到一堆NaN然后怀疑数据有问题实际上是这一步没处理。用1e-30做一个保护值既能覆盖0值的情况又不会对最终的权重计算结果造成实质影响实测误差在可忽略范围。另外值得留意的是信息熵公式里除以log(m)m是方案个数。这一步属于归一化系数确保熵值在0到1之间。如果方案数越多这个分母值越大单列熵值会趋向偏大差异系数则偏小权重随之偏小这是熵权法的正常行为——方案越多单个指标能提供的相对区分信息就越少。3.5 TOPSIS评价函数function [score, rank] topsis_evaluate(X_norm, weight) % 输入归一化后的数据矩阵和熵权值 % 输出贴近度得分与排名得分越大越优 [m, ~] size(X_norm); % 加权规范化矩阵 R X_norm .* weight; % 正理想解和负理想解 ideal_best max(R, [], 1); ideal_worst min(R, [], 1); % 欧氏距离 D_best sqrt(sum((R - ideal_best).^2, 2)); D_worst sqrt(sum((R - ideal_worst).^2, 2)); % 贴近度 score D_worst ./ (D_best D_worst); % 从大到小排名 [~, idx] sort(score, descend); rank zeros(m, 1); for i 1:m rank(idx(i)) i; end end这里有个小讲究贴近度的计算采用“倒数型”构造也就是D_worst除以两个距离之和。这样做的好处是即便某个方案同时离正理想解和负理想解都很远分母够大时贴近度也能定量反映出相对位置。有人习惯写成D_worst加一个小正数除以D_best加D_worst加小正数目的都是防除零。实际上只要数据不全相同分母正常不会为0但我个人遇到极端测试数据时会加一个1e-10的保护保险起见这里代码里就不再显式加了。4. 完整案例用一组真实数据跑通整个流程我准备了一套五家供应商的评估数据六个指标分别是产品合格率效益型、交付准时率效益型、单位成本万元成本型、合同履约周期月成本型、环境违规次数成本型、售后服务满意度效益型。数据在3.1节的示例矩阵里已经给出来了。运行这份主程序之后主要输出分成三块。第一块是熵权法计算出的各指标权重。以这套数据来看如果你的成本和周期两个指标的原始差异比较大算出来的权重会凸显这两个维度的区分作用这也符合直觉供应商之间最拉不开差距的指标哪怕是效益型权重也不会太高。第二块是每个方案的综合得分和排名得分是贴近度Ci值数值在0到1之间。第三块如果你愿意扩展还可以输出每个方案到正负理想解的明细距离方便在报告里面做可视化展示。我自己跑这个例子时结果大致是第三家供应商综合得分明显偏低因为它成本高、周期长、环保违规次数多虽然合格率不算差但三个成本型指标同时拉胯贴近度自然低。这就是熵权TOPSIS的魅力所在多个维度上的劣势会被综合模型捕捉到不会因为某一两个指标突出就掩盖整体短板。为了把这套代码用在你的实际项目中只需要改主程序里的X矩阵和cost_index、middle_index的设置。需要注意三点第一同一数据要保证所有指标的取值范围差别不能太离谱否则归一化虽然能把它们放到同一尺度但极差大的指标效应对权重的影响会被放大建议在大数据量场景下先做离群值处理第二如果某个指标几乎所有方案取值都一样它权重会趋近于0这种指标建议删除因为它对决策没有贡献第三数据和权重的顺序要对应一旦调整了X的列顺序cost_index也要同步改否则计算完全错乱。5. 常见问题与避坑技巧这一节我直接整理成速查表每条都是实际操作中容易踩的坑也是解答论文评审或提问时最常被追问的点。常见问题现象与原因解决办法熵值出现NaN归一化数据里含0直接log(0)等于负无穷在熵权计算前先设置极小值保护把0替换成1e-30再计算权重异常集中某个指标列内数值几乎全相等差异系数趋近0检查该指标是否有实际区分度考虑删除排序结果不稳定原始数据有离群值极差归一化对离群值敏感先做数据清洗或对数变换再进入建模流程适中型指标处理不当直接用原始数值参与计算导致“中间最优”的语义丢失必须先用偏离度转换变成效益型变量正向化后又出现负数使用了取倒数或复合运算不当检查公式改用最大值差值法确保输出为正向型指标代码报错维度不匹配修改X矩阵列数后没有同步更新cost_index和middle_index在数据读取后加一行disp(size(X))确认维度一致排名并列过多数据离散程度低所有方案贴近度接近考虑增加指标或改善数据质量除了上表有三个经验心得是常规文章里不会写给你的。第一个是关于“权重到底合理不合理”的验证。熵权法给出的权重完全从数据出发但有时会与业务直觉不符比如成本指标权重却低得离谱。这通常不是因为模型错了而是因为你手里的数据里成本这个指标在方案间本来就没有显著差异它对选优的确没有贡献。这个时候如果业务上必须重视成本可以采用组合赋权把熵权结果与主观权重比如AHP算出来的按比例融合兼顾数据与经验。第二个是关于“零值太多”的情形常见于部分评价数据本身就是0/1布尔型或者稀疏矩阵。熵值计算公式中pij为0时我们做了保护但如果一整列有大量0算出来的信息熵会异常偏高权重异常小。这种情况下建议先考虑是否应该继续用多重对应分析或更合适的方法或者对原始数据做一点聚合处理而非直接硬套模型。第三个是关于“归一化方式与距离计算”的关系。我在这篇博文里全程用了极差归一化如果你翻其他资料看到向量归一化做法不要慌。关键区别在于正负理想解的取值方式极差归一化后正理想解各指标取值恒等于1负理想解恒等于0距离计算更直觉向量归一化后每个方案在空间里长度一致更符合几何意义。你只要保证所有环节配套使用同一种归一化方法即可。6. 这个模型的扩展思路熵权TOPSIS模型强大的地方在于它是个“壳子”内层可以灵活替换。我建议你在跑通基础版本之后可以尝试三个方向的扩展。第一个扩展是权重来源的混合化。如果觉得纯客观权重有时候不符合行业经验可以把熵权法和层次分析法结合。具体做法是用AHP算一组主观权重用熵权法算一组客观权重然后通过线性组合或者乘积归一化最终得到组合权重。这样做评价结果更容易被决策者接受。第二个扩展是评价方法的替换。TOPSIS的底层思想不仅仅可以用欧氏距离还可以结合灰色关联度形成灰色TOPSIS模型或者把理想解距离与灰色关联度按比例相加。这个方法在很多工程评价类的论文里非常吃香因为“灰色关联”能捕捉到曲线形状上的相似性而欧氏距离只关心空间位置。第三个扩展是时间维度的引入。如果你的数据不是截面数据而是面板数据比如连续三年的企业经营指标可以在每年分别计算贴近度再通过年际加权或动态权重观察排名变化趋势。这种动态评价模型在管理科学类研究里是常常被拿去写论文的方向。当然必须提醒一句任何模型都是工具结果好坏最终取决于数据质量与指标选取的合理程度。选址、选品、选服务商这些问题无论模型算出来什么最后还是要结合业务可行性做综合判断。熵权TOPSIS能给你的是客观锚点减少“拍脑袋”的比例帮你在评审答辩时拿出更扎实的依据。我在实际使用这个模型的过程中最深的体会是想把这个模型用顺关键在于预处理阶段扎不扎实。很多人跑不通不是代码写错而是数据没做正向化、归一化方向错了、或者有异常值没处理。把数据逻辑理清楚后面的数学计算基本一路顺畅。先把代码跑起来再把你自己的数据填进去一次两次迭代下来你就彻底掌握这套组合拳了。本文还有配套的精品资源点击获取