熵权法实战:结合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供应商进行敏感性分析,观察权重变化对排名的影响程度。
更多推荐


所有评论(0)