如何在 shap 中绘制错误分类的样本?

How to plot misclassified samples in shap?

我有一个基因数据集,其致病可能性得分在 0 到 1 之间(已知得分为 1 的基因会导致疾病,而得分为 0.74 的基因可能会导致疾病)。我正在尝试建立一个机器学习模型来预测回归分类中新基因的疾病评分。

我想查看已知疾病基因但得分较低的基因的形状决策图(例如,得分为 1 但我的模型得分低于 0.8 的基因)。我正在努力将这些基因组合在一起进行绘图。

我的数据如下:

X:
Index   Feature1  Feature2   ... FeatureN
Gene1     1           0.2          10
Gene2     1           0.1          7
Gene3     0           0.3          10
#index is actually the index and not a column

Y:
Score
1
0.6
0.4

我 运行 一个带有嵌套交叉验证的 xgboost 回归器,查看 MSE,预测 r2,并绘制观察值与预期值。我可以在观察到的与预期的图中看到,在 Y 中得分为 1 的基因有许多模型预测的低分,我想了解为什么模型使用 shap 来做到这一点。不幸的是,我无法提供示例数据。

我正在尝试调整为标签分类给出的示例形状代码:

import shap

xgbr = xgboost.XGBRegressor()
xgbr.fit(X_train, Y_train)

select = range(8) #I have 8 features after feature selection with BorutaShap
features = X.iloc[select]
features_display = X.loc[features.index]

explainer = shap.TreeExplainer(xgbr)
expected_value = explainer.expected_value

#Example code from https://slundberg.github.io/shap/notebooks/plots/decision_plot.html: 

y_pred = xgbr.predict(X) 
y_pred = (shap_values.sum(1) + expected_value) > 0
misclassified = y_pred != y_test[select]
shap.decision_plot(expected_value, shap_values, features_display, link='logit', highlight=misclassified)

如何 select y_pred 使 predictions/genes 本应为 1 但实际上低于 0.8(或任何小数)?

编辑:回应我试过的给定答案:

explainer = shap.TreeExplainer(xgbr)
shap_values = explainer.shap_values(X_test)

y_pred = xgbr.predict(X_test)
m = (y_pred <= 0.5) & (Y_test == 1)

shap.initjs()
shap.decision_plot(explainer.expected_value, shap_values,  X_test[m],  return_objects=True)

这个 运行s 但 m 的长度为 171(我的 Y_test 数据中的全部行数)然后绘图绘制了所有 171 看起来像 - 和我通过查看数据知道应该只有一个基因 <= 0.5 但实际上得分为 1.

由于我没有你的数据集,我无法检查代码,但这里有一些想法可能会为你指明方向。

看来你没有训练你回归。它应该像

这样的行
xgbr = xgboost.XGBRegressor()
xgbr.train(X, Y)

现在您可以使用 xgbr.predict(X) ;)

你还需要训练解释器:

explainer = shap.TreeExplainer(xgbr)
with warnings.catch_warnings():
     warnings.simplefilter("ignore")
     sh = explainer.shap_values(X)

现在您可以 select 值:

misclassified = (y_pred <= 0.7) & (Y == 1)
shap.decision_plot(expected_value, sh, features_display, link='logit', highlight=misclassified)

在您使用 shap 之前,我建议您检查您的回归量与您的数据的拟合程度。因此,为此,我建议您将部分数据用于测试 而无需 在训练中使用它。然后,您可以通过计算和比较测试集和训练集上的 MSE 来评估拟合优度。差异越大,预测器的性能越差。

首先,你提到预测回归分类中新基因的疾病评分,什么意思?输出似乎是二元的,01,因此这是一个二元分类问题。您应该改用 xgboost 的分类器。 更新:不过,根据评论,让我们假设一个回归问题来模拟您的情况。尽管对于下面的示例,我们应该设置 'objective':'multi:softmax' 以输出实际标签。

根据您的问题,您似乎想做的是在那些未正确预测的样本上为测试集建立索引,并分析 误导性 特征,这是有道理的。

让我们用一些示例数据集重现您的问题:

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split
import shap
import xgboost

X,y = shap.datasets.iris()
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

model = xgboost.train(params={"learning_rate": 0.01}, 
                      dtrain=xgboost.DMatrix(X_train, label=y_train), 
                      num_boost_round =100)

使用整个测试集的 SHAP 图非常简单。对于 force_plot 例如:

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

shap.initjs()
shap.force_plot(explainer.expected_value, shap_values, X_test)

现在,如果我们想对错误分类的样本做同样的事情,我们需要查看输出概率。由于 iris 数据集有几个 类,假设我们想要可视化那些应该被分类为 2 的样本的 force_plot,但我们有一个输出值 1.7:

y_pred = model.predict(xgboost.DMatrix(X_test))
m = (y_pred <= 1.7) & (y_test == 2)

现在让我们使用掩码对 X_test 集执行布尔索引,并更新 shap_values:

shap.initjs()
c= explainer.shap_values(X_test[m])
shap.force_plot(explainer.expected_value, shap_values, X_test[m])

这告诉我们,主要是花瓣的长度和宽度将 回归 推向了更高的值。因此,它们可能是在错误分类中起主要作用的变量。

同样,对于 decision_plot

shap.decision_plot(explainer.expected_value, shap_values, 
                   X_test[m], feature_order='hclust', 
                   return_objects=True)