理解梯度Boosted回归树的部分依赖性

时间:2018-03-13 03:21:32

标签: python r scikit-learn

我在查看Python中部分依赖图的tutorial。教程或documentation中没有给出等式。 R函数的documentation给出了我期望的公式:

enter image description here

这对Python教程中给出的结果似乎没有意义。如果它是房价预测的平均值,那么它是如何消极和小的?我希望价值数百万。我错过了什么吗?

更新

对于回归,似乎从上述公式中减去平均值。怎么会加回来?对于我训练有素的模型,我可以通过

获得部分依赖
from sklearn.ensemble.partial_dependence import partial_dependence
partial_dependence, independent_value = partial_dependence(model, features.index(independent_feature),X=df2[features])

我想平均添加(?)。我是否可以通过在df2值上使用model.predict()并更改independent_feature值来获得此结果?

2 个答案:

答案 0 :(得分:4)

R公式如何运作

问题中提供的r公式适用于randomForest。随机森林中的每棵树都试图直接预测目标变量。因此,每棵树的预测位于预期的间隔(在您的情况下,所有房价都是正的),并且集合的预测只是所有单个预测的平均值

ensemble_prediction = mean(tree_predictions)

这是公式告诉你的:只需预测所有树x并对它们取平均值。

为什么Python PDP值很小

然而,在sklearn中,计算GradientBoostingRegressor的部分依赖性。在梯度增强中,每个树在当前预测时预测损失函数的导数,其仅与目标变量间接相关。对于GB回归,预测为

ensemble_prediction = initial_prediction + sum(tree_predictions * learning_rate)

并且对于GB分类,预测概率为

ensemble_prediction = softmax(initial_prediction + sum(tree_predictions * learning_rate))

对于这两种情况,部分依赖性仅报告为

sum(tree_predictions * learning_rate)

因此,initial_prediction(对于GradientBoostingRegressor(loss='ls')它仅等于训练y的平均值)不包括在PDP中,这使得预测为负。

至于其值的小范围,示例中的y_train很小:平均值大致为2,因此房价可能以百万计。

sklearn公式如何实际运作

我已经说过在sklearn中,部分依赖函数的值是所有树的平均值。还有一个调整:所有不相关的功能都被平均掉了。为了描述实际的平均方法,我将引用sklearn的the documentation

  

对于网格中“目标”特征的每个值,部分   依赖函数需要边缘化树的预测   “补充”功能的所有可能值。在决策树中   这个功能可以有效地评估,而无需参考   培训数据。对于每个网格点,加权树遍历为   执行:如果拆分节点涉及“目标”功能,则执行   遵循相应的左或右分支,否则两者   遵循分支,每个分支按分数加权   训练进入该分支的样本。最后,部分   依赖性由所有访问叶子的加权平均值给出。对于   树集合每个树的结果再次取平均值。

如果您仍不满意,请参阅the source code

一个例子

要看到预测已经在因变量的范围内(但只是居中),你可以看一个非常有玩具的例子:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.ensemble.partial_dependence import plot_partial_dependence

np.random.seed(1)
X = np.random.normal(size=[1000, 2])
# yes, I will try to fit a linear function!
y = X[:, 0] * 10 + 50 + np.random.normal(size=1000, scale=5) 
# mean target is 50, range is from 20 to 80, that is +/- 30 standard deviations 
model = GradientBoostingRegressor().fit(X, y)

fig, subplots = plot_partial_dependence(model, X, [0, 1], percentiles=(0.0, 1.0), n_cols=2)
subplots[0].scatter(X[:, 0], y - y.mean(), s=0.3)
subplots[1].scatter(X[:, 1], y - y.mean(), s=0.3)
plt.suptitle('Partial dependence plots and scatters of centered target')
plt.show()

你可以看到部分依赖图很好地反映了居中目标变量的真实分布。

enter image description here

如果您不仅需要单位,而且平均值要与y重合,则必须将“丢失”均值添加到partial_dependence函数的结果中,然后手动绘制结果:

from sklearn.ensemble.partial_dependence import partial_dependence
pdp_y, [pdp_x] = partial_dependence(model, X=X, target_variables=[0], percentiles=(0.0, 1.0))
plt.scatter(X[:, 0], y, s=0.3)
plt.plot(pdp_x, pdp_y.ravel() + model.init_.mean)
plt.show()
plt.title('Partial dependence plot in the original coordinates');

enter image description here

答案 1 :(得分:0)

您正在查看部分依赖图。 PDP是表示的图表 一组变量/预测变量及其对目标字段的影响(在本例中为价格)。这些图表不估算实际价格。 重要的是要意识到PDP不是数据集值或价格的表示。它表示变量对目标字段的影响。负数是概率的对数,而不是原始概率。