变形力图和决策图为XGBClassifier模型提供了错误的输出

时间:2019-10-01 12:45:50

标签: python matplotlib plot xgboost shap

我正在尝试为一小部分预测提供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()

如前所述,在计分时,(我所关注的)每个观察值的得分均应大于.5,但这并不是我在整形图中看到的。这是一个示例:

Example Decision Plot

此图显示的输出约为.1,但是使用predict_proba对观察结果进行评分时,我得到的值为.608

由于数据的敏感性,我不能真正提供一个代表,我不确定潜在的问题是什么。

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



相关点冻结项目:

Python 3.7.3

matplotlib == 3.0.3

shap == 0.30.1

xgboost == 0.90

1 个答案:

答案 0 :(得分:1)

我建议您直接在模型输出和SHAP输出之间进行比较。 SHAP Decision Plots文档中Section "Changing the SHAP base value"中的第二个代码示例显示了如何对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))