2

我用 SHAP 来解释我的 RF

RF_best_parameters = RandomForestRegressor(random_state=24, n_estimators=100)
RF_best_parameters.fit(X_train, y_train.values.ravel())
shap_explainer_model = shap.TreeExplainer(RF_best_parameters)

TreeExplainer 类有一个属性expected_value。我的第一个猜测是这个字段是预测 y 的平均值,根据 X_train (我也读过这里

但事实并非如此。
命令的输出:

shap_explainer_model.expected_value

是 0.2381。

命令的输出:

RF_best_parameters.predict(X_train).mean()

是 0.2389。

正如我们所看到的,这些值是不一样的。那么expected_value这里的意义是什么?

4

2 回答 2

4

这是由于与随机森林算法一起使用时该方法的特殊性;引用相关 Github 线程shap explainer expected_value 中的响应与模型期望值不同

这是因为 sklearn 如何在它构建的树模型中记录训练样本。随机森林使用数据的随机子样本来训练每棵树,而在 sklearn 中使用随机子样本来记录模型中的叶样本权重。由于 TreeExplainer 使用记录的叶样本权重来表示训练数据集,因此它将取决于训练期间使用的随机抽样。这将导致像您所看到的那样的小变化。

我们实际上可以验证其他算法不存在这种行为,比如梯度提升树:

from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor
import numpy as np

import shap
shap.__version__
# 0.37.0

X, y = make_regression(n_samples=1000, n_features=10, random_state=0)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

gbt = GradientBoostingRegressor(random_state=0)
gbt.fit(X_train, y_train)

mean_pred_gbt = np.mean(gbt.predict(X_train))
mean_pred_gbt
# -11.534353657511172

gbt_explainer = shap.TreeExplainer(gbt)
gbt_explainer.expected_value
# array([-11.53435366])

np.isclose(mean_pred_gbt, gbt_explainer.expected_value)
# array([ True])

但是对于 RF,我们确实得到了一个“小的变化”,正如主要 SHAP 开发人员在上面的线程中提到的:

rf = RandomForestRegressor(random_state=0)
rf.fit(X_train, y_train)

rf_explainer = shap.TreeExplainer(rf)
rf_explainer.expected_value
# array([-11.59166808])

mean_pred_rf = np.mean(rf.predict(X_train))
mean_pred_rf
# -11.280125877556388

np.isclose(mean_pred_rf, rf_explainer.expected_value)
# array([False])
于 2020-11-10T13:27:57.040 回答
1

试试看嘛 :

shap_explainer_model = shap.TreeExplainer(RF_best_parameters, data=X_train, feature_perturbation="interventional", model_output="raw")

然后shap_explainer_model.expected_value应该为您提供模型对火车数据的平均预测。

否则,TreeExplainer 使用feature_perturbation="tree_path_dependent"; 根据文档

“tree_path_dependent”方法是只跟随树并使用沿着每个叶子向下的训练示例的数量来表示背景分布。这种方法不需要背景数据集,因此在没有提供背景数据集时默认使用。

于 2020-06-05T15:37:17.403 回答