熵权法
熵权法(Entropy Weight Method, EWM)是数学建模竞赛中最常用的客观赋权方法:它不依赖专家打分,仅凭"数据本身携带的信息量"给每个指标分配权重——哪个指标在不同评价对象之间差异大、能提供更多区分信息,哪个指标的权重就大。熵权法常与 TOPSIS、灰色关联等评价模型联用(熵权-TOPSIS 是竞赛高频组合),也是与 AHP 做组合赋权的标准配件。本文从原理、适用场景、算法指标、可视化到可运行代码,完整梳理熵权法的竞赛实战用法。
一、算法含义
1.1 通俗理解:从"信息量"说起
信息论创始人香农(Shannon)提出:一条消息所携带的信息量,与它的"意外程度"成正比。越容易猜到的事,说出来信息量越小:
- 天气预报说"明天要么下雨、要么不下雨,各 50%"——这几乎等于没说,信息量几乎为零;
- 天气预报说"明天晴(概率 99%)"——不确定性被大幅消除,信息量大。
香农用信息熵 度量这种"不确定性 / 混乱程度":
其中 是第 种结果出现的概率。熵有三个关键性质:
- ,当所有概率集中在一种结果上(某个 ,其余为 0)时 ——"完全确定"的消息熵为零,信息量最大;
- 当 种结果等概率()时, 达到最大——这是"最混乱、最没信息"的状态;
- 概率分布越均匀 → 熵越大 → 信息量越小;分布越集中 → 熵越小 → 信息量越大。即:信息量越大,熵越小。
把这套思想搬到评价问题上:把每个指标在各评价对象上的取值占比 看成"概率"。如果一个指标在所有评价对象上取值几乎相同(如五个城市的空气优良天数都是 300 天左右),它的信息熵就很大——该指标几乎不能帮我们区分谁好谁坏,信息量小,权重就应该小;反之,取值差异悬殊的指标熵小、信息量大、权重就大。
1.2 熵权法的五步流程
设评价问题有 个评价对象、 个指标,原始数据矩阵为 。熵权法分五步:
第①步:数据标准化(含非负平移处理)
先按指标方向做极差标准化(min-max),把所有指标压到 :
- 正向指标(越大越好):
- 负向指标(越小越好):
由于 在 0 处无定义,再做非负平移:( 取 量级即可)。若采用 Z-score 等其他标准化方式产生了负值(如"利润增长率"这类指标),必须先把整列平移到正数域,即负值平移处理:。
第②步:计算比重矩阵
(这里的 指第①步平移后的标准化值 ;若原始数据已全部为正且不做标准化,也可直接对原始数据计算比重。)第 个指标下所有对象的比重之和为 1,构成一个"概率分布"。
第③步:计算各指标的信息熵
其中 是归一化常数: 个对象时熵的理论最大值是 ,除以它保证 。
第④步:计算差异系数(信息效用值)
是 的"反义词":该指标携带了多少有效的区分信息。
第⑤步:归一化得到权重
权重之和为 1。最终的综合得分可由 加权得到。
1.3 为什么"指标差异越大权重越大"——直觉解释
用数学验证一下极端情况:若第 个指标在所有对象上取值完全相同(),标准化后大家仍相等,比重 (等概率分布)。代入熵公式:
于是 ,:完全没有区分力的指标权重为零。反过来,指标取值差异越大,比重分布越集中(少数对象"占大头"),熵 越小, 和 就越大。
直观地说:熵权法就像在问每个指标——"你在一群候选者里,能不能帮我们分出高下?"能分出高下的(数据差异大的),发言权(权重)就大;分不出高下的,就少说话。
1.4 客观赋权 vs 主观赋权(与 AHP 对比)
| 对比维度 | 熵权法(客观赋权) | AHP(主观赋权) |
|---|---|---|
| 权重来源 | 数据本身的信息量(变异程度) | 专家两两比较打分(1-9 标度) |
| 是否需要专家 | 不需要 | 需要,且要通过一致性检验() |
| 核心优点 | 完全客观、可复现、无主观偏差 | 符合业务认知,可融入政策偏好 |
| 核心缺点 | 可能违背业务常识(见 1.5) | 主观性强,不同专家结果不同 |
| 竞赛用法 | 输出"客观权重",或与 AHP 组合 | 输出"主观权重",或与熵权组合 |
1.5 优缺点
优点:
- 完全客观:只认数据,计算过程无任何人为打分,评审不易质疑;
- 计算简单:五个公式即可手推,代码不超过 40 行,无迭代、无优化器;
- 可复现:同样的数据必然给出同样的权重,不依赖随机性;
- 对数据分布没有假设:不要求正态性、线性等条件,几乎任何数值型矩阵都能算;
- 天然度量"区分度":权重即"该指标能提供多少区分信息",与评价的初衷一致。
缺点:
- 只看差异、不看业务:业务上很重要的指标,如果所有对象取值相近,熵权法会给它很低的权重——数据上"没差异"不等于业务上"不重要",这是熵权法最大的争议点;
- 权重随样本而变:增删一个评价对象,全部权重重新洗牌,权重不稳定;
- 不反映指标间相关性:两个高度相关的指标会被重复计权(改进见第八节 CRITIC 法);
- 对标准化方式敏感:min-max、Z-score、比重法等不同预处理会得到不同权重,论文中须写明所用方式;
- 指标方向必须人为指定:正向/负向判断本身带一点主观成分,方向标反结论完全颠倒。
二、何时使用(适用场景与条件)
2.1 适用场景
- 评价体系的权重建构:多指标综合评价的第一步永远是"定权重",熵权法给出一个客观、可复现的权重初值。如"城市高质量发展评价""企业信用评价""供应商选择""校园网评优"等;
- 客观权重确定:论文中需要一套"不用解释为什么"的权重时,熵权法是标准答案——"权重由数据信息量客观确定"这句话本身就很有说服力;
- 与 AHP 组合赋权:按 合成,既尊重数据又尊重业务经验,是评价类题目最稳妥的定权方案;
- 作为 TOPSIS、灰色关联、模糊综合评价的输入:这些模型都要求先有指标权重,熵权法是最常用的"标准配件"。
2.2 竞赛典型题目
- 评价类题目(高频):如"对 个城市 / 企业的 个方面进行综合评价并排名",权重部分直接套熵权法——先熵权定权,再 TOPSIS 排序;
- 指标筛选题:熵权接近 0 的指标区分度不足,可作为"删减指标"的数据依据;
- 组合模型的权重环节:任何需要"综合得分"的模型(灰色关联度、模糊评价、VIKOR……)都可以把熵权结果作为权重输入;
- 权重敏感性分析:对比"熵权权重"与"主观权重"下的评价排名差异,本身就是论文的一个小节。
2.3 使用前提(建模前检查清单)
- 有完整的原始数据矩阵 :无缺失(少量缺失可先插值/均值填补);
- 指标是数值型(分类指标需先量化);
- 能明确每个指标的方向(正向 / 负向);
- 评价对象数 不宜太小(一般建议 , 更稳,否则权重随机性大);
- 同一指标下所有对象口径一致(如 GDP 都按亿元、同一统计年份)。
2.4 不适用 / 慎用的情形
- 数据缺失多:熵权法建立在完整比重矩阵上,缺失值过多时填补误差会直接污染权重;
- 指标业务重要性明显与数据变异矛盾:如"人均 GDP"业务上极其重要,但样本里各城市差异不大,熵权法会压低其权重——此时应改用组合赋权或主观赋权;
- 评价对象极少(如只有 3 个城市): 归一化后权重随机性大,结论不稳;
- 指标间强相关:如"GDP"与"财政收入"高度相关,熵权法会同时给两者较高权重,造成信息重复计入;
- 需要权重长期稳定的场合(如年度考核指标体系):样本一变权重就变,不适合作为固定标准。
2.5 与 AHP / TOPSIS 的组合(熵权-TOPSIS 是竞赛高频组合!)
- 熵权-TOPSIS:熵权法管"权重",TOPSIS 管"排序"——用熵权对标准化矩阵加权得到 ,再计算各对象与正理想解 、负理想解 的欧氏距离,按贴近度 排序。两个模型分工明确、衔接自然,是评价类题目的竞赛第一高频组合;
- AHP-熵权组合赋权:主观(专家经验)与客观(数据信息)按比例合成 , 通常取 0.5(各占一半),具体取值由问题背景决定,见第六节代码与第七节解读;
- 进阶还有博弈论组合赋权(使组合权重与各单一权重的偏差极小化)、离差最大化组合赋权等,可作为第八节的延伸方向。
三、算法指标
3.1 标准化后矩阵 (中间量,需提及)
- 中文名:标准化值(极差标准化 / min-max 标准化)
- 含义:把每个指标统一压到 ,消除量纲影响;负向指标被"逆向化"(越小越好的指标变成越大越好),使所有指标方向一致。
- 解读:某城市标准化值为 1 表示它在所有城市中该指标最优;0 表示最差。标准化后需做非负平移(),为熵计算铺路。
3.2 比重矩阵 (中间量)
- 中文名:比重(特征比重、概率)
- 含义:第 个对象在第 个指标上的取值占全体对象的份额,每列之和为 1,可看作一个概率分布。
- 解读:比重分布越均匀 → 该指标越"没有区分度";越集中 → 差异越大。
3.3 信息熵 (核心指标)
- 中文名:信息熵(第 个指标的信息熵)
- 含义:该指标取值分布的"混乱程度"。除以 保证 。
- 解读: 越小 → 分布越集中 → 差异越大 → 信息量越大 → 权重应越大。
3.4 差异系数 (信息效用值)
- 中文名:差异系数,又称信息效用值、信息冗余度——"信息效用"是 的另一种常见说法
- 含义: 的"反义词":该指标携带了多少有效的区分信息。
- 解读: 越大说明指标区分度越强;(即 )说明所有对象取值完全相同,指标毫无区分力。
3.5 权重 (最终输出)
- 中文名:熵权(指标 的客观权重)
- 含义:把差异系数归一化,。
- 解读: 是最终用于加权求综合得分的系数,例如综合得分 。
3.6 指标汇总表
| 指标 | 中文名 | 公式 | 取值范围 | 解读要点 |
|---|---|---|---|---|
| 标准化后矩阵 | 极差标准化(分正/负向) | 统一量纲、统一方向 | ||
| 比重矩阵 | ,列和为 1 | 越均匀区分度越差 | ||
| 信息熵 | , | 越小信息量越大 | ||
| 差异系数(信息效用值) | 越大区分度越强 | |||
| 权重(熵权) | ,和为 1 | 最终加权系数 |
四、可视化图表
4.1 四张图速查表
| 图名 | 用途 | 关键解读点 |
|---|---|---|
| ① 各指标信息熵条形图 | 展示每个指标的"混乱程度",判断哪些指标差异大 | 熵小(如房价 0.5744)→ 信息量大 → 权重大;熵接近 1 → 指标几乎无区分力 |
| ② 各指标权重柱状图(主结论图) | 直接给出最终权重,论文正文必备 | 标注数值;对比 平均线:高于平均线的指标"更有话语权" |
| ③ 差异系数与权重双轴对比图 | 同图展示 与 两套量纲 | 两条序列形状完全相同(),仅差一个常数倍,双轴只是方便读出两种数值 |
| ④ 组合赋权对比图(AHP vs 熵权 vs 组合) | 展示主观、客观、组合三套权重的差异 | 组合权重介于两者之间;主客观分歧大的指标值得在论文中讨论 |
4.2 "好图"与"异常图"的特征
好图:
- 数值标注完整(权重图每个柱子上方标数);
- 四张图指标顺序一致、同一指标同色,便于对照阅读;
- 有参考线(如权重图上的 平均线);
- 图题直接给出结论(如"房价权重最大,说明房价数据差异显著")。
异常图(出现时先查数据):
- 所有指标权重几乎相等 → 各指标变异程度都差不多,或标准化方式有问题;
- 某一指标权重为 0 → 该指标所有对象取值完全相同(或标准化出错,如整列为常数导致极差为 0、除零);
- 权重图与业务常识严重相反(如"GDP 权重垫底")→ 考虑组合赋权;
- 四张图中同一指标颜色 / 顺序不统一 → 评审阅读困难,务必统一。
五、符号说明
| 符号 | 含义 | 示例/单位 |
|---|---|---|
| 评价对象个数 | (5 个城市) | |
| 指标个数 | ||
| 原始数据矩阵() | 城市 × 指标 | |
| 第 个对象第 个指标的原始值 | 北京 GDP = 40269 亿元 | |
| 极差标准化后的值 | ,无量纲 | |
| 非负平移量 | ||
| 平移后的标准化值 | ||
| 比重(概率) | 列和为 1,无量纲 | |
| 熵的归一化常数 | , 时 | |
| 第 个指标的信息熵 | ,越小越好 | |
| 差异系数(信息效用值) | , | |
| 第 个指标的熵权 | 和为 1,无量纲 | |
| AHP 主观权重 | 和为 1 | |
| 组合赋权中主观权重的占比 | 0.5 表示各占一半 | |
| 组合权重 |
六、可运行程序(完整代码)
环境要求:Python 3.12,只依赖 numpy、pandas、matplotlib(
pip install numpy pandas matplotlib)。以下所有代码块按顺序拼接保存为ew_demo.py,在本文档所在目录运行即可:控制台打印全部指标,并在figures/子目录生成 4 张图。熵权法核心公式全部手写实现,不调用任何现成熵权库。无图形界面的环境可用MPLBACKEND=Agg python ew_demo.py跳过弹窗、只保存图片。
# -*- coding: utf-8 -*-
"""
============================================================
熵权法完整示例:手写实现(不调用任何现成熵权库)
------------------------------------------------------------
数据(合成):5 个城市 × 6 个指标(GDP、人均收入、空气优良天数、
绿化率、高校数、房价),演示"城市综合发展评价"定权。
其中空气优良天数、绿化率人为设计成"各城市差不多"
(变异小 → 熵大 → 权重小),房价、高校数差异悬殊
(变异大 → 熵小 → 权重大),直观演示熵权逻辑。
输出:控制台打印标准化矩阵、比重矩阵、信息熵/差异系数/权重表、
AHP-熵权组合赋权对比表;figures/ 目录下生成 4 张图。
依赖:numpy、pandas、matplotlib(Python 3.12)
============================================================
"""
# ========== 0. 导入库与全局设置 ==========
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# ---- matplotlib 中文显示设置(防止图内中文乱码)----
plt.rcParams["font.sans-serif"] = ["PingFang SC", "Arial Unicode MS", "SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 让负号"-"正常显示
# ---- 图片输出目录(相对当前工作目录的 figures/ 子目录)----
FIG_DIR = "figures"
os.makedirs(FIG_DIR, exist_ok=True)
# ---- 全文档统一配色:同一指标在不同图中同色,便于对照阅读 ----
C_ENTROPY = "#2a78d6" # 信息熵 e_j(图 1)
C_DIFF = "#1baf7a" # 差异系数 d_j(图 3)
C_WEIGHT = "#eb6834" # 熵权权重 w_j(图 2 / 图 3 / 图 4)
C_AHP = "#4a3aa7" # AHP 主观权重(图 4)
C_COMB = "#1baf7a" # 组合权重(图 4,与 d_j 不同图出现,共用色系)
# ========== 1. 构造数据:5 个城市 × 6 个指标(竞赛经典"城市综合发展评价") ==========
# 数值为手工构造的合成数据(仅用于演示算法流程,非真实统计值)。
# 特意设计了两组对比:
# * 空气优良天数、绿化率:五个城市"差不多"(变异小)
# → 信息熵大 → 权重小,演示"区分度不足的指标应得小权重";
# * 高校数、房价:城市间差异悬殊 → 信息熵小 → 权重大。
cities = ["北京", "上海", "广州", "深圳", "成都"]
indicators = ["GDP(亿元)", "人均收入(元)", "空气优良天数(天)",
"绿化率(%)", "高校数(所)", "房价(元/m2)"]
X = np.array([
[40269, 79000, 296, 41.5, 92, 68000], # 北京
[44652, 79500, 305, 43.6, 85, 71000], # 上海
[28839, 60000, 306, 43.9, 88, 35000], # 广州
[30664, 55000, 307, 44.1, 9, 73000], # 深圳
[20817, 40000, 308, 44.3, 12, 18000], # 成都
], dtype=float)
# 指标方向:1 = 正向(越大越好),-1 = 负向(越小越好,如房价)
direction = np.array([1, 1, 1, 1, 1, -1])
print("==================== 原始数据矩阵 X(5 个城市 × 6 个指标) ====================")
print(pd.DataFrame(X, index=cities, columns=indicators))
# ========== 2. 第①步:数据标准化(极差法,区分正/负向指标)+ 非负平移 ==========
n, m = X.shape # n = 5 个评价对象,m = 6 个指标
Z = np.zeros_like(X) # 标准化后的矩阵(n × m)
for j in range(m):
xj = X[:, j]
x_min, x_max = xj.min(), xj.max()
if direction[j] > 0:
# 正向指标(越大越好):按"距最小值的位置"缩放
Z[:, j] = (xj - x_min) / (x_max - x_min)
else:
# 负向指标(越小越好):先用最大值减去原值做"逆向化",再缩放
Z[:, j] = (x_max - xj) / (x_max - x_min)
# ---- 非负平移 ----
# 极差标准化结果落在 [0,1],最小值恰好为 0,而 ln 在 0 处无定义。
# 处理办法一(数学约定):规定 0·ln0 = 0(第 3 步用 np.where 兜底);
# 处理办法二(更稳妥):整体加一个很小的正数平移,让所有值严格大于 0。
# 若采用 Z-score 等其他标准化(可能产生负值,如"利润增长率"这类指标),
# 必须先做"负值平移处理":x'' = x' - min(x') + 1e-6,把整列抬升到正数域。
EPS = 1e-6
Z = Z + EPS
print("\n==================== 标准化后矩阵 Z(已做非负平移 +1e-6) ====================")
print(pd.DataFrame(np.round(Z, 4), index=cities, columns=indicators))
# ========== 3. 第②步:比重矩阵 p_ij = x_ij / Σ_i x_ij ==========
# 对每个指标单独归一化:比重 p_ij 可理解为"第 i 个城市在第 j 个指标上
# 占全体城市的份额",每列之和恰好为 1,构成一个"概率分布"。
P = Z / Z.sum(axis=0) # 比重矩阵 (n × m),每列和为 1
# ---- 0·ln0 = 0 的数值处理 ----
# 数学上约定 0·ln0 = 0(x → 0+ 时 x·ln x → 0,洛必达法则可证)。
# 虽然第 2 步已做 +1e-6 平移、本例不会出现 p = 0;但换用其他数据或
# 标准化方式时仍可能出现 p = 0,这里用 np.where 兜底:
# p > 0 的项正常算 p·ln(p),p = 0 的项直接贡献 0,绝不会触发 ln(0) 报错。
P_ln_P = np.where(P > 0, P * np.log(P), 0.0)
print("\n==================== 比重矩阵 P(每列之和 = 1) ====================")
print(pd.DataFrame(np.round(P, 4), index=cities, columns=indicators))
# ========== 4. 第③④⑤步:信息熵 → 差异系数 → 权重 ==========
k = 1.0 / np.log(n) # ③ 归一化常数:n 个对象时熵的最大值是 ln(n),
# 除以它使 e_j 落在 [0,1]
e = -k * P_ln_P.sum(axis=0) # ③ 信息熵 e_j:越小说明数据差异越大、信息量越大
d = 1.0 - e # ④ 差异系数(信息效用值)d_j = 1 - e_j
w = d / d.sum() # ⑤ 权重 w_j = d_j / Σ d_j(权重之和 = 1)
res = pd.DataFrame({
"信息熵 e_j": np.round(e, 4),
"差异系数 d_j(信息效用)": np.round(d, 4),
"权重 w_j": np.round(w, 4),
}, index=indicators)
print("\n==================== 熵权法计算结果(核心指标表) ====================")
print("信息熵 e_j 越小 → 数据差异越大 → 信息量越大 → 权重越大")
print(res)
print(f"\n差异系数之和 Σ d_j = {d.sum():.4f},权重之和 Σ w_j = {w.sum():.4f}(校验应=1)")
# 按权重从大到小给指标排序(论文中常用的展示方式)
order = np.argsort(-w)
print("指标按权重从大到小排序:")
for rank, j in enumerate(order, start=1):
print(f" 第{rank}名:{indicators[j]}(w = {w[j]:.4f})")
# ========== 5. 组合赋权:AHP 主观权重 + 熵权客观权重按 α 合成 ==========
# 熵权法只看数据差异,可能与业务认知冲突(例如本例中"房价"权重最大,
# 但业务上通常认为 GDP、人均收入才是城市发展的核心指标)。
# 竞赛常用做法:将 AHP(层次分析法,专家打分)主观权重与熵权客观权重
# 按比例合成,公式:w = α·w_AHP + (1-α)·w_熵权
# α ∈ [0,1] 表示主观权重的占比,α = 0.5 表示主客观各占一半。
w_ahp = np.array([0.25, 0.25, 0.10, 0.08, 0.12, 0.20]) # 专家给出的主观权重(和为 1)
alpha = 0.5 # 组合系数:主客观各占 50%
w_comb = alpha * w_ahp + (1 - alpha) * w # 组合权重
cmp = pd.DataFrame({
"AHP主观权重": w_ahp,
"熵权客观权重": np.round(w, 4),
f"组合权重(α={alpha})": np.round(w_comb, 4),
}, index=indicators)
print("\n==================== 组合赋权对比表(α = 0.5) ====================")
print(cmp)
print(f"组合权重之和 = {w_comb.sum():.4f}(校验应=1)")
# ========== 6. 图 1:各指标信息熵条形图(熵小 → 信息量大 → 权重大) ==========
x_pos = np.arange(m)
fig, ax = plt.subplots(figsize=(9, 4.8))
ax.bar(x_pos, e, width=0.6, color=C_ENTROPY, edgecolor="white", label="信息熵 e_j")
ax.set_xticks(x_pos)
ax.set_xticklabels(indicators)
ax.set_ylabel("信息熵 e_j")
ax.set_ylim(0, 1.15)
ax.set_xlim(-0.5, 7.8)
ax.set_title("各指标信息熵 e_j(越小说明数据差异越大、信息量越大)")
ax.grid(axis="y", linestyle="--", alpha=0.35)
for xi, ei in zip(x_pos, e): # 每个柱子上方标注熵值
ax.text(xi, ei + 0.02, f"{ei:.4f}", ha="center", va="bottom", fontsize=9)
# 两处关键标注:熵大(区分度不足)与熵小(信息量大)
ax.annotate("空气/绿化:熵大 → 各城市差不多 → 区分度不足",
xy=(2.5, 0.86), xytext=(0.7, 1.06), fontsize=9,
arrowprops=dict(arrowstyle="->", color="0.4"))
ax.annotate("房价:熵最小 → 信息量最大 → 权重应最大",
xy=(5.0, e[5]), xytext=(5.6, 0.45), fontsize=9,
arrowprops=dict(arrowstyle="->", color="0.4"))
plt.tight_layout()
plt.savefig(os.path.join(FIG_DIR, "ew_entropy_bar.png"), dpi=200)
# ========== 7. 图 2:各指标权重柱状图(标注数值,主结论图) ==========
fig, ax = plt.subplots(figsize=(9, 4.8))
ax.bar(x_pos, w, width=0.6, color=C_WEIGHT, edgecolor="white", label="权重 w_j")
ax.axhline(1.0 / m, color="0.5", linestyle="--", linewidth=1.2,
label=f"平均权重 1/m = {1/m:.3f}(无信息时的权重)")
ax.set_xticks(x_pos)
ax.set_xticklabels(indicators)
ax.set_ylabel("权重 w_j")
ax.set_ylim(0, w.max() * 1.3)
ax.set_title("熵权法确定的各指标权重(权重越大,指标区分度越强)")
ax.legend(loc="upper right")
ax.grid(axis="y", linestyle="--", alpha=0.35)
for xi, wi in zip(x_pos, w): # 每个柱子上方标注权重数值
ax.text(xi, wi + 0.008, f"{wi:.4f}", ha="center", va="bottom",
fontsize=10, fontweight="bold")
plt.tight_layout()
plt.savefig(os.path.join(FIG_DIR, "ew_weights_bar.png"), dpi=200)
# ========== 8. 图 3:差异系数与权重双轴对比图 ==========
# 注意 w_j = d_j / Σ d_j,两条序列形状完全相同(只差一个常数倍数),
# 双轴只是为了在同一张图上读出两种量纲:左轴差异系数,右轴权重。
fig, ax1 = plt.subplots(figsize=(9, 4.8))
ax1.bar(x_pos, d, width=0.55, color=C_DIFF, edgecolor="white",
label="差异系数 d_j(左轴)")
ax1.set_xticks(x_pos)
ax1.set_xticklabels(indicators)
ax1.set_ylabel("差异系数 d_j", color=C_DIFF)
ax1.set_ylim(0, d.max() * 1.25)
ax1.tick_params(axis="y", labelcolor=C_DIFF)
ax2 = ax1.twinx() # 右轴:权重
ax2.plot(x_pos, w, color=C_WEIGHT, marker="o", markersize=7, linewidth=2,
label="权重 w_j(右轴)")
ax2.set_ylabel("权重 w_j", color=C_WEIGHT)
ax2.set_ylim(0, w.max() * 1.1) # 让折线整体落在柱子上方,避免标注重叠
ax2.tick_params(axis="y", labelcolor=C_WEIGHT)
ax1.set_title("差异系数 d_j 与权重 w_j 双轴对比(w_j 与 d_j 成正比,仅量纲不同)")
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1 + h2, l1 + l2, loc="upper left")
ax1.grid(axis="y", linestyle="--", alpha=0.35)
for xi, di in zip(x_pos, d): # 左轴:标注差异系数
ax1.text(xi, di + 0.012, f"{di:.4f}", ha="center", va="bottom", fontsize=9)
for xi, wi in zip(x_pos, w): # 右轴:标注权重
ax2.text(xi, wi + 0.006, f"{wi:.4f}", ha="center", va="bottom",
fontsize=9, color=C_WEIGHT)
plt.tight_layout()
plt.savefig(os.path.join(FIG_DIR, "ew_compare.png"), dpi=200)
# ========== 9. 图 4:组合赋权对比图(AHP 主观 vs 熵权客观 vs 组合) ==========
fig, ax = plt.subplots(figsize=(9.5, 5))
width = 0.24 # 三组柱子并排,留出缝隙
ax.bar(x_pos - width, w_ahp, width, color=C_AHP, edgecolor="white",
label="AHP 主观权重")
ax.bar(x_pos, w, width, color=C_WEIGHT, edgecolor="white",
label="熵权客观权重")
ax.bar(x_pos + width, w_comb, width, color=C_COMB, edgecolor="white",
label=f"组合权重 (α={alpha})")
ax.set_xticks(x_pos)
ax.set_xticklabels(indicators)
ax.set_ylabel("权重")
ax.set_ylim(0, max(w_ahp.max(), w.max(), w_comb.max()) * 1.25)
ax.set_title("AHP 主观权重、熵权客观权重与组合权重对比")
ax.legend(loc="upper right")
ax.grid(axis="y", linestyle="--", alpha=0.35)
for xi, wi in zip(x_pos, w_comb): # 只标注组合权重(最终结果)
ax.text(xi + width, wi + 0.008, f"{wi:.4f}", ha="center", va="bottom", fontsize=9)
plt.tight_layout()
plt.savefig(os.path.join(FIG_DIR, "ew_ahp_compare.png"), dpi=200)
# ========== 10. 显示图形 ==========
# 在带图形界面的环境(本地 IDE / 终端)中会弹出 4 个窗口,关闭后脚本结束;
# 在服务器等无图形界面环境中 matplotlib 会自动跳过显示,仅保留 PNG 图片。
# 命令行批量运行可加环境变量 MPLBACKEND=Agg 直接跳过弹窗。
plt.show()
print("\n4 张图已保存至 figures/ 目录:")
print(" ew_entropy_bar.png / ew_weights_bar.png / ew_compare.png / ew_ahp_compare.png")
七、结果解读与注意事项
7.1 运行输出解读(以本例合成数据为例)
本例 5 个城市 × 6 个指标,程序输出如下(保留 4 位小数):
| 指标 | 信息熵 | 差异系数 | 权重 |
|---|---|---|---|
| GDP(亿元) | 0.8028 | 0.1972 | 0.1430 |
| 人均收入(元) | 0.8126 | 0.1874 | 0.1359 |
| 空气优良天数(天) | 0.8578 | 0.1422 | 0.1031 |
| 绿化率(%) | 0.8579 | 0.1421 | 0.1030 |
| 高校数(所) | 0.7153 | 0.2847 | 0.2064 |
| 房价(元/m²) | 0.5744 | 0.4256 | 0.3086 |
怎么读这张表:
- 房价权重最大(0.3086):五个城市房价从 1.8 万到 7.3 万/m²,差异悬殊(极差 5.5 万),标准化后比重高度集中在成都(占 55%),信息熵最小(0.5744)→ 信息量最大 → 权重最大。注意房价是负向指标:标准化时做了逆向化,房价越低的城市标准化值越高(越接近"好"的一端)。
- 高校数权重次之(0.2064):深圳 9 所与北京 92 所差异明显,该指标区分度强。
- GDP(0.1430)、人均收入(0.1359)权重居中:城市间虽有差异,但按极差标准化后比重分布相对均衡。
- 空气优良天数(0.1031)与绿化率(0.1030)权重最低:五个城市的优良天数都在 296~308 天、绿化率都在 41.5%~44.3%——空气质量指标各城市差异小 → 权重低,说明该指标区分度不足。注意:这并不意味着"空气不重要",而是"在这五个城市里,该指标分不出高下",对排名的贡献有限。这正是熵权法的特点,也是它的争议点。
- 组合赋权(α = 0.5):AHP 主观权重认为 GDP、人均收入最重要(各 0.25),与熵权"房价最重要"分歧明显;按 合成后:GDP 0.1965、人均收入 0.1930、空气优良天数 0.1015、绿化率 0.0915、高校数 0.1632、房价 0.2543——房价权重被拉回 0.25 附近,GDP/收入权重抬升,主客观观点得到折中。这正是"组合赋权"的价值:既不盲从数据,也不盲从专家。
7.2 常见坑与应对
- 忘记非负平移导致 ln 报错:极差标准化必然产生 0,直接
np.log(0)会得到-inf(计算熵时出现 nan)。两种解法:整体平移 ;或按约定 用np.where兜底。本例两种都做了(双保险)。 - 负值平移处理:原始数据或 Z-score 标准化出现负值时,必须先整体抬升:,否则 对负数报错。
- 标准化方式不唯一:min-max 与 Z-score 得到的权重不同。竞赛中写明所用方式("采用极差标准化")并保持一致即可,切忌前文 min-max、后文 Z-score 混用。
- 熵权为零时的权重重分配:若某指标 (所有对象取值完全相同)则 ;若多个指标都如此,权重只在剩余指标间重新分配,此时应考虑删掉无区分度指标后重新计算,或改用组合赋权。
- 指标方向标反:房价、碳排放等成本类指标必须设为负向,否则"越贵越好"的结论会完全颠倒。
- 忘记除以 :不归一化不改变权重排序( 同时放大),但熵值会超出 ,论文里写"熵值介于 0 和 1 之间"会被评审质疑。
7.3 竞赛论文写作建议(话术模板)
采用熵权法客观确定各指标权重,计算结果见表 X:其中指标房价权重最大(0.3086),说明该指标数据差异显著、信息量大;空气优良天数(0.1031)与绿化率(0.1030)权重较小,说明这两个指标在各城市间差异不大、区分度不足。进一步,为兼顾业务经验,将熵权法客观权重与 AHP 主观权重按 0.5:0.5 进行组合赋权,得到综合权重:GDP 0.1965、人均收入 0.1930、空气优良天数 0.1015、绿化率 0.0915、高校数 0.1632、房价 0.2543,并据此计算各城市综合得分与排名……
写作要点:
- 正文放权重表 + 权重柱状图(图 2),熵值条形图(图 1)可放附录或简略提及;
- **组合赋权对比图(图 4)**用于说明"客观权重与业务认知的差异及折中",是展示建模思考深度的加分项;
- 若某些指标权重过低(如本例空气、绿化),主动解释"该指标区分度不足",比被评审问出来好;
- 权重表保留 4 位小数即可,并注明"权重之和为 1"的校验。
八、延伸阅读
- 改进熵权法:针对 的修正、标准化方式的改进(如平移量自适应)、区间熵权、非平衡数据下的熵权修正等——用于处理"权重为零 / 权重失稳"问题;
- 熵权-TOPSIS:熵权定权 + TOPSIS 排序(加权距离与正负理想解的贴近度),评价类题目的竞赛标配组合;
- 熵权-灰色关联分析:熵权定权后,用灰色关联度衡量各对象与理想序列的相似度并排序,适合小样本、贫信息场景;
- CRITIC 法:另一种客观赋权法,用指标的对比强度(标准差)× 冲突性( 与其他指标的相关系数)定权,同时考虑变异与相关性,可作为熵权法的对照或改进;
- 其他:变异系数法(最朴素的客观赋权)、主成分分析定权、博弈论组合赋权(使组合权重与各单一权重偏差极小化)。