CRITIC权重法实战指南用Python实现数据评价与可视化全流程当你面对一份包含多个评价指标的数据集时如何科学地确定各指标的重要性CRITIC权重法提供了一种基于数据内在特性的客观赋权方案。不同于主观打分法容易受人为因素影响CRITIC方法通过分析指标间的对比强度和冲突性来自动计算权重特别适合处理具有相关性的多指标评价问题。1. 环境准备与数据理解在开始之前确保你的Python环境已安装以下库pip install numpy pandas matplotlib seaborn假设我们有一份城市发展评估数据集包含5个城市的6项指标城市GDP(亿元)人均收入(万元)空气质量指数失业率(%)医疗资源指数教育投入占比A市12006.8853.2784.1B市9805.9924.1653.8C市15007.5782.8824.5D市8505.2885.0603.5E市11006.5823.5754.0注意需要预先明确每个指标的类型GDP、人均收入、医疗资源指数和教育投入占比是正向指标越大越好空气质量指数和失业率是负向指标越小越好。2. 数据预处理与标准化不同类型指标需要先进行标准化处理消除量纲影响。我们使用极值标准化方法import numpy as np import pandas as pd def data_normalization(data, indicators_type): 数据标准化处理 :param data: 原始数据矩阵 :param indicators_type: 指标类型列表1为正向指标2为负向指标 :return: 标准化后的矩阵 normalized_data np.zeros_like(data, dtypefloat) for i in range(data.shape[1]): col data[:, i] max_val, min_val np.max(col), np.min(col) if indicators_type[i] 1: # 正向指标 normalized_data[:, i] (col - min_val) / (max_val - min_val) else: # 负向指标 normalized_data[:, i] (max_val - col) / (max_val - min_val) return normalized_data # 示例数据 raw_data np.array([ [1200, 6.8, 85, 3.2, 78, 4.1], [980, 5.9, 92, 4.1, 65, 3.8], [1500, 7.5, 78, 2.8, 82, 4.5], [850, 5.2, 88, 5.0, 60, 3.5], [1100, 6.5, 82, 3.5, 75, 4.0] ]) indicators_type [1, 1, 2, 2, 1, 1] # 指标类型 normalized_data data_normalization(raw_data, indicators_type) print(标准化后的矩阵:\n, normalized_data)标准化后的数据所有值都在[0,1]区间内且都转化为正向指标便于后续比较。3. CRITIC权重计算核心步骤CRITIC权重的计算主要基于两个关键概念对比强度通过标准差衡量指标内数据的波动程度冲突性通过相关系数衡量指标间的相关性3.1 计算对比强度对比强度反映指标内各评价对象取值的差异程度def calculate_contrast_intensity(normalized_data): 计算对比强度标准差 return np.std(normalized_data, axis0, ddof1) contrast calculate_contrast_intensity(normalized_data) print(各指标对比强度:\n, contrast)3.2 计算冲突性矩阵冲突性反映指标间的相关性使用Pearson相关系数def calculate_conflict(normalized_data): 计算冲突性 corr_matrix np.corrcoef(normalized_data, rowvarFalse) return np.sum(1 - corr_matrix, axis0) conflict calculate_conflict(normalized_data) print(各指标冲突性:\n, conflict)3.3 计算信息承载量与权重信息承载量是对比强度与冲突性的乘积权重则是归一化的信息承载量def calculate_critic_weights(contrast, conflict): 计算CRITIC权重 information_capacity contrast * conflict weights information_capacity / np.sum(information_capacity) return weights weights calculate_critic_weights(contrast, conflict) print(各指标权重:\n, weights)4. 结果可视化分析4.1 权重分布条形图import matplotlib.pyplot as plt import seaborn as sns # 设置中文显示 plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False # 指标名称 indicators [GDP, 人均收入, 空气质量, 失业率, 医疗资源, 教育投入] # 绘制权重条形图 plt.figure(figsize(10, 6)) sns.barplot(xindicators, yweights, paletteviridis) plt.title(各指标CRITIC权重分布) plt.ylabel(权重) plt.xticks(rotation45) for i, v in enumerate(weights): plt.text(i, v0.01, f{v:.3f}, hacenter) plt.tight_layout() plt.show()4.2 城市评价雷达图计算各城市综合得分并可视化def calculate_scores(normalized_data, weights): 计算综合得分 scores np.dot(normalized_data, weights) return 100 * scores / np.max(scores) # 转换为百分制 scores calculate_scores(normalized_data, weights) print(各城市综合得分:\n, scores) # 雷达图绘制 def plot_radar_chart(cities, scores): angles np.linspace(0, 2*np.pi, len(cities), endpointFalse).tolist() angles angles[:1] # 闭合图形 fig, ax plt.subplots(figsize(8, 8), subplot_kwdict(polarTrue)) ax.fill(angles, [*scores, scores[0]], alpha0.25) ax.plot(angles, [*scores, scores[0]], markero) ax.set_theta_offset(np.pi / 2) ax.set_theta_direction(-1) ax.set_thetagrids(np.degrees(angles[:-1]), cities) ax.set_rlabel_position(0) plt.yticks([20, 40, 60, 80, 100], [20, 40, 60, 80, 100], colorgrey, size7) plt.ylim(0, 110) plt.title(城市发展综合评价雷达图, pad20) plt.show() cities [A市, B市, C市, D市, E市] plot_radar_chart(cities, scores)5. 实际应用中的注意事项指标类型判断务必正确区分正向和负向指标错误的类型设定会导致权重计算完全错误数据质量检查处理缺失值删除或合理填充检查异常值使用箱线图或3σ原则识别结果解释高权重指标通常具有较大内部差异和较低相关性低权重指标可能是数据变化小或与其他指标高度相关方法比较与熵权法相比CRITIC考虑了指标间相关性与AHP相比CRITIC完全基于数据避免主观偏差# 完整流程封装示例 def critic_method(data, indicators_type, indicator_namesNone): CRITIC权重法完整流程封装 # 数据标准化 normalized_data data_normalization(data, indicators_type) # 计算对比强度 contrast calculate_contrast_intensity(normalized_data) # 计算冲突性 conflict calculate_conflict(normalized_data) # 计算权重 weights calculate_critic_weights(contrast, conflict) # 计算得分 scores calculate_scores(normalized_data, weights) return { normalized_data: normalized_data, contrast: contrast, conflict: conflict, weights: weights, scores: scores } # 使用示例 result critic_method(raw_data, indicators_type) print(最终权重:, result[weights])在实际项目中我发现CRITIC方法特别适合处理指标间存在一定相关性的评价问题。曾经在一个区域经济发展评估项目中使用这种方法成功识别出虽然GDP指标波动较大但由于与其他指标高度相关最终权重反而低于预期这一发现帮助我们更全面地理解了区域发展差异的主要驱动因素。