当前位置:首页>python>期刊图片复现|Python绘制XGB+SHAP分析特征重要性圆环图

期刊图片复现|Python绘制XGB+SHAP分析特征重要性圆环图

  • 2026-10-11 08:32:47
期刊图片复现|Python绘制XGB+SHAP分析特征重要性圆环图

代码绘制成果展示

论文:Barriers to combating corporate greenwashing: Evidence from systematic  literature review, NCA, econometric models and machine learning
这张环形图展示了机器学习模型预测时各特征因素的重要性及其具体影响方向 。图形的最外层散点图展示了各变量的SHAP值分布,其中每个数据点代表一个特定样本对该因素的SHAP值 ;数据点的颜色深浅反映了特征值的大小,红色代表该特征的取值较高,蓝色代表取值较低 。向内侧看的第二层和第三层分别列出了每个因素的平均重要性排名和平均相对重要性得分 。图形的最内层则使用不同的颜色块对各个变量所属分类。
论文原图
仿图
多种配色

代码解释

第一部分

库的导入以及字体设置
# =========================================================================================# ====================================== 1. 环境设置 =======================================# =========================================================================================import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport matplotlib.patches as patchesfrom matplotlib.colors import LinearSegmentedColormapfrom sklearn.model_selection import train_test_split, GridSearchCV

第二部分

颜色库
# =========================================================================================# ======================================2.颜色库=======================================# =========================================================================================color_schemes = {    1: {'cat': ['#075697', '#f48120', '#c0628d', '#19a5c8'], 'imp': ['#3b4cc0', '#8b58a7', '#c62b75', '#d41125'],        'shap': 'coolwarm'},}

第三部分

绘图函数:画布初始化与极坐标系设置,定义不同环的内径和外径
# =========================================================================================# ======================================3.绘图函数=======================================# =========================================================================================def plot_feature_importance_ring(features_data, categories_colors, ranks, norm_imps, num_features, shap_dict,fval_dict,imp_colors, shap_cmap, scheme_id):    # 创建画布    fig = plt.figure(figsize=(15, 15), facecolor='white')    # 在画布上添加子图轴    ax = fig.add_axes([0.1,  # 左                       0.1,  # 下                       0.8,  # 宽                       0.8],  # 高                      projection='polar')  # 极坐标    r_cat_in, r_cat_out = 3.0, 4.2  # 内侧第一环(类别环)的内径和外径    r_imp_in, r_imp_out = 4.4, 5.8  # 第二环(特征重要性环)的内径和外径    r_rank_in, r_rank_out = 6.0, 6.6  # 第三环(排名数字环)的内径和外径    r_shap_in, r_shap_out = 6.8, 9.5  # 最外侧区域(SHAP散点图所在区域)的内径和外径

第四部分

绘图函数:遍历所有特征的SHAP值,找出全局最大和最小值,并求出绝对值的最大跨度。为了后续SHAP散点的径向幅度,防止点超出预设的最外环。SHAP=0基准线绘制.
    r_shap_base = 8.0  # SHAP值为0时的基准线的半径位置    r_text = 9.7  # 最外圈特征名称文本的半径位置    c_import = LinearSegmentedColormap.from_list('imp', imp_colors)  # 根据重要性颜色列表,创建一个线性渐变颜色映射对象    # 生成用于绘制基准弧线的角度数组    theta_full = np.linspace(0, 1.5 * np.pi, 300)    # SHAP=0基准线    ax.plot(theta_full,  # 角度            [r_shap_base] * 300,  # 半径            color='#8cb369',  # 颜色            lw=1.2,  # 线条宽            zorder=1)  # 层

第五部分

绘图函数:循环绘制内侧三层圆环与文字,第一环类别,第二环重要性环,第三环排名环。
    # 遍历每一个特征及其对应的特征类别    for i, (name, cat) in enumerate(features_data):        angle = angles[i]  # 当前特征对应的中心极角位置        # 绘制特征类别环柱状图        ax.bar(angle,  # 角               r_cat_out - r_cat_in,  # 高度               bottom=r_cat_in,  # 底部起始半径               width=width,  # 宽度               color=categories_colors[cat],  # 颜色               edgecolor='black',  # 边框色               lw=0.5,  # 边框线宽               zorder=2)  # 层        deg = np.rad2deg(angle)  # 将极角从弧度格式转换为角度度数格式        rot_text = 90 - deg if deg <= 180 else 270 - deg  # 根据文字所处半圆位置动态设置旋转角度        halign = 'left' if deg <= 180 else 'right'  # 根据文字所处左右半部分,设置水平对齐方式        # 排名环中文本        ax.text(angle,  # 角                (r_rank_in + r_rank_out) / 2,  # 半径                str(ranks[i]),  # 文本                ha='center',  # 水平                va='center',  # 垂直                rotation=rot_text,  # 旋转角度                fontsize=12)  # 字体大小

