
代码绘制成果展示









代码解释


第一部分

# =========================================================================================# ====================================== 1. 环境设置 =======================================# =========================================================================================import matplotlib.pyplot as pltimport pandas as pdimport numpy as npimport shapimport xgboost as xgbfrom sklearn.model_selection import train_test_split, GridSearchCVfrom sklearn.preprocessing import StandardScalerfrom sklearn.metrics import mean_squared_error, mean_absolute_error, r2_scoreimport matplotlib.colors as mcolorsfrom matplotlib import cm

第二部分

# =========================================================================================# ======================================2.颜色库=======================================# =========================================================================================COLOR_SCHEMES= {1: 'Spectral_r',}SHAP_COLOR_INDEX =19 #蜂巢图的配色POLAR_COLOR_INDEX =19 #极坐标玫瑰图的配色

第三部分

# =========================================================================================# ======================================3.子图布局控制=======================================# =========================================================================================#蜂巢图的布局控制SHAP_X = 0.05 #蜂巢图左下角的 X 坐标SHAP_Y = 0.15 #蜂巢图左下角的 Y 坐标SHAP_W = 0.55 #蜂巢图的宽度SHAP_H = 0.75 #蜂巢图的高度#极坐标图的布局控制POLAR_X = 0.50 #极坐标图左下角的 X 坐标POLAR_Y = 0.1 #极坐标图左下角的 Y 坐标POLAR_SIZE = 0.75 #极坐标图的整体尺寸POLAR_BOTTOM_VAL = 15 #极坐标图内圈空心圆的半径POLAR_GAP = 2.0 #内圈实线与柱子之间的间隔大小

第四部分

# =========================================================================================# ======================================4.绘图函数=======================================# =========================================================================================def draw_shap_analysis_plot(shap_values, X_val, df_polar):fig = plt.figure(figsize=(20, 10)) # 创建画布#获取配色shap_cmap_name = COLOR_SCHEMES.get(SHAP_COLOR_INDEX, 'coolwarm') #蜂巢图cmap_shap = matplotlib.colormaps[shap_cmap_name]polar_cmap_name = COLOR_SCHEMES.get(POLAR_COLOR_INDEX, 'Spectral_r') #极坐标图cmap_polar = matplotlib.colormaps[polar_cmap_name]

第五部分

# =======================#左图# =======================# 定义左图的位置参数ax1_pos = [SHAP_X, #左SHAP_Y, #下SHAP_W, #宽SHAP_H] #高# 在画布上添加左图坐标轴ax1 = fig.add_axes(ax1_pos)plt.sca(ax1) #将当前绘图区域切换到 ax1#绘制蜂巢图shap.summary_plot(shap_values, #SHAP 值X_val, # 特征数据show=False, #不立即显示plot_type="dot", # 点图max_display=len(df_polar), # 最大显示的特征数量sort=False, # 关闭自动排序cmap=cmap_shap) #颜色映射方案ax1.set_title("SHAP Factor Summary Plot", fontsize=16) #设置标题# 子图编号ax1.text(0.5, # X 坐标-0.1, #Y 坐标"(a)", #文本transform=ax1.transAxes, #坐标系ha='center', #水平对齐fontsize=16) #字体大小

第六部分

# =======================# 极坐标图# =======================#位置参数ax2_pos = [POLAR_X,#左POLAR_Y,#下POLAR_SIZE,#宽POLAR_SIZE] #高# 绘制极坐标柱状图bars = ax2.bar(theta, #每个柱子的角度中心位置df_polar['Value'], # 每个柱子的长度width=width, # 柱子的宽度bottom=POLAR_BOTTOM_VAL + POLAR_GAP, # 柱子底部的起始半径color=colors, # 填充颜色edgecolor='black', # 边框的颜色linewidth=0.8) # 边框线条的宽度ax2.plot(circle_theta, #角度坐标circle_r, #半径color='black', #线条的颜色linewidth=1, #线条的宽度linestyle='-') #样式

第七部分

ax2.set_theta_zero_location("N") #极坐标的零度方向为正北ax2.set_theta_direction(-1) #极坐标的角度增长方向为顺时针ax2.set_axis_off() # 关闭默认的坐标轴# 遍历每个柱子,添加数值和标签for angle, value, feature, raw_val inzip(theta, df_polar['Value'], df_polar['Feature'], df_polar['Raw']):angle_deg = np.degrees(angle) # 将弧度转换为角度# 计算半径 (基础 + 间隔 + 柱子长度)visual_top = POLAR_BOTTOM_VAL + POLAR_GAP + value# 如果在右半圆if 0 <= angle_deg < 180:rotation = 90 - angle_deg #文本旋转角度alignment_ha = 'left' # 水平对齐alignment_va = 'center' # 垂直对齐ax2.text(angle, #角度坐标pos_outer, #半径坐标label_text, #文本内容ha=alignment_ha, #水平对齐va=alignment_va, #垂直对齐rotation=rotation, #文本旋转角度rotation_mode='anchor', #旋转模式fontsize=9, #字体大小fontweight='bold', #字体粗细color='black') #字体颜色

第八部分

# 在右图中插入一个子坐标轴用于颜色调cax = ax2.inset_axes([0.48, 0.35, 0.04, 0.3], transform=ax2.transAxes)sm = cm.ScalarMappable(cmap=cmap_polar, norm=norm) # 创建 ScalarMappable 对象ax2.text(0.5,-0.05,"(b)",transform=ax2.transAxes,ha='center',fontsize=16)#保存plt.savefig(fr'result_S{SHAP_COLOR_INDEX}_P{POLAR_COLOR_INDEX}.png' , dpi=300, bbox_inches='tight')plt.savefig(fr'result_S{SHAP_COLOR_INDEX}_P{POLAR_COLOR_INDEX}.pdf' , bbox_inches='tight')

