熵权法 Python 实战:3步完成鸢尾花数据集指标权重计算(附完整代码)

发布时间:2026/7/5 12:03:19
熵权法 Python 实战:3步完成鸢尾花数据集指标权重计算(附完整代码) 熵权法 Python 实战3步完成鸢尾花数据集指标权重计算附完整代码在数据分析与决策过程中如何科学地确定各指标的权重一直是个难题。传统的主观赋权方法如层次分析法AHP依赖专家经验容易引入人为偏差。而熵权法作为一种客观赋权方法能够直接从数据分布中提取信息自动计算各指标的重要性。本文将带你用Python实现熵权法并以经典的鸢尾花数据集为例展示如何通过3个步骤快速计算出各特征的权重。1. 理解熵权法的核心思想熵权法源于信息论中的熵概念。在信息论中熵用来衡量系统的不确定性熵值越大系统越无序信息量越小反之熵值越小系统越有序信息量越大。将这个原理应用到指标权重计算中高熵指标数据分布均匀差异小提供的信息量少应赋予较小权重低熵指标数据分布不均匀差异大提供的信息量多应赋予较大权重举个例子假设我们评估城市宜居性时考虑空气质量和绿化率两个指标。如果所有城市的空气质量都很接近高熵而绿化率差异明显低熵那么绿化率对最终评价的影响应该更大。2. 熵权法的数学实现步骤熵权法的计算可以分为以下三个核心步骤2.1 数据标准化处理由于不同指标的量纲和数量级不同首先需要将原始数据标准化到[0,1]区间。对于正向指标越大越好和负向指标越小越好处理方法略有不同import numpy as np from sklearn.preprocessing import MinMaxScaler # 正向指标标准化 def normalize_positive(x): scaler MinMaxScaler() return scaler.fit_transform(x) # 负向指标标准化 def normalize_negative(x): scaler MinMaxScaler() return 1 - scaler.fit_transform(x)2.2 计算信息熵标准化后的数据需要计算每个指标的信息熵。这里使用香农熵公式def calculate_entropy(x): # 避免log(0)的情况 x np.where(x 0, 1e-10, x) # 计算比例 p x / np.sum(x, axis0) # 计算熵值 k 1 / np.log(len(x)) entropy -k * np.sum(p * np.log(p), axis0) return entropy2.3 计算指标权重根据熵值计算差异系数最终确定各指标权重def calculate_weights(entropy): # 差异系数 d 1 - entropy # 权重 weights d / np.sum(d) return weights3. 鸢尾花数据集实战现在我们以sklearn自带的鸢尾花数据集为例完整演示熵权法的应用。3.1 数据准备与预处理首先加载数据并进行初步观察from sklearn.datasets import load_iris import pandas as pd # 加载数据 iris load_iris() df pd.DataFrame(iris.data, columnsiris.feature_names) # 查看数据概况 print(df.describe())鸢尾花数据集包含四个特征花萼长度sepal length花萼宽度sepal width花瓣长度petal length花瓣宽度petal width3.2 完整熵权法实现将前面的步骤整合成一个完整的函数def entropy_weight_method(data, positive_indicesNone, negative_indicesNone): 熵权法计算指标权重 参数: data: 原始数据矩阵 (n_samples, n_features) positive_indices: 正向指标列索引列表 negative_indices: 负向指标列索引列表 返回: weights: 各指标权重 # 数据标准化 normalized_data np.zeros_like(data) if positive_indices is not None: normalized_data[:, positive_indices] normalize_positive(data[:, positive_indices]) if negative_indices is not None: normalized_data[:, negative_indices] normalize_negative(data[:, negative_indices]) # 计算熵值 entropy calculate_entropy(normalized_data) # 计算权重 weights calculate_weights(entropy) return weights3.3 应用与结果分析对鸢尾花数据集应用熵权法# 假设所有特征都是正向指标 weights entropy_weight_method(df.values, positive_indices[0,1,2,3]) # 结果展示 result pd.DataFrame({ Feature: iris.feature_names, Weight: weights }) print(result)典型输出结果可能如下FeatureWeightsepal length (cm)0.152sepal width (cm)0.058petal length (cm)0.395petal width (cm)0.395解读结果显示花瓣长度和花瓣宽度的权重最高各约39.5%而花萼宽度的权重最低约5.8%。这与鸢尾花分类问题的实际情况相符因为花瓣特征通常更能区分不同种类的鸢尾花。4. 进阶应用与注意事项4.1 结果可视化为了更好地理解权重分布我们可以用matplotlib绘制权重条形图import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.bar(result[Feature], result[Weight], colorskyblue) plt.title(Feature Weights Calculated by Entropy Method) plt.ylabel(Weight) plt.xticks(rotation45) plt.show()4.2 实际应用中的注意事项指标方向性判断必须明确每个指标是正向还是负向。例如在医疗指标中治愈率是正向指标而死亡率是负向指标。数据预处理处理缺失值建议删除或合理填充处理异常值可采用3σ原则或IQR方法识别和处理样本量要求熵权法对样本量有一定要求样本太少可能导致权重不稳定。与其他方法结合可考虑与AHP等主观赋权法结合兼顾客观数据和专家经验。4.3 扩展应用综合评价得分计算出权重后可以进一步计算每个样本的综合得分def calculate_scores(data, weights): # 标准化数据假设都是正向指标 normalized_data normalize_positive(data) # 计算加权得分 scores np.dot(normalized_data, weights) return scores # 计算鸢尾花数据集的综合得分 df[Score] calculate_scores(df.values[:, :4], weights) print(df.sort_values(Score, ascendingFalse).head())5. 完整代码整合以下是整合后的完整代码可直接运行# 熵权法完整实现鸢尾花数据集案例 import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler from sklearn.datasets import load_iris import matplotlib.pyplot as plt # 1. 数据标准化函数 def normalize_positive(x): scaler MinMaxScaler() return scaler.fit_transform(x) def normalize_negative(x): scaler MinMaxScaler() return 1 - scaler.fit_transform(x) # 2. 熵值计算函数 def calculate_entropy(x): x np.where(x 0, 1e-10, x) p x / np.sum(x, axis0) k 1 / np.log(len(x)) entropy -k * np.sum(p * np.log(p), axis0) return entropy # 3. 权重计算函数 def calculate_weights(entropy): d 1 - entropy weights d / np.sum(d) return weights # 4. 熵权法主函数 def entropy_weight_method(data, positive_indicesNone, negative_indicesNone): normalized_data np.zeros_like(data, dtypefloat) if positive_indices is not None: normalized_data[:, positive_indices] normalize_positive(data[:, positive_indices]) if negative_indices is not None: normalized_data[:, negative_indices] normalize_negative(data[:, negative_indices]) entropy calculate_entropy(normalized_data) weights calculate_weights(entropy) return weights # 5. 综合评价得分计算 def calculate_scores(data, weights): normalized_data normalize_positive(data) scores np.dot(normalized_data, weights) return scores # 主程序 if __name__ __main__: # 加载数据 iris load_iris() df pd.DataFrame(iris.data, columnsiris.feature_names) # 计算权重 weights entropy_weight_method(df.values, positive_indices[0,1,2,3]) # 展示权重结果 result pd.DataFrame({ Feature: iris.feature_names, Weight: weights }) print(Feature Weights:) print(result) # 可视化权重 plt.figure(figsize(10, 5)) plt.bar(result[Feature], result[Weight], colorskyblue) plt.title(Feature Weights Calculated by Entropy Method) plt.ylabel(Weight) plt.xticks(rotation45) plt.tight_layout() plt.show() # 计算并展示综合得分 df[Score] calculate_scores(df.values[:, :4], weights) print(\nTop 5 samples by comprehensive score:) print(df.sort_values(Score, ascendingFalse).head())运行这段代码你将得到四个特征的权重分配权重分布的可视化图表样本综合得分排名在实际项目中你可以将此代码作为模板只需替换数据输入部分即可应用到自己的数据集上。对于更复杂的场景可能需要调整标准化方法或增加其他预处理步骤。