引言:熵值法的基本概念与理论基础

熵值法(Entropy Method)是一种基于信息熵理论的客观赋权方法,由香农(C.E. Shannon)在信息论中引入。在多指标综合评价中,熵值法通过分析各指标数据的离散程度来确定权重,离散程度越大,该指标提供的信息量越多,权重就越大。这种方法避免了主观赋权的偏差,具有较强的数学严谨性和客观性。

熵值法的核心思想是:如果某个指标在所有样本中的取值差异很小(即数据离散程度低),说明该指标在综合评价中发挥的作用较小,应赋予较低的权重;反之,如果取值差异很大,则应赋予较高权重。这种方法特别适用于指标间存在相关性、且需要客观赋权的复杂系统评价问题。

熵值法的基本原理

信息熵的概念

信息熵是度量系统不确定性的一个物理量。对于一个离散随机变量X,其概率分布为P(X) = {p₁, p₂, …, pₙ},则信息熵定义为:

H(X) = -Σ(pᵢ * ln(pᵢ))

其中,pᵢ表示事件i发生的概率,ln是自然对数。信息熵越大,系统的不确定性越高,包含的信息量越少;信息熵越小,系统的确定性越高,包含的信息量越多。

熵值法在综合评价中的应用

在综合评价中,假设有m个评价对象,n个评价指标,形成原始数据矩阵X = (xᵢⱼ)ₘₓₙ。熵值法通过以下步骤计算各指标的权重:

  1. 数据标准化:消除量纲影响,使不同指标具有可比性
  2. 计算比重:计算每个样本在各指标中的比重
  3. 计算熵值:根据比重计算各指标的信息熵
  4. 计算权重:根据熵值计算各指标的权重系数

熵值法的详细计算步骤

第一步:数据标准化处理

由于不同指标的量纲和数量级可能不同,首先需要对原始数据进行标准化处理。常见的标准化方法有极差法、Z-score法等。这里介绍最常用的极差标准化方法:

对于效益型指标(越大越好):

yᵢⱼ = (xᵢⱼ - min(xⱼ)) / (max(xⱼ) - min(xⱼ))

对于成本型指标(越小越好):

