catboost特征重要性 条形图
Catboost是一种基于梯度提升决策树的机器学习模型,在训练完模型后,我们可以通过分析特征重要性来了解模型对输入特征的重视程度。Catboost特征重要性条形图可以帮助我们直观地了解模型中各个特征的重要性排序,从而帮助我们更好地理解模型的决策过程。
条形图的横轴代表特征的重要性值,纵轴代表特征的名称。条形图呈现出特征的相对重要性,越长的条形表示特征越重要。通过观察条形图,我们可以看出哪些特征对模型的预测起到了关键作用,从而可以选择性地筛选重要特征,减少模型复杂度,提高模型训练和预测的效率。
除了直接观察条形图,我们还可以根据特征重要性的数值进行定量分析。 Catboost可以通过提供的特征重要性值来帮助我们理解每个特征对模型的影响程度。这些数值可以帮助我们找到对目标变量影响最大的特征,以及识别不太重要的特征,进而优化特征选择和特征工程的过程。
综上所述,Catboost特征重要性条形图是一种直观、有效的工具,可以帮助我们对模型进行解释和优化,从而更好地理解模型的预测过程,提高模型的性能和鲁棒性。
``` for file_path in file_list: try: base_name = os.path.basename(file_path) output_name = f"{os.path.splitext(base_name)[0]}模型评估结果.xlsx" output_path = os.path.join(output_folder, output_name) print(f"\n正在处理文件:{base_name}") df = pd.read_excel(file_path) df.columns = df.columns.str.strip() df['Qe'] = df['Removal'] * 0.01 * df['Initial'] / df['Biomass'] X = df[features] y = df[target_column] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) model = CatBoostRegressor(**catboost_params) model.fit(X_train, y_train) # 预测与评估... # 预测与评估(保持不变) y_pred = model.predict(X_test) y_train_pred = model.predict(X_train) # 指标计算(保持不变) metrics = { '训练集 MSE': mean_squared_error(y_train, y_train_pred), '测试集 MSE': mean_squared_error(y_test, y_pred), '训练集 RMSE': np.sqrt(mean_squared_error(y_train, y_train_pred)), '测试集 RMSE': np.sqrt(mean_squared_error(y_test, y_pred)), '训练集 R²': r2_score(y_train, y_train_pred), '测试集 R²': r2_score(y_test, y_pred) } # 保存结果(保持不变) results_df = pd.DataFrame({ '数据集': ['训练集', '测试集'], 'MSE': [metrics['训练集 MSE'], metrics['测试集 MSE']], 'RMSE': [metrics['训练集 RMSE'], metrics['测试集 RMSE']], 'R²': [metrics['训练集 R²'], metrics['测试集 R²']] }) results_df.to_excel(output_path, index=False) # 汇总数据收集(保持不变) summary_data = { '文件名': base_name, **{k: v for k, v in metrics.items()} } print(f"已保存结果至:{output_path}") # ========== SHAP分析 ========== explainer = shap.TreeExplainer(model) shap_values = explainer.shap_values(X_test) # 可视化 plt.figure(figsize=(10, 6)) shap.summary_plot(shap_values, X_test, plot_type="bar", show=False) plt.savefig(os.path.join(shap_folder, f"{base_name}_特征重要性.png"), dpi=300) plt.close() plt.figure(figsize=(10, 6)) shap.summary_plot(shap_values, X_test, show=False) plt.savefig(os.path.join(shap_folder, f"{base_name}_SHAP分布.png"), dpi=300) plt.close() # 保存SHAP值 shap_df = pd.DataFrame(shap_values, columns=features) shap_df['文件名'] = base_name all_shap = pd.concat([all_shap, shap_df], axis=0) # 汇总统计 mean_abs_shap = pd.Series(np.abs(shap_values).mean(axis=0), index=features) # ========== SHAP结束 ========== # 更新结果 summary_data = { '文件名': base_name, **{k: v for k, v in metrics.items()}, **{f"{feat}_SHAP": mean_abs_shap[feat] for feat in features} } all_results.append(summary_data) except Exception as e: print(f"处理错误:{str(e)}") continue # 保存全局SHAP结果 if not all_shap.empty: all_shap.to_excel(os.path.join(output_folder, "全局SHAP分析结果.xlsx"), index=False) shap_df = pd.read_excel(os.path.join(output_folder, "全局SHAP分析结果.xlsx"))```让上述代码输出全局shap分析结果的同时进行可视化
首先,代码的主循环遍历每个文件,处理数据、训练模型、计算指标,并进行SHAP分析。每个文件的SHAP值被保存到shap_df,然后通过pd.concat累积到all_shap中。循环结束后,如果all_shap不为空,就保存到“全局SHAP分析结果.xlsx”。用户的需求是在这一步同时进行可视化。
现有的SHAP可视化是针对单个文件的,在循环内生成并保存每个文件的特征重要性图和分布图。现在需要的是在全局SHAP数据保存后,生成基于所有文件汇总的SHAP可视化。
我需要考虑如何汇总所有文件的SHAP值。由于all_shap已经将所有文件的SHAP值合并,可以计算全局的平均SHAP值或直接使用所有数据生成可视化。不过,SHAP的summary_plot本身可以处理多个样本的数据,所以可能直接使用all_shap中的SHAP值即可。
接下来,在保存全局SHAP的Excel之后,添加可视化代码。需要确保shap_values和对应的特征数据正确。例如,可能需要从all_shap中提取SHAP值部分(排除可能的附加列如“文件名”)。此外,特征名称需要正确对应。
可能的步骤:
- 在保存全局SHAP到Excel后,读取该文件或直接使用已有的all_shap DataFrame。
- 分离SHAP值和特征名称,注意可能有“文件名”列需要排除。
- 使用shap.summary_plot生成全局的特征重要性条形图和SHAP值分布图。
- 保存这些图表到指定目录。
需要注意的是,如果all_shap包含“文件名”列,那么在提取SHAP值时需要排除这一列。例如,使用shap_values = all_shap.drop(columns=['文件名']).values,然后确保features变量包含正确的特征名称。
此外,要添加异常处理,确保在生成可视化时不会因为数据问题而报错,同时正确设置图片保存路径,可能需要使用全局的输出文件夹或特定的SHAP文件夹。
最后,在代码中相应位置插入这些步骤,并测试是否存在语法错误,比如变量作用域是否正确,特别是features变量是否在循环外可用,或者是否需要从all_shap的列中推断特征名称。
可能还需要考虑SHAP值的数量是否过大,导致可视化缓慢,但用户可能已经处理了数据量的问题,所以暂时假设可以直接处理。
总结修改点:
- 在保存全局SHAP的if块内,添加读取或处理all_shap生成SHAP值矩阵。
- 生成并保存全局的summary_plot条形图和分布图。
- 确保使用的特征名称正确,并且路径正确。以下是修改后的代码实现方案,主要增加全局SHAP可视化功能,修改部分用注释标出:
$$代码修改部分$$
保存全局SHAP结果
if not all_shap.empty: # 保存原始数据 all_shap.to_excel(os.path.join(output_folder, "全局SHAP分析结果.xlsx"), index=False)
# ===== 新增全局可视化 =====
try:
# 准备数据(排除文件名列)
shap_values_global = all_shap.drop(columns=['文件名']).values
X_global = pd.concat([X_train, X_test]) # 使用完整数据集
# 生成特征重要性图
plt.figure(figsize=(12, 8))
shap.summary_plot(shap_values_global, X_global, plot_type="bar", show=False)
plt.title("全局特征重要性排名", fontproperties='SimHei')
plt.savefig(os.path.join(shap_folder, "全局特征重要性.png"),
dpi=300, bbox_inches='tight')
plt.close()
# 生成SHAP分布图
plt.figure(figsize=(12, 8))
shap.summary_plot(shap_values_global, X_global, show=False)
plt.title("全局SHAP值分布", fontproperties='SimHei')
plt.savefig(os.path.join(shap_folder, "全局SHAP分布.png"),
dpi=300, bbox_inches='tight')
plt.close()
print(f"已生成全局SHAP可视化图表到 {shap_folder}")
except Exception as e:
print(f"全局可视化失败:{str(e)}")
# ===== 结束新增 =====
# 保留原始读取语句(如有需要)
shap_df = pd.read_excel(os.path.join(output_folder, "全局SHAP分析结果.xlsx"))
$$代码修改结束$$
实现效果说明:
- 数据准备阶段
- 通过
all_shap.drop(columns=['文件名'])
移除文件名列,保留纯SHAP值矩阵 - 使用
pd.concat([X_train, X_test])
合并全部数据集作为特征参考
- 可视化生成
- 输出两幅核心图表:
全局特征重要性.png
:条形图展示平均绝对SHAP值排序全局SHAP分布.png
:散点图展示特征值与SHAP值关系
- 图表尺寸调整为$12\times 8$英寸,标题使用中文字体
- 异常处理
- 使用try-except块捕获可能出现的可视化错误
- 输出明确的成功/失败状态信息
- 文件存储
- 图片保存为300dpi高清PNG格式
- 使用
bbox_inches='tight'
自动调整边界 - 存储路径与单个文件的SHAP分析结果一致
技术原理:
- SHAP值矩阵$S \in \mathbb{R}^{n\times m}$(n样本数,m特征数)反映每个样本的特征贡献
- 通过计算$|S|$的列均值得到全局特征重要性$\bar{s}j = \frac{1}{n}\sum{i=1}^n |s_{ij}|$
- 分布图中点的颜色映射遵循特征值大小,横坐标为$s_{ij}$,纵坐标表示特征排序
使用建议:
- 提前验证
shap_folder
路径存在性:os.makedirs(shap_folder, exist_ok=True)
- 若内存不足,可改用抽样可视化:
shap.plots.beeswarm(shap.Explanation(values=shap_values_global, data=X_global.values, feature_names=features))
相关推荐














