熵权法实战:结合TOPSIS模型解决供应商评价问题(附Python代码与结果)

📅 2026/7/4 2:16:19 👁️ 阅读次数 📝 编程学习
熵权法实战:结合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. 熵权法计算权重

熵权法通过指标变异程度确定权重,步骤如下:

  1. 标准化矩阵:消除量纲影响
  2. 计算比重:第i个对象在第j项指标下的比重
  3. 计算熵值:衡量指标不确定性
  4. 确定权重:信息效用值归一化
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供货强度完成率订单率风险综合得分
114186.321.120.876.210.812
27178.451.080.855.980.796
311192.670.950.898.340.781

6. 模型优化与实践建议

  1. 权重合理性检验:当某指标熵值接近1时,其权重趋近0,需结合业务判断是否合理
  2. 组合评价方法:可结合层次分析法(AHP)对熵权法结果进行修正
  3. 动态权重调整:对于时间序列数据,可采用滑动窗口计算动态权重
# 组合权重示例(熵权法+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供应商进行敏感性分析,观察权重变化对排名的影响程度。