首页 > 解决方案 > 形状力图和决策图为 XGBClassifier 模型提供了错误的输出

问题描述

我正在尝试为一小部分预测提供 shap 决策图,但 shap 找到的输出与我在仅使用模型进行预测时得到的结果不同,即使在调用中使用 link = 'logit' 也是如此。由于我试图绘制的子集,我试图生成的每个决策图的结果都应该大于预期值。但是,生成的每个图的预测值都低于预期值。

我有两个模型处于最小集合中,因此我使用 for 循环来确定要为其生成绘图的模型。我为 RandomForestClassifier 模型创建正确的图没有问题,但 XGB 模型出现了问题。

rf_explainer = shap.TreeExplainer(RF_model)
xgb_explainer = shap.TreeExplainer(XGB_model)

for i in range(flagged.shape[0]):
    if flagged_preds.RF_Score[i] == flagged_preds.Ensemble_Score[i]:
        idx = flagged.index[i]
        idxstr = idx[1].astype('str') + ' -- ' + idx[2].date().strftime('%Y-%m-%d') + ' -- ' + idx[0].astype('str')
        shap_value = rf_explainer.shap_values(flagged.iloc[i,:])
        shap.decision_plot(rf_explainer.expected_value[1], shap_value[1], show=False)
        plt.savefig(f'//PathToFolder/{idxstr} -- RF.jpg', format = 'jpg', bbox_inches = 'tight', facecolor = 'white')

    if flagged_preds.XGB_Score[i] == flagged_preds.Ensemble_Score[i]:
        idx = flagged.index[i]
        idxstr = idx[1].astype('str') + ' -- ' + idx[2].date().strftime('%Y-%m-%d') + ' -- ' + idx[0].astype('str')
        shap_value = xgb_explainer.shap_values(flagged.iloc[i,:])
        shap.decision_plot(xgb_explainer.expected_value, shap_value, link = 'logit',  show=False)
        plt.savefig(f'//PathToFolder/{idxstr} -- XGB.jpg', format = 'jpg', bbox_inches = 'tight', facecolor = 'white')
    plt.close()

如前所述,在评分时,(我关心的)每个观察值都应该 > 0.5,但这不是我在 shap plots 中看到的。这是一个例子:

示例决策图

该图显示了大约 0.1 的输出,但是当使用 predict_proba 对该观察进行评分时,我得到的值为 0.608

由于数据的敏感性,我无法真正提供代表,我不确定根本问题是什么。

非常欢迎任何反馈,谢谢。



相关点冻结项目:

蟒蛇 3.7.3

matplotlib==3.0.3

形状==0.30.1

xgboost==0.90

标签: pythonmatplotlibplotxgboostshap

解决方案


我建议在您的模型输出和您的 SHAP 输出之间进行直接比较。SHAP 决策图文档中“更改 SHAP 基值”部分中的第二个代码示例 显示了如何对 SHAP 值求和以匹配 LightGBM 模型的模型输出。您可以对任何其他模型使用相同的方法。如果求和的 SHAP 值与模型输出不匹配,则不是绘图问题。代码示例复制如下。两行应打印相同的值。

# The model's raw prediction for the first observation.
print(model.predict(features.iloc[[0]].values, raw_score=True)[0].round(4))

# The corresponding sum of the mean + shap values
print((expected_value + shap_values[0].sum()).round(4))

推荐阅读