SHAP调用summary_plot绘制bar图失败且丢失特征名问题求助
核心问题原因
- 你使用的是5分类模型,SHAP返回的SHAP值为三维结构(样本数×特征数×类别数),0.40.0版本的
shap.summary_plot对该结构的条形图适配存在缺陷,无法自动识别聚合逻辑 - 你将
train_x转为numpy数组传入explainer,丢失了DataFrame自带的特征名元数据 - 报错是因为三维SHAP值的索引逻辑和传入的一维特征名列表不匹配,旧版本绘图函数的内部索引逻辑出错
可用解决方案
方案1(兼容0.40.0版本,无需升级)
第一步:生成SHAP值时保留特征名,不要转numpy数组
import numpy as np import shap # 训练完成的clf已存在 explainer = shap.Explainer(clf) # 直接传入DataFrame自动保留特征名,要跑全量数据直接去掉.iloc[:5,:]即可 shap_expl = explainer(train_x.iloc[:5,:]) # 提取三维SHAP数组:shape = (样本数, 特征数, 5个分类) shap_values = shap_expl.values feature_names = train_x.columns.tolist()
场景A:绘制所有类别平均的全局特征重要性条形图
# 聚合类别维度得到二维结构,适配绘图逻辑 shap.summary_plot( shap_values.mean(axis=2), train_x.iloc[:5,:], plot_type='bar', feature_names=feature_names )
场景B:绘制单个类别的特征重要性条形图
# class_idx取值0-4,对应你的5个分类,按需调整即可 class_idx = 0 shap.summary_plot( shap_values[:,:,class_idx], train_x.iloc[:5,:], plot_type='bar', feature_names=feature_names )
方案2(一劳永逸,无维度处理成本)
直接升级SHAP到0.42.0及以上版本,新版对多分类Explanation对象的绘图支持已经优化,直接运行以下代码即可得到正确结果:
explainer = shap.Explainer(clf) shap_values = explainer(train_x.iloc[:5,:]) shap.summary_plot(shap_values, plot_type='bar')
注意事项
- 跑全量训练集时,直接替换
train_x.iloc[:5,:]为train_x即可,如果数据量过大,可先用shap.sample(train_x, 1000)采样1000条样本减少计算耗时 - 特征名丢失的问题核心是不要将DataFrame转为numpy数组传入explainer,新版本SHAP会自动读取DataFrame的columns作为特征名
内容的提问来源于stack exchange,提问作者Dhruv Kapoor
相关产品推荐
相关产品推荐

