熵权法
本文最后更新于 2025年7月28日 上午
25年暑假学习数模算法时做的一些笔记。
熵权法
一种比较客观的,得到权重的方法
依据的原理:指标的变异程度越小,所反映的信息量也越少,其对应的权值也应该越低。
步骤
1.数据标准化
矩阵标准化之后为$Z$,满足 $$ z_{ij} = \frac{x_{ij}}{\sqrt{\sum_{i=1}^{n} x_{ij}}} $$ 若存在负数,则 $$ \tilde{Z} = \frac{x - \min{x_{1j}, x_{2j}, ..., x_{nj}}}{\max{x_{1j}, x_{2j}, ..., x_{nj}} - \min{x_{1j}, x_{2j}, ..., x_{nj}}} \ \tilde{Z} \in (0,1) $$
2.计算概率矩阵$P$
$$ p_{ij} = \frac{z_{ij}}{\sum_{i=1}^{n} z_{ij}} $$
3.计算熵权
$$ 信息熵e_j = -\frac{1}{\ln n} \sum_{i=1}^{n} p_{ij} \ln(p_{ij}) \quad (j=1,2,...,m) \ 信息效用值d_j=1-e_j \ 归一化得到w_j=\frac{d_j}{\sum_{j=1}^{m}d_j} \ 其中 W_j 为第 j 个指标的熵权。 $$
Python代码
代码
import numpy as np
def entropy_weight(X):
"""
根据给定的数据矩阵计算熵权。
参数:
X (np.array): 数据矩阵,n行(样本)x m列(指标)。
返回:
np.array: 每个指标的权重 w。
"""
# 将输入转换为numpy数组
X = np.array(X)
# --- 步骤 1: 数据标准化 ---
# 为了普适性和避免负数带来的问题,我们使用您提供的第二种标准化方法 (Min-Max Normalization)
# Z = (x - min) / (max - min)
# PS: 如果您的数据保证全为正数,也可以使用第一种方法。
# 检查数据中是否存在负数
if np.any(X < 0):
print("数据中存在负数,将使用 Min-Max 标准化方法。")
# 对每一列(指标)进行标准化
min_vals = X.min(axis=0)
max_vals = X.max(axis=0)
# 防止分母为0
ranges = max_vals - min_vals
ranges[ranges == 0] = 1
Z = (X - min_vals) / ranges
else:
print("数据中无负数,将使用向量归一化方法。")
# z_ij = x_ij / sqrt(sum(x_ij^2 for i in 1 to n))
# 注意:您给出的公式是 x_ij / sqrt(sum(x_ij)),这在数学上不常见。
# 通常使用的是向量范数,即除以平方和的平方根。这里我们按照常规的向量标准化来处理。
norm_base = np.sqrt((X**2).sum(axis=0))
# 防止分母为0
norm_base[norm_base == 0] = 1
Z = X / norm_base
# 处理标准化后可能出现的0值,为其加上一个极小值,以防止log(0)错误
Z[Z == 0] = 1e-9
# --- 步骤 2: 计算概率矩阵 P ---
# p_ij = z_ij / sum(z_ij for i in 1 to n)
P = Z / Z.sum(axis=0)
# --- 步骤 3: 计算熵权 ---
n, m = X.shape # n 个样本, m 个指标
# 计算信息熵 e_j
# e_j = - (1/ln(n)) * sum(p_ij * ln(p_ij) for i in 1 to n)
k = -1 / np.log(n)
# 计算每个指标的信息熵
e = (P * np.log(P)).sum(axis=0) * k
# 计算信息效用值 (信息冗余度) d_j
# d_j = 1 - e_j
d = 1 - e
# 归一化得到最终权重 w_j
# w_j = d_j / sum(d_j for j in 1 to m)
w = d / d.sum()
return w
if __name__ == '__main__':
# ================================================================
# 请在这里修改您的矩阵数据
# n行样本, m列指标
# 例如,一个4个样本、3个指标的矩阵
X = [
[8, 9, 7],
[6, 7, 8],
[9, 6, 6],
[7, 8, 9]
]
# ================================================================
# 将列表转换为numpy数组以便计算
X_matrix = np.array(X)
# 调用函数计算权重
weights = entropy_weight(X_matrix)
# 打印结果
print("\n计算得到的各指标权重为:")
for i, w in enumerate(weights):
print(f"指标 {i+1}: {w:.4f}")