随机森林的 TreeExplainer 的 expected_value 字段是啥?
Posted
技术标签:
【中文标题】随机森林的 TreeExplainer 的 expected_value 字段是啥?【英文标题】:What is the expected_value field of TreeExplainer for a Random Forest?随机森林的 TreeExplainer 的 expected_value 字段是什么? 【发布时间】:2020-06-04 07:13:48 【问题描述】:我用 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 (我也读过这个here)
但事实并非如此。 命令的输出:
shap_explainer_model.expected_value
是 0.2381。 命令的输出:
RF_best_parameters.predict(X_train).mean()
是 0.2389。
正如我们所看到的,这些值是不一样的。
那么这里的expected_value
是什么意思呢?
【问题讨论】:
【参考方案1】:这是由于与随机森林算法一起使用时该方法的特殊性;引用相关 Github 线程 shap explainer expected_value is different from model 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])
【讨论】:
【参考方案2】:试试看:
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"
;对应documentation:
“tree_path_dependent”方法是只跟随树,并使用沿着每个叶子向下的训练示例的数量来表示背景分布。此方法不需要后台数据集,因此在没有提供后台数据集时默认使用。
【讨论】:
OP 很清楚shap_explainer_model.expected_value
在他们的情况下没有给出平均预测(随机森林)。以上是关于随机森林的 TreeExplainer 的 expected_value 字段是啥?的主要内容,如果未能解决你的问题,请参考以下文章