随机森林的 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 字段是啥?的主要内容,如果未能解决你的问题,请参考以下文章

随机森林

随机森林原理

随机森林

特征筛选(随机森林)

RandomForest随机森林算法

分类算法 - 随机森林