第六部分

绘图函数:最外层SHAP散点与特征名称绘制
        # 绘制SHAP散点的空白环形边框        ax.bar(angle,  # 角度               r_shap_out - r_shap_in,  # 边框高度               bottom=r_shap_in,  # 起始底部位置               width=width,  # 宽               color='none',  # 填充色               edgecolor='black',  # 边框色               lw=0.5,  # 线宽               zorder=3)  # 层        # 各个特征的名字        ax.text(angle,  # 角度                r_text,  # 半径                name,  # 文本                ha=halign,  # 水平                va='center',  # 垂直                rotation=rot_text,  # 旋转角度                rotation_mode='anchor',  # 以文本锚点作为旋转的中心点                fontsize=14,  # 字体大小                color='black')  # 颜色

第七部分

绘图函数:去除背景线、添加图例与SHAP刻度标注
    ax.set_axis_off()  # 隐藏极坐标系自带的背景网格线、刻度和坐标轴边框    ax.set_ylim(0, 12)  # 设定极坐标系的径向界限    pos_min = r_shap_base + (min_shap / max_abs_shap) * 1.2  # 最小SHAP值对应的半径位置    pos_max = r_shap_base + (max_shap / max_abs_shap) * 1.2  # 最大SHAP值对应的半径位置    # 刻度文本标注    ax.text(-0.04,  # 角度            pos_min,  # 半径            f"{min_shap:.3f}",  # 文本            ha='right',  # 水平            va='center',  # 垂直            fontsize=14)  # 大小    ax.text(-0.04,  # 角度            r_shap_base,  # 半径            '0',  # 文本            ha='right',  # 水平            va='center',  # 垂直            fontsize=14)  # 大小    ax.text(-0.04,  # 角度            pos_max,  # 半径            f"{max_shap:.3f}",  # 文本            ha='right',  # 水平            va='center',  # 垂直            fontsize=14)  # 大小

第八部分

绘图函数:自定义颜色条绘制与绘图结果保存
    #第一个颜色条坐标轴    cax1 = fig.add_axes([0.18,  # 左                         0.52,  # 下                         0.02,  # 宽                         0.37])  # 高    cb1 = plt.colorbar(plt.cm.ScalarMappable(cmap=shap_cmap), cax=cax1)  # 生成颜色条  # 颜色条标题    # 第二个颜色条坐标轴    cax2 = fig.add_axes([0.25,  # 左                         0.52,  # 下                         0.02,  # 宽                         0.37])  # 高    cax2.set_xticks([])  # 去掉横坐标轴上的刻度    cax2.set_yticks([])  # 去掉纵坐标轴上的刻度    cax2.set_ylabel('Average ranking', fontsize=18)  # 标题    # 特征标题    fig.text(0.12,  # x             0.525,  # y             'Factors',  # 文本             rotation=90,  # 竖向             fontsize=18,  # 大小             color='red',             va='center')  # 垂直

第九部分

执行部分:数据读取与特征分类归属匹配
# =========================================================================================# ======================================4.执行部分=======================================# =========================================================================================if __name__ == '__main__':    file_path = r'data.xlsx'  # 原始数据路径    df = pd.read_excel(file_path)  # 读取数据    # 切出特征数据    cols = [col for col in df.columns if col != 'Target']    # 划分数据    X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3, random_state=42)    # 归一化    scaler = MinMaxScaler()    X_train = pd.DataFrame(scaler.fit_transform(X_train), columns=all_feature_names)    X_test = pd.DataFrame(scaler.transform(X_test), columns=all_feature_names)    X_test_scaled_df = X_test

第十部分

