当前位置: 首页 > news >正文

别再手动算排名了!用Python+TOPSIS法5分钟搞定多指标评价(附完整代码)

用Python+TOPSIS法5分钟搞定多指标评价排名

当你面对一堆供应商评估表格、学生综合评分数据或者项目优先级排序表时,是否还在用Excel手动计算加权分数?每次调整权重都要重新算一遍,不仅效率低下,还容易出错。今天我要分享的TOPSIS法,配合Python的Pandas和Numpy库,能让你在5分钟内搞定这些繁琐的计算,而且结果比手动计算更客观科学。

TOPSIS(Technique for Order Preference by Similarity to Ideal Solution)即优劣解距离法,它的核心思想很直观:找出每个方案距离"理想解"最近,同时距离"负理想解"最远的那个方案作为最优解。这种方法特别适合处理多指标决策问题,比如:

  • 供应商评估(价格、交货期、质量等多维度打分)
  • 员工绩效考核(KPI多项指标综合)
  • 投资项目选择(收益率、风险、周期等权衡)
  • 学术评价(论文、专利、项目等多指标排名)

1. 环境准备与数据加载

首先确保你已安装Python和Jupyter Notebook(推荐Anaconda发行版)。我们需要用到以下几个核心库:

import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler

假设我们有一份供应商评估的Excel数据,包含以下指标:

供应商价格(万元)交货周期(天)质量合格率(%)售后服务评分
A12015984.2
B15010954.5
C10020993.8

用Pandas加载数据非常简单:

df = pd.read_excel('supplier_evaluation.xlsx', index_col='供应商') print(df.head())

注意:数据中的指标类型不同,价格和交货周期是越小越好(成本型),而质量合格率和售后服务评分是越大越好(效益型)。这是TOPSIS处理前的关键认知。

2. 数据预处理:指标正向化

TOPSIS要求所有指标同向化(都转为越大越好)。我们需要区分指标类型:

  • 效益型指标:越大越好(如质量合格率)
  • 成本型指标:越小越好(如价格)
  • 区间型指标:落在某个区间最好(如温度)
  • 中间型指标:越接近某个值越好(如pH值)

对于我们的示例数据,只需处理成本型指标。常用正向化方法有:

  1. 倒数法:1/x
  2. 差值法:max(x) - x
  3. 标准化法:(max(x) - x)/(max(x) - min(x))

这里使用差值法实现:

# 成本型指标列名 cost_columns = ['价格(万元)', '交货周期(天)'] # 正向化处理 for col in cost_columns: df[col] = df[col].max() - df[col] print("正向化后的数据:") print(df)

处理后的数据中,所有指标都变为效益型——数值越大代表表现越好。

3. 数据标准化与权重分配

不同指标的量纲和数量级不同,需要标准化处理。常用方法有:

  • 向量归一化x_ij / sqrt(sum(x_ij^2))
  • Min-Max标准化(x - min)/(max - min)
  • Z-score标准化(x - mean)/std

TOPSIS通常采用向量归一化:

# 向量归一化 normalized_df = df / np.sqrt((df**2).sum()) print("归一化矩阵:") print(normalized_df)

权重分配有三种常见方法:

  1. 等权重法:所有指标权重相同
  2. 主观赋权法:如AHP层次分析法
  3. 客观赋权法:如熵权法

这里演示等权重和熵权法两种实现:

# 方法1:等权重 equal_weights = np.ones(df.shape[1]) / df.shape[1] # 方法2:熵权法 def entropy_weight(X): # 避免log(0) X = X + 1e-10 # 计算比重 P = X / X.sum(axis=0) # 计算熵值 E = np.sum(-P * np.log(P), axis=0) / np.log(len(X)) # 计算差异系数 D = 1 - E # 计算权重 W = D / D.sum() return W entropy_weights = entropy_weight(df.values) print("熵权法计算的权重:", entropy_weights)

4. TOPSIS核心计算步骤

有了标准化矩阵和权重后,就可以计算正负理想解和相对接近度了。

def topsis(data, weights): # 加权标准化矩阵 weighted_matrix = data * weights # 确定正负理想解 ideal_best = weighted_matrix.max() ideal_worst = weighted_matrix.min() # 计算距离 dist_best = np.sqrt(((weighted_matrix - ideal_best)**2).sum(axis=1)) dist_worst = np.sqrt(((weighted_matrix - ideal_worst)**2).sum(axis=1)) # 计算相对接近度 score = dist_worst / (dist_best + dist_worst) return score # 使用熵权法权重计算 df['TOPSIS评分'] = topsis(normalized_df, entropy_weights) df['排名'] = df['TOPSIS评分'].rank(ascending=False) print("最终结果:") print(df.sort_values('排名'))

5. 完整代码封装与使用建议

