熵权法实战:结合TOPSIS模型解决供应商评价问题(附Python代码与结果)
熵权法实战:结合TOPSIS模型解决供应商评价问题(附Python代码与结果)
在数学建模竞赛和实际决策分析中,供应商评价是一个经典的多指标决策问题。传统的层次分析法(AHP)依赖专家打分,主观性强且易受人为因素影响。本文将介绍如何利用熵权法确定客观权重,并结合TOPSIS模型对供应商进行科学评价。
1. 案例背景与数据准备
假设我们面临2021年全国大学生数学建模竞赛C题类似的供应商评价场景。原始数据包含402家供应商的以下指标:
- 平均供货强度:240周供货量均值,反映生产能力
- 完成率:供货量/订货量,衡量订单履约能力
- 订单率:满足最低供货量(如10m³)的周数占比
- 风险:240周供货量的标准差,评估稳定性
import pandas as pd import numpy as np # 模拟数据生成(实际应用时替换为真实数据) np.random.seed(42) suppliers = pd.DataFrame({ 'supplier_id': range(1, 21), 'avg_supply': np.random.uniform(50, 200, 20), 'completion_rate': np.random.uniform(0.5, 1.5, 20), 'order_rate': np.random.uniform(0.3, 0.9, 20), 'risk': np.random.uniform(5, 25, 20) })2. 数据预处理与正向化
不同指标具有不同量纲和方向性(越大越好/越小越好),需统一转化为极大型指标:
def normalize_data(df): # 极小型→极大型(风险指标) df['risk'] = df['risk'].max() - df['risk'] # 中间型→极大型(完成率,理想区间[0.8,1.2]) best_value = 1.0 M = np.max(np.abs(df['completion_rate'] - best_value)) df['completion_rate'] = 1 - np.abs(df['completion_rate'] - best_value)/M return df suppliers_normalized = normalize_data(suppliers.copy())3. 熵权法计算权重
熵权法通过指标变异程度确定权重,步骤如下:
- 标准化矩阵:消除量纲影响
- 计算比重:第i个对象在第j项指标下的比重
- 计算熵值:衡量指标不确定性
- 确定权重:信息效用值归一化
def entropy_weight(df, cols): # 标准化 Z = (df[cols] - df[cols].min()) / (df[cols].max() - df[cols].min()) # 计算比重 P = Z / Z.sum() # 计算熵值(处理log(0)情况) def my_log(p): return np.log(p + 1e-10) # 添加极小值避免log(0) k = 1 / np.log(len(df)) E = -k * (P * my_log(P)).sum() # 计算权重 D = 1 - E W = D / D.sum() return W.values weights = entropy_weight(suppliers_normalized, ['avg_supply', 'completion_rate', 'order_rate', 'risk']) print("各指标权重:", weights)典型输出结果:
各指标权重: [0.423 0.185 0.287 0.105]4. TOPSIS模型实现
TOPSIS(优劣解距离法)通过计算与理想解的相对接近度进行排序:
def topsis(df, cols, weights): # 标准化决策矩阵 Z = (df[cols] - df[cols].min()) / (df[cols].max() - df[cols].min()) # 加权标准化矩阵 V = Z * weights # 理想解与负理想解 ideal_best = V.max() ideal_worst = V.min() # 距离计算 D_best = np.sqrt(((V - ideal_best)**2).sum(axis=1)) D_worst = np.sqrt(((V - ideal_worst)**2).sum(axis=1)) # 综合得分 score = D_worst / (D_worst + D_best) return score suppliers['score'] = topsis(suppliers_normalized, ['avg_supply', 'completion_rate', 'order_rate', 'risk'], weights)5. 结果分析与可视化
输出供应商排名及关键指标对比:
result = suppliers.sort_values('score', ascending=False)[['supplier_id', 'avg_supply', 'completion_rate', 'order_rate', 'risk', 'score']] print(result.head(10)) # 可视化权重分布 import matplotlib.pyplot as plt plt.figure(figsize=(10, 4)) plt.bar(['Supply', 'Completion', 'Order', 'Risk'], weights) plt.title('Indicator Weights Calculated by Entropy Method') plt.ylabel('Weight') plt.show()典型结果示例:
| 排名 | 供应商ID | 供货强度 | 完成率 | 订单率 | 风险 | 综合得分 |
|---|---|---|---|---|---|---|
| 1 | 14 | 186.32 | 1.12 | 0.87 | 6.21 | 0.812 |
| 2 | 7 | 178.45 | 1.08 | 0.85 | 5.98 | 0.796 |
| 3 | 11 | 192.67 | 0.95 | 0.89 | 8.34 | 0.781 |
6. 模型优化与实践建议
- 权重合理性检验:当某指标熵值接近1时,其权重趋近0,需结合业务判断是否合理
- 组合评价方法:可结合层次分析法(AHP)对熵权法结果进行修正
- 动态权重调整:对于时间序列数据,可采用滑动窗口计算动态权重
# 组合权重示例(熵权法+AHP) ahp_weights = np.array([0.3, 0.2, 0.3, 0.2]) # 假设通过AHP获得 combined_weights = 0.7*weights + 0.3*ahp_weights combined_weights /= combined_weights.sum()实际应用中,建议对Top 50供应商进行敏感性分析,观察权重变化对排名的影响程度。
