【问题标题】:Understanding Partial Dependence for Gradient Boosted Regression trees理解梯度提升回归树的部分依赖
【发布时间】:2018-08-21 05:09:27
【问题描述】:

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

这似乎与 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 值来得到这个?

【问题讨论】:

    标签: python r scikit-learn


    【解决方案1】:

    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))
    

    对于这两种情况,部分依赖被报告为just

    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()
    

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

    如果您不仅想要单位,还想要与 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');
    

    【讨论】:

    • 公式中的平均值是所有数据点的平均值,而不是整体。该公式被声明为适用于所有模型。我有兴趣使用部分依赖作为一种价格指数。有没有办法将这里给出的内容转换为因变量的单位?
    • 在回归的情况下,是的:它已经在因变量的单位中。但是这些值是居中的,所以它们告诉你偏离平均值。
    • 不幸的是,在分类的情况下,否:报告概率会产生误导,因为在概率单位中,模型不是相加的,部分重要性旨在显示变量的相加效应。
    • 我已经更新了问题,请看。我想知道如何回到预测值。即加回平均值
    • 太棒了!当它允许我时,我会奖励赏金。
    【解决方案2】:

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

    【讨论】:

    • 问题中的公式不正确吗?这是一个平均价格。这种情况是回归而不是分类,所以它仍然是概率的对数吗?
    • 公式没问题。它的目的不是提供价格,而是提供居住人数、房屋年龄、业主收入及其对房价的影响/影响之间的关系。它基本上是一个效果图。由于位置是主要因素,因此无法估计实际价格。
    • 我实际上在一年前画了同样的情节,并且在我的脑海中经历了同样的问题。价格在哪里?然后我开始深入阅读部分依赖图。他们实际上并没有像我认为的那样做。 kaggle.com/dansbecker/partial-dependence-plots
    猜你喜欢
    • 2013-10-15
    • 2021-06-16
    • 1970-01-01
    • 2015-03-07
    • 2019-06-27
    • 1970-01-01
    • 2020-01-26
    • 1970-01-01
    • 2020-04-10
    相关资源
    最近更新 更多