将上述步骤封装成一个函数,方便重复使用:

def topsis_evaluation(input_file, cost_columns, output_file=None): """ TOPSIS多指标评价完整流程 参数: input_file: 输入Excel文件路径 cost_columns: 成本型指标列名列表 output_file: 结果输出路径(可选) 返回: 带评分和排名的DataFrame """ # 1. 数据加载 df = pd.read_excel(input_file, index_col=0) # 2. 正向化处理 for col in cost_columns: df[col] = df[col].max() - df[col] # 3. 数据标准化 normalized_df = df / np.sqrt((df**2).sum()) # 4. 计算权重(熵权法) weights = entropy_weight(df.values) # 5. TOPSIS计算 df['TOPSIS评分'] = topsis(normalized_df, weights) df['排名'] = df['TOPSIS评分'].rank(ascending=False) # 6. 结果输出 if output_file: df.to_excel(output_file) return df.sort_values('排名') # 使用示例 result = topsis_evaluation( input_file='supplier_evaluation.xlsx', cost_columns=['价格(万元)', '交货周期(天)'], output_file='supplier_ranking_result.xlsx' )

实际使用时,你只需要:

  1. 准备Excel数据,第一列为评价对象名称
  2. 确定哪些列是成本型指标(越小越好)
  3. 调用这个函数,指定输入输出路径

提示:对于区间型或中间型指标,可以在正向化步骤添加相应处理逻辑。完整代码可在GitHub仓库获取。

我在多个供应商评估项目中使用这个方法后,发现它有三大优势:

  1. 客观性:避免了人为赋权的主观性
  2. 灵活性:权重方法可自由选择(熵权法、AHP等)
  3. 可视化:结果可以方便地用Python做进一步分析展示

一个常见的问题是:当某个指标值出现极端异常时怎么办?我的经验是:

  • 预处理阶段使用Winsorize方法处理极端值
  • 或者考虑用标准化方法代替原始数据
  • 对于明显错误的数据,应该人工检查修正
http://www.jsqmd.com/news/737145/

相关文章:

  • 京东e卡回收平台推荐:高价、安全、快速的三合一选择 - 团团收购物卡回收
  • SketchUp STL插件:5分钟实现3D设计到打印的无缝转换
  • 别再只学理论了!用H3C交换机实战802.1X:基于端口和基于MAC认证到底有啥区别?
  • TVA与CNN的历史性对决(3)
  • 华硕笔记本性能调校实战:3种高效方案解锁硬件潜能
  • 京东e卡回收平台靠谱吗?深度解析热门平台优缺点 - 团团收购物卡回收
  • 如何为Windows系统创建高性能虚拟显示器:ParsecVDisplay完整指南
  • 前端工程化:基于Node.js的图片资源自动化处理与资产管理实践
  • 别再死记公式了!用Python+MATLAB手把手带你玩转单自由度无阻尼振动(附代码)
  • GetQzonehistory终极指南:一键备份QQ空间十年回忆的完整方案
  • 如何用XXMI启动器轻松管理游戏模组:完整指南
  • Qt6.5在线安装保姆级教程:用国内镜像源告别龟速下载(附阿里云盘工具)
  • 3分钟快速上手:罗技鼠标宏绝地求生压枪脚本终极配置指南
  • Ubuntu 20.04下搞定gici-open编译:从glog报错到ceres版本冲突的保姆级排坑指南
  • 成对验证技术提升代码生成模型推理能力
  • TranslucentTB:3步打造Windows任务栏透明化,让你的桌面焕然一新
  • Kai 9000:构建具备持久记忆与跨平台执行能力的开源AI助手
  • LizzieYzy:围棋AI智能分析工具的完整指南,让你快速提升棋力
  • 保姆级教程:手把手教你修改PX4机型文件,让自定义无人机在QGC上完美显示
  • 如何快速解决RimSort中SteamCmd下载失败:3种实用权限配置方法
  • 从晶圆到焊球:保姆级图解WLCSP封装的八个关键步骤(附RDL与BOP选择指南)
  • Substrate跨链桥实战:从架构设计到安全部署
  • 别再只看ROC了!用‘价格斜率’构建ETF轮动策略,实测改善回撤(附Python代码)
  • 大语言模型长上下文处理能力评测框架LOCA-bench解析
  • 如何高效使用MTKClient:联发科设备底层调试终极解决方案
  • 解锁音乐自由:ncmdump如何帮你轻松转换网易云音乐NCM文件
  • 融资代办机构怎么选,厦门德账房性价比高吗 - mypinpai
  • RAKwireless RUI3开源物联网平台开发指南
  • 轻量级实时聊天框架chat-js:前端优先的设计与实战集成指南
  • 图像降噪新思路:拆解KBNet,看它如何用‘动态卷积核’巧妙结合CNN与注意力机制