numpy 计算所有类别的绝对SHAP值的平均值

ycl3bljg  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(89)

假设我有下面的模型,从这些合成数据中构建。

import numpy as np
import shap
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(n_samples=1000, 
                           n_features=50, 
                           n_informative=9, 
                           n_redundant=0, 
                           n_repeated=0, 
                           n_classes=10, 
                           n_clusters_per_class=1,
                           class_sep=9,
                           flip_y=0.2,
                           random_state=17)

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

model = RandomForestClassifier()
model.fit(X_train, y_train)

字符串
我计算特征形状值:

explainer = shap.Explainer(model)
shap_values = explainer.shap_values(X_test)

type(shap_values)
list


为了分别计算每个类的SHAP值,我这样做:

abs_sv = np.abs(shap_values)
avg_feature_importance_per_class = np.mean(abs_sv, axis=1)

avg_feature_importance_per_class.shape
(10, 50)

问题

现在,我如何计算所有类的绝对SHAP值的平均值,我可以将其视为模型的特征重要性(从SHAP值导出)。
我喜欢这个:

feature_importance_overall = np.mean(abs_sv, axis=0)


但是我把自己弄糊涂了。我真的做得对吗?特别是如果我看形状:

feature_importance_overall.shape
(250, 50)


我期待的东西的形状(number_of_features_,)。类似于我得到的:

model.feature_importances_.shape
(50,)


avg_feature_importance_per_class.shape也显示了这一点,但对于number_of_classes(即(10, 50)),因为这是单独为各个类计算的。

htzpubme

htzpubme1#

为了理解如何执行您提到的计算,让我们看一下shap_values的形状

print(np.array(shap_values).shape)
# (10, 250, 50)

字符串
这个numpy数组包含三个维度,它们表示:

  • 10:类的数量
  • 250:测试数据中的记录数
  • 50:特征数量

因此,要获得计算“所有类的平均绝对形状值”的所需结果,需要在10个类(索引0处的第一个维度)以及所有250个记录(索引1处的第二个维度)中平均此数组,您可以通过以下操作完成:

feature_importance_overall = np.mean(abs_sv, axis=(0, 1))
feature_importance_overall.shape
# (50,)

相关问题