执行部分:模型训练与预测性能评估,定义树深和树棵数的范围,利用交叉验证网格搜索寻找最佳拟合参数。挑选出的最优XGBoost模型进行预测,计算常见的回归问题指标:R2、均方根误差(RMSE)、平均绝对误差(MAE)和均方误差(MSE),用以检验模型是否过拟合或欠拟合。
    # 参数网格    param_grid = {        'max_depth': range(2, 11, 1),        'n_estimators': range(10, 200, 20),    }    # 创建XGB模型    xgb_model = xgb.XGBRegressor(random_state=42, objective='reg:squarederror')    # 配置网格搜索    print("=" * 50)    print("模型评估结果:")    print(f"训练集R2:{r2_train:.3f} | RMSE: {rmse_train:.3f} | MAE: {mae_train:.3f} | MSE: {mse_train:.3f}")    print(f"测试集R2:{r2_test:.3f} | RMSE: {rmse_test:.3f} | MAE: {mae_test:.3f} | MSE: {mse_test:.3f}")    print("=" * 50)

第十一部分

执行部分:SHAP分析
    # =================================================================    explainer = shap.TreeExplainer(best_model)  # 创建SHAP树解释器    shap_values_raw = explainer.shap_values(X_test)  # 计算测试集SHAP值    importances = np.abs(shap_values_raw).mean(axis=0)  # SHAP值取绝对平均值    sorted_idx = np.argsort(importances)[::-1]  # 特征重要性排序    sorted_features = [all_feature_names[i] for i in sorted_idx]  # 排序特征    # 创建一个字典,将特征名称映射为其重要性排名    feature_ranks = {feat: rank + 1 for rank, feat in                     enumerate(sorted_features)}    for i, name in enumerate(all_feature_names):        shap_dict[name] = shap_values_raw[:, i]  # SHAP值        fval_dict[name] = X_test_scaled_df[name].values  # 特征值

第十二部分

执行部分:绘图执行,设置是批量绘制出所有配色图还是一个配色的图
     plot_all = True  # 是否批量出图            current_scheme = color_schemes[i]  # 提取配色方案            category_color_map = dict(zip(category_keys, current_scheme['cat']))  # 类别颜色            imp_colors = current_scheme['imp']  # 提取重要性渐变色            shap_cmap = current_scheme['shap']  # 提取散点图颜色            # 绘图            plot_feature_importance_ring(            )        target_scheme = 1  # 要使用的配色方案        current_scheme = color_schemes[target_scheme]  # 提取配色方案        category_color_map = dict(zip(category_keys, current_scheme['cat']))  # 类别颜色        imp_colors = current_scheme['imp']  # 提取重要性渐变色        shap_cmap = current_scheme['shap']  # 提取散点图颜色        # 调用绘图函数        plot_feature_importance_ring()

如何应用到你自己的数据

1.设置是一次绘制一张图还是一次性绘制出所有配色的图,执行部分:

plot_all = True  # 是否批量出图

2.设置原始数据文件的路径地址,执行部分:

file_path = r'data.xlsx'  # 原始数据路径

3.切除不同类别数据,执行部分:

internal_features = cols[0:15]external_features = cols[15:28]firm_features = cols[28:58]macro_features = cols[58:67]

4.定义类别,执行部分:

category_keys = ['Internal stakeholders', 'External stakeholders', 'Firm characteristics', 'Macro environment']

5.划分数据,执行部分:

X_train, X_test, y_train, y_test = train_test_split(X_data, y_data, test_size=0.3, random_state=42)

6.设置模型的超参数网格,执行部分:

param_grid = {    'max_depth': range(2, 11, 1),    'n_estimators': range(10, 200, 20),}

7.设置绘图结果的保存地址,绘图函数部分:

plt.savefig(fr'feature_importance_ring_{scheme_id}.png', dpi=300, bbox_inches='tight')

推荐

期刊图片复现|Python绘制二维偏依赖PDP图
期刊复现|python绘制基于SHAP分析和GAM模型拟合的单特征依赖图
期刊复现|用Python绘制SHAP特征重要性总览图、依赖图、双特征交互效应SHAP图,解锁XGBoost模型的终极奥秘
期刊图片复现|Python绘制shap重要性蜂巢图+单特征依赖图+交互效应强度气泡图+交互效应依赖图(回归+二分类+分类)

获取方式

公众号中的所有所有的免费代码都已经下架了,都并入到付费部分里了,付费合集代码和数据的购买通道已经开通,全部合集100元,后续将会持续更新,决定购买请后台私信我,注意只会分享练习数据和代码文件,不会提供答疑服务,代码文件中已经包含了每行代码的完整注释,购买前请确保真的需要!!!

最新文章

随机文章