如何计算跨所有类别的绝对SHAP值均值以得到模型特征重要性
问题场景
使用合成数据构建RandomForestClassifier多分类模型,通过SHAP库得到各样本的SHAP值列表,已算出每个类别的平均特征重要性(形状(10,50))。需计算跨所有类别的绝对SHAP值均值作为模型整体特征重要性,但当前用np.mean(abs_sv, axis=0)得到的结果形状为(250,50),不符合预期的(50,)(与model.feature_importances_形状一致)。
问题原因
多分类任务中,explainer.shap_values(X_test)返回的是长度等于类别数的列表,每个元素对应一个类别的SHAP值数组,形状为(样本数, 特征数)。你的abs_sv是包含10个(250,50)数组的列表(X_test样本数为250)。
直接对abs_sv调用np.mean(axis=0)时,numpy会自动将列表堆叠为(10,250,50)的三维数组,沿类别维度(axis=0)取均值后得到(250,50),即每个样本、每个特征的跨类别平均绝对SHAP值,并非全局的特征重要性。
正确计算方式
有两种等价的实现方式,均可得到形状为(50,)的整体特征重要性:
方法1:堆叠后计算全局均值
先将所有类别的绝对SHAP值堆叠为三维数组,再沿类别维度和样本维度同时取均值:
abs_sv_stack = np.stack(abs_sv) # 形状变为(10, 250, 50) feature_importance_overall = np.mean(abs_sv_stack, axis=(0, 1)) # 沿类别、样本维度取均值,结果形状(50,)
方法2:基于类别平均结果再聚合
利用已计算好的每个类别的平均特征重要性(avg_feature_importance_per_class,形状(10,50)),直接沿类别维度取均值:
feature_importance_overall = np.mean(avg_feature_importance_per_class, axis=0) # 结果形状(50,)
验证
两种方法得到的结果完全一致,且与model.feature_importances_的形状匹配,可直接用于全局特征重要性分析。
内容的提问来源于stack exchange,提问作者Amina Umar

