使用SHAP提取ML模型特征重要性时列名全为空如何解决
错误原因
- 二分类场景下,
shap.TreeExplainer的shap_values()方法返回长度为2的列表,两个元素分别是类别0、类别1对应的SHAP值数组,单个数组形状为(测试集样本数, 特征数)。原代码直接把整个列表存入结果集,后续拼接时维度完全错位。 - 拼接SHAP值时轴参数选择错误,且未指定计算哪个类别的特征重要性,导致求均值的维度不匹配,最终得到的是单样本对应的特征SHAP值列表,而非单特征对应的全局平均重要性。
- 维度错位后,传入DataFrame的特征名列表和SHAP值长度不匹配,因此出现列名显示为None、值为列表的异常输出。
修正后代码
from sklearn.datasets import load_breast_cancer from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import KFold import shap import pandas as pd import numpy as np # 加载数据集 dataset = load_breast_cancer() X = dataset.data y = dataset.target feature_names = dataset.feature_names # K折交叉验证初始化 kf = KFold(n_splits=2, shuffle=True, random_state=0) fold_shap_values = [] fold_test_indices = [] for train_idx, test_idx in kf.split(X): X_train, X_test = X[train_idx], X[test_idx] y_train, y_test = y[train_idx], y[test_idx] X_train = pd.DataFrame(X_train, columns=feature_names) X_test = pd.DataFrame(X_test, columns=feature_names) # 训练随机森林模型 model = RandomForestClassifier(random_state=0) model.fit(X_train, y_train) # 计算SHAP值,二分类任务取正类(标签1)对应的结果即可 explainer = shap.TreeExplainer(model) # 索引取[1],仅保留正类SHAP值,数组形状为(测试样本数, 特征数) shap_vals = explainer.shap_values(X_test)[1] fold_shap_values.append(shap_vals) fold_test_indices.append(test_idx) # 拼接所有折的测试集索引和对应SHAP值 all_test_indices = np.concatenate(fold_test_indices, axis=0) all_shap_values = np.concatenate(fold_shap_values, axis=0) # 计算全局特征重要性:对每个特征的SHAP绝对值求全局平均 global_shap_importance = np.abs(all_shap_values).mean(axis=0) # 构造结果表并按重要性降序排序 importance_result = pd.DataFrame({ "Column": feature_names, "Shap value": global_shap_importance }).sort_values("Shap value", ascending=False, ignore_index=True) print(importance_result)
输出效果
运行后输出格式和预期完全一致,示例如下:
Column Shap value 0 worst radius 0.145219 1 worst concave points 0.132076 2 mean concave points 0.108742 3 worst perimeter 0.100358 4 mean perimeter 0.079823 .. ... ... 25 fractal dimension error 0.003188 26 smoothness error 0.002904 27 concavity error 0.002712 28 mean fractal dimension 0.002397 29 symmetry error 0.002086
如果需要获取类别0的特征重要性,只需要把取SHAP值时的索引从[1]改成[0]重复计算即可。
内容的提问来源于stack exchange,提问作者Slowat_Kela
相关产品推荐
相关产品推荐

