简介面向大学生、科研人员以及需要进行软件选型或项目评估的IT从业者这份资源提供了Topsis综合评价法的MATLAB实现代码与配套银行示例数据帮助读者快速搭建多准则决策分析流程。压缩包内共2个文件包含一个Excel格式的评价基础数据表和一个.m格式的算法脚本整体大小仅10KB结构精简且便于直接运行和二次修改。代码从数据标准化开始依次完成权重设定、最优/最劣向量构建、距离计算以及贴近度排序结果输出清晰便于理解算法每一步的数学含义。将示例数据替换为自己的指标矩阵并调整权重后即可用于方案比选、供应商评价、IT产品对比等实际场景。该资源已有637人浏览学习尤其适合刚接触Topsis方法、希望结合代码和真实数据快速入门的用户。 不废话直接进入正题。你搜“Topsis综合评价法代码及其数据”大概率是正在做数学建模、毕业论文或者某个项目里的多指标评估部分需要一套能直接跑通、能出结果、还能解释得清楚的代码。这篇文章就把TOPSIS从原理到代码再到数据准备全流程拆开讲代码给了可以直接用的Python实现数据格式和常见坑也一并说了。看完你能拿着自己的数据直接改不用再去拼凑网上那些残缺片段。1. 先把方法想明白TOPSIS到底在算什么事TOPSIS全称是Technique for Order Preference by Similarity to Ideal Solution也就是“逼近理想解的排序法”。名字听着绕核心逻辑其实特别朴素如果有一个方案在所有指标上都最好那它就是我们想要的“正理想解”反过来所有指标都最差的方案就是“负理想解”。实际中这种完美方案不存在所以TOPSIS做的事情就是计算每个评价对象离正理想解有多近、离负理想解有多远最终用一个“贴近度”来排名。贴近度的逻辑是离正理想解越近、离负理想解越远的方案排名越靠前。举个生活中的例子你想在几部手机里挑一部考虑性能、价格、续航、拍照四个维度每部手机都有各自的强弱项。你没法直接说哪部绝对最好但你可以比较它们和“理想中那部最好的手机”的差距。TOPSIS就是把这种模糊的比较变成可计算的数字。相比简单的加权平均TOPSIS的好处是不用假设各指标间的替代关系对指标量纲不敏感只要做标准化对样本量也没有硬性要求。它不要求数据满足正态分布也不像层次分析法那样需要构建复杂的判断矩阵。所以在数学建模、论文里的多指标综合评估场景下TOPSIS几乎是个万能备选方案。1.1 核心需求解析“Topsis综合评价法代码及其数据”这个标题里有两个关键词不容忽视代码和数据。光有代码没有合适格式的数据代码就是废的光有数据没有能解释逻辑的代码也没法复现结果。从实际需求来看使用TOPSIS的人通常面临以下几个场景数学建模比赛比如全国大学生数学建模竞赛的各类题目经常需要给多个方案排序。毕业论文对几个城市、几家企业、几个方案做综合实力评价。项目决策评估供应商、选择技术路线、评定绩效。这三个场景对代码的要求不一样建模比赛要求快速出结果、能画图展示论文要求计算过程严谨、能解释清楚每一步的数学含义项目决策则更看重代码的可复用性和数据的处理能力。1.2 为什么TOPSIS被用得这么频繁我在实际使用中最大的感受是TOPSIS是一种“怎么用都不会错”的方法。它不像层次分析法那样需要专家打分也不像熵权法那样对数据分布有隐形要求更不像数据包络分析DEA那样对指标数量有限制。只要你能把指标列出来、把数据填进去TOPSIS就能给你一个排序。而且TOPSIS非常灵活。它的“理想解”不是固定的而是根据你当前的样本数据动态确定的。这意味着你换了一批数据理想解也会跟着变化这就是它的自适应特性。如果你的目标是选一个方案相对优劣这个方法再合适不过。2. 数据准备与预处理代码再好也得从数据开始很多人拿到代码就急着运行却忽略了TOPSIS对数据格式的要求。代码本身不复杂大多数时间反而花在数据清洗和指标处理上。2.1 数据从哪里来TOPSIS适用于有明确评价对象、有多个评价指标、指标值可量化的场景。常见的数据来源包括统计年鉴或公开数据库比如评价各省份经济发展水平用GDP、人均收入、教育投入等公开统计指标实验测量数据比如比较几种材料性能用强度、耐磨性、成本等问卷汇总数据比如评价几个方案的满意度用各项评分均值企业报表数据比如评价供应商用交货准时率、合格率、价格等建议把数据整理成Excel表格或者CSV文件行表示评价对象列表示评价指标第一行是指标名称。我一般习惯用pandas直接读入Excel因为大多数情况下数据量不大用不着上数据库。2.2 指标正向化把方向统一成“越大越好”TOPSIS要求所有指标方向一致否则“理想解”就矛盾了。比如评价手机性能是越大越好价格却是越小越好。如果不做处理一个方案性能好但价格高它跟理想解的距离就会乱算。指标正向化就是把不同方向的指标全部转成“极大值型”也就是越大越好。转换方式极大型指标效益型如性能、续航不处理直接用。极小型指标成本型如价格、碳排放量取倒数或者用最大值减当前值。取倒数的问题是可能导致数据波动剧烈最大值减当前值更稳健。中间型指标如人体体温36.5度最好偏离都不好需要找最优值然后算与最优值的绝对距离。区间型指标如血压在某个区间内最好需要设定区间上下限按偏离程度转换。我这几年用得比较多的是“最大值减当前值”方式处理成本型指标因为这种方式保持了一列为正数不会出现倒数放大极小值的问题。2.3 消除量纲归一化和标准化的选择指标的单位不同比如GDP的单位是亿元人均可支配收入是元教育投入占比是百分比直接代入公式计算距离会被数值量级大的指标主导。所以必须先标准化。TOPSIS里常用的标准化方法有两种向量归一化每个值除以该列所有值的平方和再开根号。这是TOPSIS传统方法中最常用的好处是保留了各指标的相对差异程度。极差归一化min-max每个值减去最小值再除以最大值减最小值把数据压缩到0到1之间。好处是所有数据都在同一个量纲区间缺点是容易受极端值影响。到底选哪种我的习惯是如果后续还要用熵权法定权重就用极差归一化因为熵值法对数据比较敏感如果已经定了主观权重直接用向量归一化更贴合TOPSIS原来的定义。2.4 权重自定义还是熵权法TOPSIS本身不产生权重权重需要另外计算或人为给定。确定权重有两种主流思路主观赋权根据专家经验或实际需求直接给指标分配权重。优点是可以体现决策者的偏好缺点是主观性强换个人结果就变了。客观赋权最常用的是熵权法。熵值衡量的是指标的离散程度某个指标的样本差异越大说明它携带的信息越多权重就应该越高。熵权法的计算步骤是先对指标做极差归一化计算每个指标的比重矩阵计算熵值再根据熵值算差异系数差异系数归一化得到权重我在实际项目里通常组合使用先用熵权法算出客观权重再根据业务理解微调主观权重这样既照顾了数据客观性也保证了决策合理性。3. Python完整实现可直接复制的TOPSIS代码把原理和数据处理弄清楚之后代码反而是最简单的部分。下面这套代码是我自己整理过多次的版本结构清晰带注释可以直接拿你的数据跑。3.1 核心函数实现import numpy as np import pandas as pd def topsis(data, weightsNone, impactsNone): data: DataFrame, 行是评价对象列是指标 weights: list或array, 各指标权重默认等权重 impacts: list, 每个指标的方向表示越大越好-表示越小越好 # 1. 数据转为numpy数组 matrix data.values.astype(float) n_rows, n_cols matrix.shape # 2. 设置默认权重和方向 if weights is None: weights np.ones(n_cols) / n_cols else: weights np.array(weights, dtypefloat) weights weights / weights.sum() # 归一化权重 if impacts is None: impacts [] * n_cols # 3. 向量归一化每个值除以列向量的模 row_sums np.sqrt((matrix ** 2).sum(axis0)) norm_matrix matrix / row_sums # 4. 加权 weighted_matrix norm_matrix * weights # 5. 确定正理想解和负理想解 ideal_best [] ideal_worst [] for j in range(n_cols): if impacts[j] : ideal_best.append(weighted_matrix[:, j].max()) ideal_worst.append(weighted_matrix[:, j].min()) else: ideal_best.append(weighted_matrix[:, j].min()) ideal_worst.append(weighted_matrix[:, j].max()) ideal_best np.array(ideal_best) ideal_worst np.array(ideal_worst) # 6. 计算欧氏距离 dist_best np.sqrt(((weighted_matrix - ideal_best) ** 2).sum(axis1)) dist_worst np.sqrt(((weighted_matrix - ideal_worst) ** 2).sum(axis1)) # 7. 贴近度 score dist_worst / (dist_best dist_worst) return score这段代码的核心逻辑就是六步走归一化矩阵、加权、找正负理想解、算距离、算贴近度。其中最容易出错的是正负理想解的确定——很多人把方向搞反。牢记走近正理想解score高的方案才是好方案。3.2 完整示例用真实数据跑一遍我构造一个教学场景来演示比较五家供应商的综合能力指标包括产品质量合格率极大型、交货准时率极大型、价格极小型、售后服务评分极大型。# 构造示例数据 data pd.DataFrame({ 供应商: [A公司, B公司, C公司, D公司, E公司], 合格率: [0.95, 0.98, 0.92, 0.97, 0.99], 准时率: [0.88, 0.93, 0.90, 0.95, 0.91], 价格: [105, 95, 110, 100, 92], 售后分: [8.5, 9.0, 7.5, 9.5, 8.0] }) # 数据在计算前要用.select_dtypes排除文本列 score topsis(data.loc[:, [合格率, 准时率, 价格, 售后分]], impacts[, , -, ]) data[综合得分] score data data.sort_values(综合得分, ascendingFalse).reset_index(dropTrue) print(data)输出结果会是一个按综合得分从高到低排名的表格。得分最高的就是综合表现最均衡最贴近理想解的方案。注意“价格”列方向设成了负号这样它越小反而越接近理想解这是TOPSIS能处理混合方向指标的关键。3.3 一份随便改就能用的内存版完整脚本如果不想从头写直接把这部分拿去改import numpy as np import pandas as pd data pd.read_excel(你的数据.xlsx, index_col0) # 确保所有列都是数字类型如果有文本列要提前去掉 matrix data.values.astype(float) # 向量归一化 norm_matrix matrix / np.sqrt((matrix ** 2).sum(axis0)) # 权重默认等权重也可以自己改 weights np.array([0.25, 0.25, 0.25, 0.25]) weighted norm_matrix * weights # 正负理想解越大越好-越小越好 impacts [, , -, ] ideal_best np.array([weighted[:, j].max() if impacts[j] else weighted[:, j].min() for j in range(len(impacts))]) ideal_worst np.array([weighted[:, j].min() if impacts[j] else weighted[:, j].max() for j in range(len(impacts))]) d_best np.sqrt(((weighted - ideal_best) ** 2).sum(axis1)) d_worst np.sqrt(((weighted - ideal_worst) ** 2).sum(axis1)) score d_worst / (d_best d_worst) result data.copy() result[score] score result result.sort_values(score, ascendingFalse) print(result)注意你的Excel文件里不要有中文列名以外的特殊字符pandas读取时用index_col0把第一列设为索引这样后续数值计算不会碰到非数字列。3.4 结果可视化一张图看清排名用matplotlib画一个条形图直观展示各方案得分import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 解决中文乱码 plt.rcParams[axes.unicode_minus] False scores_sorted result[score].sort_values(ascendingTrue) plt.figure(figsize(10, 6)) plt.barh(scores_sorted.index, scores_sorted.values, colorskyblue) plt.xlabel(综合得分) plt.title(TOPSIS综合评价得分排名) plt.tight_layout() plt.show()画图不是必需的但在建模比赛和论文里可视化是加分项。条形图是最直观的展示方式一眼就能看出哪个方案领先。4. 常见问题与排查技巧实录代码写完了运行时报错或结果不合理怎么办这些是我这几年遇到最多的问题和解决办法。4.1 逆指标忘了处理这是最典型的错误。如果某个指标是越小越好比如成本但你把它当成极大型直接放进代码正理想解就会选最大的那个值结果全乱套。比如前面例子里的价格它是“越小越好”所以必须在impacts里对应位置写-。如果你用我从网上找到的各种代码版本有些老代码根本没有impacts参数那就必须提前在数据层面做正向化——把价格用最大值减去原值或者取倒数转换成正向指标再代入计算。4.2 归一化方法影响结果不同归一化方法的区别主要体现在权重和数据分布上。向量归一化不改变数据间比值关系适合大多数情况但如果你用了熵权法去算权重必须提前用极差归一化否则权重计算结果完全不可用。我在一个项目里犯过这个错数据用向量归一化权重用熵权法结果权重分布极其不均匀排名几乎被一个指标主导。后来改成极差归一化结果分布就合理了很多。这个坑非常隐蔽数据处理和权重计算必须用同一套标准化逻辑。4.3 正负理想解相同或得分异常如果所有方案在某个指标上的值完全相同那么这个指标对排序就没有区分度计算出来的权重和距离都会出问题。解决办法是先检查数据列的方差如果某一列标准差为零建议直接删除该指标或者用常数替代权重。还有一种情况是部分方案得分特别接近0.500几这是正常现象。TOPSIS的得分表示“贴近理想解的程度”不是百分制不需要强求高分。贴近度0.6以上已经算不错了。4.4 pandas读取Excel报错如果程序报ImportError: Missing optional dependency openpyxl说明环境缺少openpyxl库直接pip install openpyxl解决。如果是中文路径或中文列名导致读取出错最简单的处理方式是文件另存为CSV格式用pd.read_csv读取或者确认Excel文件没有合并单元格。4.5 权重不归一化会导致结果异常TOPSIS要求权重和为1如果直接传原始权重比如[2, 3, 5]而不做归一化距离结果会偏大或偏小但排序不一定会变。不过为了后续解释和论文展示方便代码里统一做了归一化处理建议所有自定义权重都先除总和。5. 从代码到分析报告数据输出的细节处理很多时候代码跑通只是完成了一半另一半是把结果整理成报告或论文需要的格式。建议把最终结果导出到Excelresult.to_excel(TOPSIS结果.xlsx, sheet_name评价结果)导出时注意pandas会把索引也导出一列如果你的索引是有含义的对象名称比如供应商名字这样可以保留。如果索引是数字可以在导出前reset_index()。如果是论文使用还需要给出计算过程中的正理想解和负理想解的数值。这两个值体现了各指标的最优水平有时比最终得分更有业务价值。我知道很多人局限在“把代码跑通”这个层面上但真正让结果被认可的是你能解释清楚每一个数是怎么来的为什么这个方案排第一。TOPSIS之所以好用就是因为它计算透明任何人都能顺着你的数据复现整个结果每一步都有清晰的决策依据。有一点尤其值得提醒TOPSIS的排名结果只对当前样本集合有意义。你换了样本或者改了指标排名就会发生变化。报告中要明确说明样本范围、指标选取依据、权重确定方法这样结论才站得住脚。做综合评价这些年我最大的体会是方法只是工具关键还是你对业务场景、指标含义和数据质量的理解。TOPSIS能帮你把复杂决策化简为数字排序但指标选得不好、权重定得不合理再好的方法也算不出有说服力的答案。所以在动手写代码之前多花点时间想清楚你的决策目标是什么、哪些指标真正能反映它的价值这才是综合评价的正确打开方式。本文还有配套的精品资源点击获取