yᵢⱼ = (max(xⱼ) - xᵢⱼ) / (max(xⱼ) - 3. 第二步:计算指标比重

计算第j项指标下第i个样本占该指标的比重:

pᵢⱼ = yᵢⱼ / Σ(yᵢⱼ) (i=1,2,…,m; j=1,2,…,n)


### 第三步:计算信息熵

计算第j项指标的信息熵:

eⱼ = -k * Σ(pᵢⱼ * ln(pᵢⱼ))

其中k为常数,通常取k = 1/ln(m),以确保eⱼ ∈ [0,1]。

### 第四步:计算信息冗余度

信息冗余度(也称为差异系数)反映了指标提供信息的能力:

dⱼ = 1 - eⱼ


### 第五步:计算指标权重

最终计算各指标的权重:

wⱼ = dⱼ / Σ(dⱼ)


## Python代码实现

下面是一个完整的Python实现,包含详细的注释和示例数据:

```python
import numpy as np
import pandas as

# 示例数据:假设我们有5个地区,每个地区有4个评价指标
# 指标1:GDP增长率(效益型)
# 指标2:人均收入(效益型)
# 挑选:失业率(成本型)
# 指标4:教育投入占比(效益型)
data = {
    '地区': ['A', 'B', 'C', 'D', 'E'],
    'GDP增长率': [8.2, 7.5, 6.8, 7.2, 8.5],
    '人均收入': [50000, 48000, 42000, 45000, 52000],
    '失业率': [3.2, 3.8, 4.5, 4.0, 3.0],
    '教育投入占比': [4.2, 3.8, 3.5, 4.0, 4.5]
}

df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("\n" + "="*50 + "\n")

# 提取数值数据(排除地区列)
numeric_data = df.iloc[:, 1:].values
m, n = numeric_data.shape

# 定义指标类型:True表示效益型,False表示成本型
benefit_type = [True, True, False, True]

# 第一步:数据标准化
def standardize(data, benefit_type):
    """
    数据标准化处理
    data: 原始数据矩阵
    benefit_type: 指标类型列表,True为效益型,False为成本型
    """
    standardized = np.zeros_like(data)
    for j in range(data.shape[1]):
        col = data[:, j]
        if benefit_type[j]:
            # 效益型指标:越大越好
            standardized[:, j] = (col - col.min()) / (col.max() - col.min())
        else:
            # 成本型指标:越小越好
            standardized[:, j] = (col.max() - col) / (col.max() - col.min())
    return standardized

# 执行标准化
y = standardize(numeric_data, benefit_type)
print("标准化后的数据:")
print(y)
print("\n" + "="*50 + "\n")

# 第二步:计算指标比重
def calculate_proportion(y):
    """
    计算指标比重
    """
    # 避免0值导致对数计算错误,添加一个极小值
    epsilon = 1e-10
    p = y + epsilon
    # 计算每列的和
    col_sums = p.sum(axis=0)
    # 计算比重
    p = p / col_sums
    return p

p = calculate_proportion(y)
print("指标比重:")
print(p)
print("\n" + "="*50 + "\n")

# 第三步:计算信息熵
def calculate_entropy(p):
    """
    计算信息熵
    """
    m = p.shape[0]
    k = 1 / np.log(m)
    # 计算每列的熵值
    e = -k * np.sum(p * np.log(p), axis=0)
    return e

e = calculate_entropy(p)
print("各指标的信息熵:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {e[j]:.4f}")
print("\n" + "="*50 + "\n")

# 第四步:计算信息冗余度
def calculate_redundancy(e):
    """
    计算信息冗余度(差异系数)
    """
    return 1 - e

d = calculate_redundancy(e)
print("各指标的信息冗余度:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {d[j]:.4f}")
print("\n" + "="*50 + "\n")

# 第五步:计算权重
def calculate_weight(d):
    """
    计算指标权重
    """
    w = d / np.sum(d)
    return w

w = calculate_weight(d)
print("各指标的最终权重:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {w[j]:.4f} ({w[j]*100:.2f}%)")
print("\n" + "="*50 + "\n")

# 综合评价得分计算
def calculate_score(y, w):
    """
    计算综合评价得分
    y: 标准化后的数据
    w: 权重向量
    """
    return np.dot(y, w)

scores = calculate_score(y, w)
print("各地区的综合评价得分:")
for i, region in enumerate(df['地区']):
    print(f"{region}: {scores[i]:.4f}")

# 结果排序
sorted_indices = np.argsort(scores)[::-1]  # 降序排列
print("\n综合评价排名:")
for rank, idx in enumerate(sorted_indices, 1):
    print(f"第{rank}名: {df['地区'][idx]} (得分: {scores[idx]:.4f})")

实际应用案例:城市综合实力评价

案例背景

假设我们要评价5个城市的综合实力,选取了以下6个指标:

  1. GDP总量(效益型):反映经济规模
  2. 人均GDP(效益型):反映经济效率
  3. 第三产业占比(效益型):反映产业结构优化程度
  4. 固定资产投资(效益型):反映发展后劲
  5. 居民人均可支配收入(效益型):反映民生水平 6.空气质量优良天数(效益型):反映生态环境质量

完整案例代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 创建更复杂的案例数据
np.random.seed(42)  # 保证结果可复现

cities = ['北京', '上海', '广州', '深圳', '杭州']
data = {
    '城市': cities,
    'GDP总量(万亿)': [3.61, 3.87, 2.50, 2.69, 1.61],
    '人均GDP(万元)': [17.4, 16.8, 15.0, 15.8, 13.5],
    '第三产业占比(%)': [82.5, 72.7, 70.6, 60.1, 64.2],
    '固定资产投资(万亿)': [0.79, 0.76, 0.58, 0.52, 0.57],
    '居民人均可支配收入(万元)': [7.5, 7.2, 6.8, 6.4, 6.0],
    '空气质量优良天数': [288, 265, 295, 310, 285]
}

df = pd.DataFrame(data)
print("城市综合实力评价原始数据:")
print(df)
print("\n" + "="*60 + "\n")

# 提取数值数据
numeric_data = df.iloc[:, 1:].values
m, n = numeric_data.shape

# 所有指标都是效益型
benefit_type = [True] * n

# 封装完整的熵值法计算过程
class EntropyMethod:
    def __init__(self, benefit_type):
        self.benefit_type = benefit_type
        self.weights = None
        self.standardized_data = None
        self.entropy = None
        self.redundancy = None
        
    def fit(self, data):
        """
        执行完整的熵值法计算
        """
        # 1. 数据标准化
        self.standardized_data = self._standardize(data)
        
        # 2. 计算比重
        p = self._calculate_proportion(self.standardized_data)
        
        # 3. 计算信息熵
        self.entropy = self._calculate_entropy(p)
        
        # 4. 计算信息冗余度
        self.redundancy = self._calculate_redundancy(self.entropy)
        
        # 5. 计算权重
        self.weights = self._calculate_weight(self.redundancy)
        
        return self
    
    def _standardize(self, data):
        """数据标准化"""
        standardized = np.zeros_like(data)
        for j in range(data.shape[1]):
            col = data[:, j]
            if self.benefit_type[j]:
                standardized[:, j] = (col - col.min()) / (col.max() - col.min())
            else:
                standardized[:, j] = (col.max() - col) / (col.max() - col.min())
        return standardized
    
    def _calculate_proportion(self, y):
        """计算指标比重"""
        epsilon = 1e-10
        p = y + epsilon
        col_sums = p.sum(axis=0)
        return p / col_sums
    
    def _calculate_entropy(self, p):
        """计算信息熵"""
        m = p.shape[0]
        k = 1 / np.log(m)
        return -k * np.sum(p * np.log(p), axis=0)
    
    def _calculate_redundancy(self, e):
        """计算信息冗余度"""
        return 1 - e
    
    def _calculate_weight(self, d):
        """计算权重"""
        return d / np.sum(d)
    
    def predict(self, data):
        """计算综合得分"""
        standardized = self._standardize(data)
        return np.dot(standardized, self.weights)

# 实例化并计算
entropy_method = EntropyMethod(benefit_type)
entropy_method.fit(numeric_data)

# 输出详细结果
print("=== 熵值法计算结果 ===\n")

print("1. 标准化后的数据:")
std_df = pd.DataFrame(
    entropy_method.standardized_data,
    columns=df.columns[1:],
    index=df['城市']
)
print(std_df.round(4))
print("\n" + "-"*60 + "\n")

print("2. 各指标信息熵:")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {entropy_method.entropy[i]:.6f}")
print("\n" + "-"*60 + "\n")

print("3. 各指标信息冗余度:")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {entropy_method.redundancy[i]:.6f}")
print("\n" + "-"*60 + "\n")

print("4. 各指标权重:")
weights_df = pd.DataFrame({
    '指标': df.columns[1:],
    '权重': entropy_method.weights,
    '权重(%)': entropy_method.weights * 100
})
print(weights_df.round(4))
print("\n" + "-"*60 + "\n")

# 计算综合得分
scores = entropy_method.predict(numeric_data)
print("5. 各城市综合得分及排名:")
results_df = pd.DataFrame({
    '城市': df['城市'],
    '综合得分': scores
})
results_df['排名'] = results_df['综合得分'].rank(ascending=False, method='min')
results_df = results_df.sort_values('综合得分', ascending=False)
print(results_df.round(4))
print("\n" + "="*60 + "\n")

# 可视化分析
plt.figure(figsize=(14, 6))

# 子图1:权重分布
plt.subplot(1, 2, 1)
bars = plt.barh(range(len(entropy_method.weights)), entropy_method.weights)
plt.yticks(range(len(entropy_method.weights)), df.columns[1:], fontsize=10)
plt.xlabel('权重', fontsize=12)
plt.title('各指标权重分布', fontsize=14, fontweight='bold')
for i, bar in enumerate(bars):
    width = bar.get_width()
    plt.text(width + 0.001, bar.get_y() + bar.get_height()/2, 
             f'{width:.4f}', ha='left', va='center', fontsize=10)

# 子图2:城市综合得分
plt.subplot(1, 2, 2)
colors = plt.cm.viridis(np.linspace(0, 1, len(results_df)))
bars = plt.bar(results_df['城市'], results_df['综合得分'], color=colors)
plt.ylabel('综合得分', fontsize=12)
plt.title('城市综合实力排名', fontsize=14, fontweight='bold')
plt.xticks(rotation=45)
for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2., height + 0.01,
             f'{height:.3f}', ha='center', va='bottom', fontsize=10)

plt.tight_layout()
plt.show()

# 敏感性分析:观察权重稳定性
print("\n=== 敏感性分析 ===\n")
print("通过调整数据观察权重变化:")
# 创建一个扰动数据集
np.random.seed(123)
perturbation = np.random.normal(1.0, 0.05, numeric_data.shape)  # 5%的随机扰动
perturbed_data = numeric_data * perturbation

entropy_perturbed = EntropyMethod(benefit_type)
entropy_perturbed.fit(perturbed_data)

print("\n原始权重 vs 扰动后权重:")
comparison_df = pd.DataFrame({
    '指标': df.columns[1:],
    '原始权重': entropy_method.weights,
    '扰动后权重': entropy_perturbed.weights,
    '变化率(%)': (entropy_perturbed.weights - entropy_method.weights) / entropy_method.weights * 100
})
print(comparison_df.round(4))

熵值法的优缺点分析

优点

  1. 客观性强:完全基于数据本身的离散程度确定权重,避免了主观判断的偏差
  2. 数学严谨:有坚实的理论基础,计算过程标准化
  3. 适用范围广:适用于各种类型的多指标综合评价问题
  4. 可解释性好:权重大小直接反映指标信息量的多少

缺点

  1. 对极端值敏感:个别极端值会显著影响权重计算
  2. 要求样本量适中:样本量过少时,计算结果可能不稳定
  3. 无法反映指标重要性差异:完全依赖数据,可能忽略实际业务中指标的重要性差异
  4. 可能产生权重分配不均:当某些指标数据离散度特别大时,可能产生权重过度集中

实际应用中的注意事项

1. 数据预处理

  • 异常值处理:在计算前应识别和处理异常值
  • 缺失值填补:合理处理缺失数据,避免影响计算结果
  1. 数据一致性:确保所有指标方向一致(效益型或成本型)

2. 样本量要求

  • 一般建议样本量m ≥ 5,否则计算结果可能不稳定
  • 指标数量n不宜过多,避免权重过于分散

3. 结果解释

  • 权重仅反映数据离散程度,不一定代表实际重要性
  • 建议结合主观赋权法(如AHP)进行组合赋权

4. 模型验证

  • 通过敏感性分析检验结果的稳定性
  • 与其他赋权方法结果进行对比验证

扩展应用:与其他方法的结合

1. 熵值法与AHP结合(组合赋权)

def combined_weight(entropy_weight, ahp_weight, alpha=0.5):
    """
    组合赋权:alpha表示熵值法权重占比
    """
    return alpha * entropy_weight + (1 - alpha) * ahp_weight

# 示例:假设AHP权重为[0.2, 0.2, 0.2, 0.2, 0.1, 0.1]
ahp_weights = np.array([0.2, 0.2, 0.2, 0.2, 0.1, 0.1])
combined = combined_weight(entropy_method.weights, ahp_weights, alpha=0.6)
print("\n组合权重(熵值法60% + AHP40%):")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {combined[i]:.4f} ({combined[i]*100:.2f}%)")

2. 熵值法与TOPSIS结合

def topsis_with_entropy(data, benefit_type, entropy_method):
    """
    熵值法赋权 + TOPSIS评价
    """
    # 1. 标准化
    std_data = entropy_method._standardize(data)
    
    # 2. 加权标准化矩阵
    weights = entropy_method.weights
    weighted_std = std_data * weights
    
    # 3. 确定正理想解和负理想解
    # 效益型指标:越大越好;成本型指标:越小越好
    ideal_positive = np.array([std_data[:, j].max() if benefit_type[j] else std_data[:, j].min() 
                              for j in range(len(benefit_type))])
    ideal_negative = np.array([std_data[:, j].min() if benefit_type[j] else std_data[:, j].max() 
                              for j in range(len(benefit_type))])
    
    # 4. 计算距离
    d_positive = np.sqrt(np.sum((weighted_std - ideal_positive * weights)**2, axis=1))
    d_negative = np.sqrt(np.sum((weighted_std - ideal_negative * weights)**2, axis=1))
    
    # 5. 计算贴近度
    closeness = d_negative / (d_positive + d_negative)
    
    return closeness

# 应用示例
topsis_scores = topsis_with_entropy(numeric_data, benefit_type, entropy_method)
print("\n熵值法+TOPSIS综合得分:")
for i, city in enumerate(df['城市']):
    print(f"   {city}: {topsis_scores[i]:.4f}")

结论

熵值法作为一种客观赋权方法,在多指标综合评价中具有重要价值。通过分析数据本身的离散程度来确定权重,避免了主观偏差,使评价结果更加科学合理。然而,在实际应用中,我们需要注意其局限性,结合具体问题特点,必要时与其他方法组合使用,以获得更可靠的评价结果。

关键要点总结:

  1. 客观性:权重完全由数据决定,避免主观干扰
  2. 适用性:适用于样本量充足、指标间相关性不强的情况
  3. 局限性:对极端值敏感,可能忽略指标实际重要性差异
  4. 改进方向:可与主观赋权法、其他评价方法结合使用

通过本文的详细解析和完整代码示例,读者可以掌握熵值法的核心原理、计算步骤和实际应用技巧,为相关研究和实践提供有力工具。# 基于熵值法的综合研究指数值计算方法与实际应用解析

引言:熵值法的基本概念与理论基础

熵值法(Entropy Method)是一种基于信息熵理论的客观赋权方法,由香农(C.E. Shannon)在信息论中引入。在多指标综合评价中,熵值法通过分析各指标数据的离散程度来确定权重,离散程度越大,该指标提供的信息量越多,权重就越大。这种方法避免了主观赋权的偏差,具有较强的数学严谨性和客观性。

熵值法的核心思想是:如果某个指标在所有样本中的取值差异很小(即数据离散程度低),说明该指标在综合评价中发挥的作用较小,应赋予较低的权重;反之,如果取值差异很大,则应赋予较高权重。这种方法特别适用于指标间存在相关性、且需要客观赋权的复杂系统评价问题。

熵值法的基本原理

信息熵的概念

信息熵是度量系统不确定性的一个物理量。对于一个离散随机变量X,其概率分布为P(X) = {p₁, p₂, …, pₙ},则信息熵定义为:

H(X) = -Σ(pᵢ * ln(pᵢ))

其中,pᵢ表示事件i发生的概率,ln是自然对数。信息熵越大,系统的不确定性越高,包含的信息量越少;信息熵越小,系统的确定性越高,包含的信息量越多。

熵值法在综合评价中的应用

在综合评价中,假设有m个评价对象,n个评价指标,形成原始数据矩阵X = (xᵢⱼ)ₘₓₙ。熵值法通过以下步骤计算各指标的权重:

  1. 数据标准化:消除量纲影响,使不同指标具有可比性
  2. 计算比重:计算每个样本在各指标中的比重
  3. 计算熵值:根据比重计算各指标的信息熵
  4. 计算权重:根据熵值计算各指标的权重系数

熵值法的详细计算步骤

第一步:数据标准化处理

由于不同指标的量纲和数量级可能不同,首先需要对原始数据进行标准化处理。常见的标准化方法有极差法、Z-score法等。这里介绍最常用的极差标准化方法:

对于效益型指标(越大越好):

yᵢⱼ = (xᵢⱼ - min(xⱼ)) / (max(xⱼ) - min(xⱼ))

对于成本型指标(越小越好):

yᵢⱼ = (max(xⱼ) - xᵢⱼ) / (max(xⱼ) - min(xⱼ))

第二步:计算指标比重

计算第j项指标下第i个样本占该指标的比重:

pᵢⱼ = yᵢⱼ / Σ(yᵢⱼ)  (i=1,2,...,m; j=1,2,...,n)

第三步:计算信息熵

计算第j项指标的信息熵:

eⱼ = -k * Σ(pᵢⱼ * ln(pᵢⱼ))

其中k为常数,通常取k = 1/ln(m),以确保eⱼ ∈ [0,1]。

第四步:计算信息冗余度

信息冗余度(也称为差异系数)反映了指标提供信息的能力:

dⱼ = 1 - eⱼ

第五步:计算指标权重

最终计算各指标的权重:

wⱼ = dⱼ / Σ(dⱼ)

Python代码实现

下面是一个完整的Python实现,包含详细的注释和示例数据:

import numpy as np
import pandas as pd

# 示例数据:假设我们有5个地区,每个地区有4个评价指标
# 指标1:GDP增长率(效益型)
# 指标2:人均收入(效益型)
# 挑选:失业率(成本型)
# 指标4:教育投入占比(效益型)
data = {
    '地区': ['A', 'B', 'C', 'D', 'E'],
    'GDP增长率': [8.2, 7.5, 6.8, 7.2, 8.5],
    '人均收入': [50000, 48000, 42000, 45000, 52000],
    '失业率': [3.2, 3.8, 4.5, 4.0, 3.0],
    '教育投入占比': [4.2, 3.8, 3.5, 4.0, 4.5]
}

df = pd.DataFrame(data)
print("原始数据:")
print(df)
print("\n" + "="*50 + "\n")

# 提取数值数据(排除地区列)
numeric_data = df.iloc[:, 1:].values
m, n = numeric_data.shape

# 定义指标类型:True表示效益型,False表示成本型
benefit_type = [True, True, False, True]

# 第一步:数据标准化
def standardize(data, benefit_type):
    """
    数据标准化处理
    data: 原始数据矩阵
    benefit_type: 指标类型列表,True为效益型,False为成本型
    """
    standardized = np.zeros_like(data)
    for j in range(data.shape[1]):
        col = data[:, j]
        if benefit_type[j]:
            # 效益型指标:越大越好
            standardized[:, j] = (col - col.min()) / (col.max() - col.min())
        else:
            # 成本型指标:越小越好
            standardized[:, j] = (col.max() - col) / (col.max() - col.min())
    return standardized

# 执行标准化
y = standardize(numeric_data, benefit_type)
print("标准化后的数据:")
print(y)
print("\n" + "="*50 + "\n")

# 第二步:计算指标比重
def calculate_proportion(y):
    """
    计算指标比重
    """
    # 避免0值导致对数计算错误,添加一个极小值
    epsilon = 1e-10
    p = y + epsilon
    # 计算每列的和
    col_sums = p.sum(axis=0)
    # 计算比重
    p = p / col_sums
    return p

p = calculate_proportion(y)
print("指标比重:")
print(p)
print("\n" + "="*50 + "\n")

# 第三步:计算信息熵
def calculate_entropy(p):
    """
    计算信息熵
    """
    m = p.shape[0]
    k = 1 / np.log(m)
    # 计算每列的熵值
    e = -k * np.sum(p * np.log(p), axis=0)
    return e

e = calculate_entropy(p)
print("各指标的信息熵:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {e[j]:.4f}")
print("\n" + "="*50 + "\n")

# 第四步:计算信息冗余度
def calculate_redundancy(e):
    """
    计算信息冗余度(差异系数)
    """
    return 1 - e

d = calculate_redundancy(e)
print("各指标的信息冗余度:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {d[j]:.4f}")
print("\n" + "="*50 + "\n")

# 第五步:计算权重
def calculate_weight(d):
    """
    计算指标权重
    """
    w = d / np.sum(d)
    return w

w = calculate_weight(d)
print("各指标的最终权重:")
for j, col_name in enumerate(df.columns[1:]):
    print(f"{col_name}: {w[j]:.4f} ({w[j]*100:.2f}%)")
print("\n" + "="*50 + "\n")

# 综合评价得分计算
def calculate_score(y, w):
    """
    计算综合评价得分
    y: 标准化后的数据
    w: 权重向量
    """
    return np.dot(y, w)

scores = calculate_score(y, w)
print("各地区的综合评价得分:")
for i, region in enumerate(df['地区']):
    print(f"{region}: {scores[i]:.4f}")

# 结果排序
sorted_indices = np.argsort(scores)[::-1]  # 降序排列
print("\n综合评价排名:")
for rank, idx in enumerate(sorted_indices, 1):
    print(f"第{rank}名: {df['地区'][idx]} (得分: {scores[idx]:.4f})")

实际应用案例:城市综合实力评价

案例背景

假设我们要评价5个城市的综合实力,选取了以下6个指标:

  1. GDP总量(效益型):反映经济规模
  2. 人均GDP(效益型):反映经济效率
  3. 第三产业占比(效益型):反映产业结构优化程度
  4. 固定资产投资(效益型):反映发展后劲
  5. 居民人均可支配收入(效益型):反映民生水平
  6. 空气质量优良天数(效益型):反映生态环境质量

完整案例代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 创建更复杂的案例数据
np.random.seed(42)  # 保证结果可复现

cities = ['北京', '上海', '广州', '深圳', '杭州']
data = {
    '城市': cities,
    'GDP总量(万亿)': [3.61, 3.87, 2.50, 2.69, 1.61],
    '人均GDP(万元)': [17.4, 16.8, 15.0, 15.8, 13.5],
    '第三产业占比(%)': [82.5, 72.7, 70.6, 60.1, 64.2],
    '固定资产投资(万亿)': [0.79, 0.76, 0.58, 0.52, 0.57],
    '居民人均可支配收入(万元)': [7.5, 7.2, 6.8, 6.4, 6.0],
    '空气质量优良天数': [288, 265, 295, 310, 285]
}

df = pd.DataFrame(data)
print("城市综合实力评价原始数据:")
print(df)
print("\n" + "="*60 + "\n")

# 提取数值数据
numeric_data = df.iloc[:, 1:].values
m, n = numeric_data.shape

# 所有指标都是效益型
benefit_type = [True] * n

# 封装完整的熵值法计算过程
class EntropyMethod:
    def __init__(self, benefit_type):
        self.benefit_type = benefit_type
        self.weights = None
        self.standardized_data = None
        self.entropy = None
        self.redundancy = None
        
    def fit(self, data):
        """
        执行完整的熵值法计算
        """
        # 1. 数据标准化
        self.standardized_data = self._standardize(data)
        
        # 2. 计算比重
        p = self._calculate_proportion(self.standardized_data)
        
        # 3. 计算信息熵
        self.entropy = self._calculate_entropy(p)
        
        # 4. 计算信息冗余度
        self.redundancy = self._calculate_redundancy(self.entropy)
        
        # 5. 计算权重
        self.weights = self._calculate_weight(self.redundancy)
        
        return self
    
    def _standardize(self, data):
        """数据标准化"""
        standardized = np.zeros_like(data)
        for j in range(data.shape[1]):
            col = data[:, j]
            if self.benefit_type[j]:
                standardized[:, j] = (col - col.min()) / (col.max() - col.min())
            else:
                standardized[:, j] = (col.max() - col) / (col.max() - col.min())
        return standardized
    
    def _calculate_proportion(self, y):
        """计算指标比重"""
        epsilon = 1e-10
        p = y + epsilon
        col_sums = p.sum(axis=0)
        return p / col_sums
    
    def _calculate_entropy(self, p):
        """计算信息熵"""
        m = p.shape[0]
        k = 1 / np.log(m)
        return -k * np.sum(p * np.log(p), axis=0)
    
    def _calculate_redundancy(self, e):
        """计算信息冗余度"""
        return 1 - e
    
    def _calculate_weight(self, d):
        """计算权重"""
        return d / np.sum(d)
    
    def predict(self, data):
        """计算综合得分"""
        standardized = self._standardize(data)
        return np.dot(standardized, self.weights)

# 实例化并计算
entropy_method = EntropyMethod(benefit_type)
entropy_method.fit(numeric_data)

# 输出详细结果
print("=== 熵值法计算结果 ===\n")

print("1. 标准化后的数据:")
std_df = pd.DataFrame(
    entropy_method.standardized_data,
    columns=df.columns[1:],
    index=df['城市']
)
print(std_df.round(4))
print("\n" + "-"*60 + "\n")

print("2. 各指标信息熵:")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {entropy_method.entropy[i]:.6f}")
print("\n" + "-"*60 + "\n")

print("3. 各指标信息冗余度:")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {entropy_method.redundancy[i]:.6f}")
print("\n" + "-"*60 + "\n")

print("4. 各指标权重:")
weights_df = pd.DataFrame({
    '指标': df.columns[1:],
    '权重': entropy_method.weights,
    '权重(%)': entropy_method.weights * 100
})
print(weights_df.round(4))
print("\n" + "-"*60 + "\n")

# 计算综合得分
scores = entropy_method.predict(numeric_data)
print("5. 各城市综合得分及排名:")
results_df = pd.DataFrame({
    '城市': df['城市'],
    '综合得分': scores
})
results_df['排名'] = results_df['综合得分'].rank(ascending=False, method='min')
results_df = results_df.sort_values('综合得分', ascending=False)
print(results_df.round(4))
print("\n" + "="*60 + "\n")

# 可视化分析
plt.figure(figsize=(14, 6))

# 子图1:权重分布
plt.subplot(1, 2, 1)
bars = plt.barh(range(len(entropy_method.weights)), entropy_method.weights)
plt.yticks(range(len(entropy_method.weights)), df.columns[1:], fontsize=10)
plt.xlabel('权重', fontsize=12)
plt.title('各指标权重分布', fontsize=14, fontweight='bold')
for i, bar in enumerate(bars):
    width = bar.get_width()
    plt.text(width + 0.001, bar.get_y() + bar.get_height()/2, 
             f'{width:.4f}', ha='left', va='center', fontsize=10)

# 子图2:城市综合得分
plt.subplot(1, 2, 2)
colors = plt.cm.viridis(np.linspace(0, 1, len(results_df)))
bars = plt.bar(results_df['城市'], results_df['综合得分'], color=colors)
plt.ylabel('综合得分', fontsize=12)
plt.title('城市综合实力排名', fontsize=14, fontweight='bold')
plt.xticks(rotation=45)
for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width()/2., height + 0.01,
             f'{height:.3f}', ha='center', va='bottom', fontsize=10)

plt.tight_layout()
plt.show()

# 敏感性分析:观察权重稳定性
print("\n=== 敏感性分析 ===\n")
print("通过调整数据观察权重变化:")
# 创建一个扰动数据集
np.random.seed(123)
perturbation = np.random.normal(1.0, 0.05, numeric_data.shape)  # 5%的随机扰动
perturbed_data = numeric_data * perturbation

entropy_perturbed = EntropyMethod(benefit_type)
entropy_perturbed.fit(perturbed_data)

print("\n原始权重 vs 扰动后权重:")
comparison_df = pd.DataFrame({
    '指标': df.columns[1:],
    '原始权重': entropy_method.weights,
    '扰动后权重': entropy_perturbed.weights,
    '变化率(%)': (entropy_perturbed.weights - entropy_method.weights) / entropy_method.weights * 100
})
print(comparison_df.round(4))

熵值法的优缺点分析

优点

  1. 客观性强:完全基于数据本身的离散程度确定权重,避免了主观判断的偏差
  2. 数学严谨:有坚实的理论基础,计算过程标准化
  3. 适用范围广:适用于各种类型的多指标综合评价问题
  4. 可解释性好:权重大小直接反映指标信息量的多少

缺点

  1. 对极端值敏感:个别极端值会显著影响权重计算
  2. 要求样本量适中:样本量过少时,计算结果可能不稳定
  3. 无法反映指标重要性差异:完全依赖数据,可能忽略实际业务中指标的重要性差异
  4. 可能产生权重分配不均:当某些指标数据离散度特别大时,可能产生权重过度集中

实际应用中的注意事项

1. 数据预处理

  • 异常值处理:在计算前应识别和处理异常值
  • 缺失值填补:合理处理缺失数据,避免影响计算结果
  • 数据一致性:确保所有指标方向一致(效益型或成本型)

2. 样本量要求

  • 一般建议样本量m ≥ 5,否则计算结果可能不稳定
  • 指标数量n不宜过多,避免权重过于分散

3. 结果解释

  • 权重仅反映数据离散程度,不一定代表实际重要性
  • 建议结合主观赋权法(如AHP)进行组合赋权

4. 模型验证

  • 通过敏感性分析检验结果的稳定性
  • 与其他赋权方法结果进行对比验证

扩展应用:与其他方法的结合

1. 熵值法与AHP结合(组合赋权)

def combined_weight(entropy_weight, ahp_weight, alpha=0.5):
    """
    组合赋权:alpha表示熵值法权重占比
    """
    return alpha * entropy_weight + (1 - alpha) * ahp_weight

# 示例:假设AHP权重为[0.2, 0.2, 0.2, 0.2, 0.1, 0.1]
ahp_weights = np.array([0.2, 0.2, 0.2, 0.2, 0.1, 0.1])
combined = combined_weight(entropy_method.weights, ahp_weights, alpha=0.6)
print("\n组合权重(熵值法60% + AHP40%):")
for i, col in enumerate(df.columns[1:]):
    print(f"   {col}: {combined[i]:.4f} ({combined[i]*100:.2f}%)")

2. 熵值法与TOPSIS结合

def topsis_with_entropy(data, benefit_type, entropy_method):
    """
    熵值法赋权 + TOPSIS评价
    """
    # 1. 标准化
    std_data = entropy_method._standardize(data)
    
    # 2. 加权标准化矩阵
    weights = entropy_method.weights
    weighted_std = std_data * weights
    
    # 3. 确定正理想解和负理想解
    # 效益型指标:越大越好;成本型指标:越小越好
    ideal_positive = np.array([std_data[:, j].max() if benefit_type[j] else std_data[:, j].min() 
                              for j in range(len(benefit_type))])
    ideal_negative = np.array([std_data[:, j].min() if benefit_type[j] else std_data[:, j].max() 
                              for j in range(len(benefit_type))])
    
    # 4. 计算距离
    d_positive = np.sqrt(np.sum((weighted_std - ideal_positive * weights)**2, axis=1))
    d_negative = np.sqrt(np.sum((weighted_std - ideal_negative * weights)**2, axis=1))
    
    # 5. 计算贴近度
    closeness = d_negative / (d_positive + d_negative)
    
    return closeness

# 应用示例
topsis_scores = topsis_with_entropy(numeric_data, benefit_type, entropy_method)
print("\n熵值法+TOPSIS综合得分:")
for i, city in enumerate(df['城市']):
    print(f"   {city}: {topsis_scores[i]:.4f}")

结论

熵值法作为一种客观赋权方法,在多指标综合评价中具有重要价值。通过分析数据本身的离散程度来确定权重,避免了主观偏差,使评价结果更加科学合理。然而,在实际应用中,我们需要注意其局限性,结合具体问题特点,必要时与其他方法组合使用,以获得更可靠的评价结果。

关键要点总结:

  1. 客观性:权重完全由数据决定,避免主观干扰
  2. 适用性:适用于样本量充足、指标间相关性不强的情况
  3. 局限性:对极端值敏感,可能忽略指标实际重要性差异
  4. 改进方向:可与主观赋权法、其他评价方法结合使用

通过本文的详细解析和完整代码示例,读者可以掌握熵值法的核心原理、计算步骤和实际应用技巧,为相关研究和实践提供有力工具。