用Python和Excel搞定TOPSIS综合评价:从数据清洗到结果可视化(附完整代码)

发布时间:2026/6/8 1:42:14

用Python和Excel搞定TOPSIS综合评价:从数据清洗到结果可视化(附完整代码) TOPSIS实战指南用Python和Excel轻松搞定多指标决策当我们需要在多个选项中做出选择时常常会面临一个难题每个选项在不同指标上表现各异有的指标表现优异有的则不尽如人意。比如选择供应商时价格、质量、交货时间等指标往往相互矛盾评估员工绩效时业绩、团队合作、创新能力等维度也难以简单比较。TOPSISTechnique for Order Preference by Similarity to Ideal Solution方法正是为解决这类多准则决策问题而生的利器。1. TOPSIS方法的核心思想TOPSIS即逼近理想解的排序方法它的核心思想非常直观在所有备选方案中最佳方案应该距离理想解最近同时距离负理想解最远。这里的理想解是指所有指标都达到最优值的虚拟方案负理想解则是所有指标都处于最差值的虚拟方案。这种方法最早由Hwang和Yoon在1981年提出如今已成为管理科学、运筹学等领域最常用的多属性决策方法之一。与AHP层次分析法等需要复杂两两比较的方法相比TOPSIS具有计算简单、逻辑清晰、易于理解的优点特别适合实际工作中的快速决策。TOPSIS的典型应用场景包括产品选择比较不同产品在价格、性能、质量等维度的表现供应商评估基于成本、交货时间、质量等指标筛选最优供应商投资决策评估不同投资项目在风险、收益、流动性等方面的平衡人才评估综合考量候选人的专业技能、工作经验、沟通能力等素质2. TOPSIS的六步实现流程2.1 数据准备与规范化TOPSIS分析的第一步是构建决策矩阵。假设我们有5个供应商需要评估考虑的指标包括价格成本型越低越好、质量效益型越高越好和交货时间成本型越短越好原始数据如下表所示供应商价格(万元)质量(评分)交货时间(天)A1285B1573C1067D1894E147.56由于各指标的量纲和方向性不同我们需要先进行规范化处理。常用的向量规范化公式为# Python实现向量规范化 import numpy as np def normalize_matrix(matrix): # 计算每列的平方和开根号 norms np.sqrt(np.sum(matrix**2, axis0)) # 避免除以零 norms[norms 0] 1 return matrix / norms # 示例数据仅数值部分 raw_data np.array([ [12, 8, 5], [15, 7, 3], [10, 6, 7], [18, 9, 4], [14, 7.5, 6] ]) normalized_data normalize_matrix(raw_data) print(规范化后的矩阵:\n, normalized_data)在Excel中可以使用以下公式实现相同的规范化效果假设数据位于B2:D6区域B2/SQRT(SUMSQ(B$2:B$6))2.2 指标加权处理不同指标的重要性往往不同我们需要为每个指标分配权重。确定权重的方法有多种如德尔菲法、AHP法等。假设我们通过专家评估确定价格、质量、交货时间的权重分别为0.4、0.3、0.3。加权规范化矩阵的计算公式为 [ c_{ij} w_j \times b_{ij} ]Python实现weights np.array([0.4, 0.3, 0.3]) weighted_data normalized_data * weights print(加权后的矩阵:\n, weighted_data)Excel中只需将规范化后的值乘以相应权重即可。2.3 确定理想解与负理想解根据指标类型效益型或成本型确定理想解和负理想解理想解(C)*每个指标取加权矩阵中的最优值效益型取最大成本型取最小负理想解(C0)每个指标取加权矩阵中的最差值效益型取最小成本型取最大Python代码实现# 指标类型0表示成本型1表示效益型 criteria_types np.array([0, 1, 0]) ideal_solution np.where(criteria_types 1, np.max(weighted_data, axis0), np.min(weighted_data, axis0)) negative_ideal_solution np.where(criteria_types 1, np.min(weighted_data, axis0), np.max(weighted_data, axis0)) print(理想解:, ideal_solution) print(负理想解:, negative_ideal_solution)2.4 计算距离与贴近度计算每个方案到理想解和负理想解的欧氏距离[ s_i^* \sqrt{\sum_{j1}^n (c_{ij} - c_j^*)^2} ] [ s_i^0 \sqrt{\sum_{j1}^n (c_{ij} - c_j^0)^2} ]然后计算相对贴近度[ f_i^* \frac{s_i^0}{s_i^0 s_i^*} ]Python实现# 计算距离 dist_to_ideal np.sqrt(np.sum((weighted_data - ideal_solution)**2, axis1)) dist_to_negative np.sqrt(np.sum((weighted_data - negative_ideal_solution)**2, axis1)) # 计算贴近度 closeness dist_to_negative / (dist_to_ideal dist_to_negative) print(到理想解距离:, dist_to_ideal) print(到负理想解距离:, dist_to_negative) print(贴近度:, closeness)2.5 结果排序与解读根据贴近度对方案进行排序贴近度越大表示方案越优。我们可以将结果可视化import matplotlib.pyplot as plt import pandas as pd results pd.DataFrame({ Supplier: [A, B, C, D, E], Closeness: closeness }).sort_values(Closeness, ascendingFalse) plt.figure(figsize(10, 6)) plt.barh(results[Supplier], results[Closeness], colorskyblue) plt.xlabel(TOPSIS Closeness Coefficient) plt.title(Supplier Ranking by TOPSIS Method) plt.gca().invert_yaxis() # 最高分在上方 plt.show()在Excel中可以使用排序功能对贴近度进行降序排列并通过条形图直观展示结果。3. 实际应用中的技巧与陷阱3.1 权重确定的实用方法权重对结果影响重大以下是几种实用的权重确定方法主观赋权法直接评分法由专家直接给出各指标权重德尔菲法通过多轮专家调查达成共识客观赋权法熵权法根据数据本身的离散程度确定权重CRITIC法同时考虑对比强度和冲突性组合赋权法将主客观权重按一定比例结合# 熵权法示例实现 def entropy_weight(matrix): # 标准化 norm_matrix matrix / np.sum(matrix, axis0) # 计算熵值 k 1 / np.log(matrix.shape[0]) entropy -k * np.sum(norm_matrix * np.log(norm_matrix 1e-10), axis0) # 计算差异系数 d 1 - entropy # 计算权重 weights d / np.sum(d) return weights entropy_weights entropy_weight(raw_data) print(熵权法计算的权重:, entropy_weights)3.2 处理特殊指标类型除了常见的效益型和成本型指标实践中还可能遇到区间型指标希望指标值落在某个区间内固定型指标希望指标值等于某个特定值非线性关系指标与效用之间不是线性关系对于区间型指标可以使用以下转换公式[ b_{ij} \begin{cases} 1 - \frac{a_j^0 - a_{ij}}{a_j^0 - a_j} a_j \leq a_{ij} a_j^0 \ 1 a_j^0 \leq a_{ij} \leq a_j^* \ 1 - \frac{a_{ij} - a_j^}{a_j - a_j^} a_j^* a_{ij} \leq a_j \ 0 \text{其他} \end{cases} ]3.3 常见问题与解决方案权重敏感性分析轻微调整权重观察排序结果是否稳定如果结果对权重变化敏感需要重新审视权重分配数据异常值处理使用标准化替代规范化对极端值进行Winsorize处理结果验证与其他多准则决策方法如AHP、VIKOR结果对比检查是否符合业务直觉和经验判断4. 高级应用与扩展4.1 结合模糊理论的Fuzzy TOPSIS当评价信息不确定或模糊时可以使用模糊TOPSIS。基本步骤将语言评价转换为模糊数构建模糊决策矩阵确定模糊理想解和负理想解计算模糊距离计算贴近度并排序# 模糊TOPSIS简化示例 from skfuzzy import trimf # 定义语言变量到三角模糊数的映射 linguistic_terms { 很差: (0, 0, 2.5), 差: (0, 2.5, 5), 一般: (2.5, 5, 7.5), 好: (5, 7.5, 10), 很好: (7.5, 10, 10) } def linguistic_to_fuzzy(term): return linguistic_terms.get(term, (0, 0, 0)) # 示例将语言评价转换为模糊数 fuzzy_data np.array([[linguistic_to_fuzzy(好) for _ in range(3)] for _ in range(5)])4.2 动态TOPSIS与时间序列分析对于需要考虑时间变化的决策问题可以引入时间权重构建动态TOPSIS模型确定不同时间点的重要性权重计算各时间点的TOPSIS结果加权聚合得到最终排序4.3 与其他方法的结合应用TOPSIS-AHP组合用AHP确定指标权重用TOPSIS进行方案排序TOPSIS-DEA组合先用DEA筛选有效决策单元再用TOPSIS对有效单元排序TOPSIS-灰色关联分析组合考虑数据的不确定性和信息不完全性5. 完整Python实现与Excel模板5.1 Python完整实现代码import numpy as np import pandas as pd import matplotlib.pyplot as plt class TOPSIS: def __init__(self, data, weights, criteria_types): :param data: 决策矩阵每行一个方案每列一个指标 :param weights: 指标权重数组 :param criteria_types: 指标类型数组0表示成本型1表示效益型 self.data np.array(data) self.weights np.array(weights) self.criteria_types np.array(criteria_types) self.normalized_data None self.weighted_data None self.ideal_solution None self.negative_ideal_solution None self.dist_to_ideal None self.dist_to_negative None self.closeness None def normalize(self): 向量规范化 norms np.sqrt(np.sum(self.data**2, axis0)) norms[norms 0] 1 # 避免除以零 self.normalized_data self.data / norms def apply_weights(self): 应用权重 self.weighted_data self.normalized_data * self.weights def determine_solutions(self): 确定理想解和负理想解 self.ideal_solution np.where(self.criteria_types 1, np.max(self.weighted_data, axis0), np.min(self.weighted_data, axis0)) self.negative_ideal_solution np.where(self.criteria_types 1, np.min(self.weighted_data, axis0), np.max(self.weighted_data, axis0)) def calculate_distances(self): 计算距离 self.dist_to_ideal np.sqrt( np.sum((self.weighted_data - self.ideal_solution)**2, axis1)) self.dist_to_negative np.sqrt( np.sum((self.weighted_data - self.negative_ideal_solution)**2, axis1)) def calculate_closeness(self): 计算贴近度 self.closeness self.dist_to_negative / (self.dist_to_ideal self.dist_to_negative) def run(self): 执行完整TOPSIS流程 self.normalize() self.apply_weights() self.determine_solutions() self.calculate_distances() self.calculate_closeness() return self.closeness def visualize(self, alternative_namesNone): 可视化结果 if alternative_names is None: alternative_names [fOption {i1} for i in range(len(self.data))] results pd.DataFrame({ Alternative: alternative_names, Closeness: self.closeness }).sort_values(Closeness, ascendingFalse) plt.figure(figsize(10, 6)) plt.barh(results[Alternative], results[Closeness], colorskyblue) plt.xlabel(TOPSIS Closeness Coefficient) plt.title(Alternatives Ranking by TOPSIS Method) plt.gca().invert_yaxis() plt.show() # 使用示例 if __name__ __main__: # 示例数据 data [ [12, 8, 5], [15, 7, 3], [10, 6, 7], [18, 9, 4], [14, 7.5, 6] ] weights [0.4, 0.3, 0.3] criteria_types [0, 1, 0] # 0:成本型, 1:效益型 alternatives [Supplier A, Supplier B, Supplier C, Supplier D, Supplier E] # 执行TOPSIS分析 topsis TOPSIS(data, weights, criteria_types) closeness topsis.run() topsis.visualize(alternatives)5.2 Excel实现模板在Excel中实现TOPSIS可以按照以下步骤设置模板数据输入区输入原始决策矩阵权重输入区设置各指标权重规范化计算区使用公式B2/SQRT(SUMSQ(B$2:B$6))计算规范化值加权计算区规范化值乘以权重理想解计算效益型MAX(加权列)成本型MIN(加权列)负理想解计算效益型MIN(加权列)成本型MAX(加权列)距离计算到理想解距离SQRT(SUMSQ(加权行-理想解行))到负理想解距离SQRT(SUMSQ(加权行-负理想解行))贴近度计算负理想距离/(负理想距离理想距离)排序结果使用RANK函数或排序功能提示在Excel中使用条件格式可以直观地高亮显示最优和最差值帮助快速识别理想解和负理想解。5.3 实际案例员工绩效评估假设我们需要评估5名员工在四个维度上的表现销售业绩效益型客户满意度效益型项目完成时间成本型团队协作效益型原始数据和权重如下# 员工绩效评估案例 performance_data [ [85, 90, 10, 8], [92, 88, 15, 7], [78, 85, 8, 9], [88, 92, 12, 8], [95, 85, 14, 7] ] performance_weights [0.4, 0.3, 0.1, 0.2] performance_types [1, 1, 0, 1] employee_names [张三, 李四, 王五, 赵六, 钱七] # 执行TOPSIS分析 topsis_perf TOPSIS(performance_data, performance_weights, performance_types) closeness_perf topsis_perf.run() topsis_perf.visualize(employee_names)通过TOPSIS分析我们可以得到综合考虑多个维度的员工绩效排名避免了单一指标评估的片面性。

相关新闻