第九部分

# =========================================================================================# ======================================4.执行部分=======================================# =========================================================================================if __name__ == '__main__':DATA_PATH = r'data.xlsx' # 原始数据df = pd.read_excel(DATA_PATH) #读取X = df.iloc[:, :-1] # 特征y = df.iloc[:, -1] #目标变量feature_names = X.columns.tolist() # 获取特征名称# 将数据集划分为训练集和验证集X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)#标准化处理scaler = StandardScaler()X_train_scaled = pd.DataFrame(scaler.fit_transform(X_train), columns=feature_names)X_val_scaled = pd.DataFrame(scaler.transform(X_val), columns=feature_names)

第十部分

# 定义超参数网格param_grid = {'n_estimators': [100, 200, 300]# 'learning_rate': [0.01, 0.05, 0.1],# 'max_depth': [3, 5, 7],# 'subsample': [0.8, 1.0]}#初始化 XGBoost 回归模型xgb_model = xgb.XGBRegressor(random_state=42, n_jobs=-1)# 初始化网格搜索对象grid_search = GridSearchCV(estimator=xgb_model, # 使用的模型param_grid=param_grid, # 参数网格cv=5, # 5折交叉验证scoring='neg_mean_squared_error', # 评分标准verbose=1, # 输出详细进度日志n_jobs=-1 # 使用所有CPU核心)# 在训练集上执行网格搜索grid_search.fit(X_train_scaled, y_train)# 获取最佳模型best_model = grid_search.best_estimator_print(f"最佳参数组合: {grid_search.best_params_}")# 保存最佳模型到本地base_name = os.path.splitext(DATA_PATH)[0]model_save_path = f"{base_name}_best_model.pkl"joblib.dump(best_model, model_save_path)

第十一部分

# 对训练集进行预测y_train_pred = best_model.predict(X_train_scaled) # 预测训练集# 对验证集进行预测y_val_pred = best_model.predict(X_val_scaled) # 预测验证集#训练集指标r2_train = r2_score(y_train, y_train_pred) # R2rmse_train = np.sqrt(mean_squared_error(y_train, y_train_pred)) #RMSEmae_train = mean_absolute_error(y_train, y_train_pred) #MAE# 验证集指标r2_val = r2_score(y_val, y_val_pred) #R2rmse_val = np.sqrt(mean_squared_error(y_val, y_val_pred)) # RMSEmae_val = mean_absolute_error(y_val, y_val_pred) # MAE# 打印评估指标print(f"训练集 R2: {r2_train:.4f}, RMSE: {rmse_train:.4f}, MAE: {mae_train:.4f}")print(f"验证集 R2: {r2_val:.4f}, RMSE: {rmse_val:.4f}, MAE: {mae_val:.4f}")print("----------------------\n")

第十二部分

#SHAP 分析print("正在进行 SHAP 分析...")explainer = shap.TreeExplainer(best_model) # 使用最佳模型创建 TreeExplainer 解释器shap_values_obj = explainer(X_val_scaled) # 计算验证集的 SHAP 值对象shap_values = shap_values_obj.values # 提取具体的 SHAP 数值矩阵# 创建DataFramedf_polar = pd.DataFrame({'Feature': feature_names, # 特征名称列'Value': shap_percentages, # 百分比数值列'Raw': mean_abs_shap # 平均绝对 SHAP 值})#调用函数绘图draw_shap_analysis_plot(shap_values,X_val_scaled,df_polar)

如何应用到你自己的数据

1.设置颜色方案:
SHAP_COLOR_INDEX =9 #蜂巢图的配色POLAR_COLOR_INDEX =29 #极坐标玫瑰图的配色
2.设置布局参数,调整两个子图的位置和大小:
#蜂巢图的布局控制SHAP_X = 0.05#蜂巢图左下角的 X 坐标SHAP_Y = 0.15#蜂巢图左下角的 Y 坐标SHAP_W = 0.55#蜂巢图的宽度SHAP_H = 0.75#蜂巢图的高度#极坐标图的布局控制POLAR_X = 0.50#极坐标图左下角的 X 坐标POLAR_Y = 0.1#极坐标图左下角的 Y 坐标POLAR_SIZE = 0.75#极坐标图的整体尺寸POLAR_BOTTOM_VAL = 15#极坐标图内圈空心圆的半径POLAR_GAP = 2.0#内圈实线与柱子之间的间隔大小
3.设置绘图结果的保存路径以及文件名:
plt.savefig(fr'result_S{SHAP_COLOR_INDEX}_P{POLAR_COLOR_INDEX}.png' , dpi=300, bbox_inches='tight')plt.savefig(fr'result_S{SHAP_COLOR_INDEX}_P{POLAR_COLOR_INDEX}.pdf' , bbox_inches='tight')
4.设置原始数据的保存路径:
DATA_PATH = r'simulated_data.xlsx' # 原始数据5.设置特征以及目标:
X = df.iloc[:, :-1] # 特征y = df.iloc[:, -1] #目标变量
6.设置超参数:
# 定义超参数网格param_grid = { 'n_estimators': [100, 200, 300] # 'learning_rate': [0.01, 0.05, 0.1], # 'max_depth': [3, 5, 7], # 'subsample': [0.8, 1.0]}

推荐


获取方式
