熵权法实战:结合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 供货强度 完成率 订单率 风险 综合得分
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. 权重合理性检验 :当某指标熵值接近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供应商进行敏感性分析,观察权重变化对排名的影响程度。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