R:我在gbm和RandomForest的部分依赖图中看到了什么?


14

实际上,我以为我已经理解了一个可以显示具有部分依赖图的图,但是使用一个非常简单的假设示例,我很困惑。在下面的代码块中,我生成了三个自变量(abc)和一个因变量(y),其中cy呈紧密线性关系,而aby不相关。我使用R包使用增强的回归树进行回归分析gbm

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")
par(mfrow = c(2,2))
plot(gbm.gaus, i.var = 1)
plot(gbm.gaus, i.var = 2)
plot(gbm.gaus, i.var = 3)

不足为奇的是,变量一个b的部分依赖曲线得到围绕平均值的水平线一个。我感到困惑的是变量c的图。我得到范围c <40和c > 60的水平线,并且y轴的值被限制为接近y的平均值。由于aby完全无关(因此模型中的变量重要性为0),所以我期望c对于其非常有限的值范围,将在整个范围内显示部分依赖性,而不是在该S型形状中显示。我试图在Friedman(2001)“贪婪函数逼近:梯度提升机”和Hastie等人中找到信息。(2011)“统计学习的要素”,但是我的数学技能太低,无法理解其中的所有方程式和公式。因此,我的问题是:什么决定变量c的偏相关图的形状?(请用非数学家可以理解的语言解释!)

在2014年4月17日新增:

在等待响应时,我使用相同的示例数据进行R-package分析randomForest。randomForest的部分相关图与我从gbm图中所期望的非常相似:解释变量ab的部分相关随机且在50附近变化,而解释变量c在其整个范围内(以及几乎在y的整个范围)。可能是什么在部分依赖地块的这些不同形状的原因gbmrandomForest

gbm和randomForest的局部图

这里是比较绘图的修改后的代码:

a <- runif(100, 1, 100)
b <- runif(100, 1, 100)
c <- 1:100 + rnorm(100, mean = 0, sd = 5)
y <- 1:100 + rnorm(100, mean = 0, sd = 5)
par(mfrow = c(2,2))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")

library(gbm)
gbm.gaus <- gbm(y ~ a + b + c, data = Data, distribution = "gaussian")

library(randomForest)
rf.model <- randomForest(y ~ a + b + c, data = Data)

x11(height = 8, width = 5)
par(mfrow = c(3,2))
par(oma = c(1,1,4,1))
plot(gbm.gaus, i.var = 1)
partialPlot(rf.model, Data[,2:4], x.var = "a")
plot(gbm.gaus, i.var = 2)
partialPlot(rf.model, Data[,2:4], x.var = "b")
plot(gbm.gaus, i.var = 3)
partialPlot(rf.model, Data[,2:4], x.var = "c")
title(main = "Boosted regression tree", outer = TRUE, adj = 0.15)
title(main = "Random forest", outer = TRUE, adj = 0.85)

1
您可能想要实际调整超参数的触摸效果。我不确定gbm中的默认树数是多少,但是它可能是如此之小,以至于没有时间学习健康的曲率。
Shea Parkes'Apr

@Shea Parkes-你是对的。缺省的树数为100,这不足以生成一个好的模型。2000棵树的gbm和随机森林的部分依赖图几乎相同。
user7417 2014年

Answers:


7

在意识到它已经捆绑在R randomForest库中之前,我花了一些时间编写自己的“ partial.function-plotter”。

[编辑...但是后来我花了一年时间制作了CRAN包forestFloor,据我认为,它比经典的部分依赖图要好得多]

如此处所示的模拟示例,在这种情况下,partial.function图非常有用,其中解释变量不会与其他变量交互。如果每个解释变量通过某个未知函数加到目标Y上,则该方法很好地显示了估计的隐藏函数。我经常在部分功能的边界看到这种扁平化。

原因如下:randomForsest有一个名为“ nodesize = 5”的参数,这意味着没有树可以细分5个或更少成员的组。因此,每棵树都无法进一步精确区分。整体的装袋/引导层通过对单个树的许多阶跃函数进行投票来平滑,但仅限于数据区域的中间。靠近数据表示空间的边界时,partial.function的“幅度”将下降。设置nodesize = 3和/或获得比噪声更多的观察值,可以减少这种边界平坦化的影响...当信噪比总体上在随机森林中下降时,预测范围就会缩小。因此,这些预测并非绝对准确,只是与目标线性相关。您可以看到a和b值作为信号示例,信噪比极低,因此,这些部分功能非常平坦。这是随机森林的一个不错的功能,您已经可以从训练集的预测范围中猜测出模型的性能如何。OOB.predictions也很棒。

没有数据的区域中局部图的平坦化是合理的:由于随机森林和CART是数据驱动的建模,因此我个人喜欢这些模型不外推的概念。因此,c = 500或c = 1100的预测与c = 100完全相同,或者在大多数情况下也为c = 98。

这是减少边框展平的代码示例:

我没有尝试过gbm软件包...

这是一些基于您的eaxample的说明性代码...

#more observations are created...
a <- runif(5000, 1, 100)
b <- runif(5000, 1, 100)
c <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
y <- (1:5000)/50 + rnorm(100, mean = 0, sd = 0.1)
par(mfrow = c(1,3))
plot(y ~ a); plot(y ~ b); plot(y ~ c)
Data <- data.frame(matrix(c(y, a, b, c), ncol = 4))
names(Data) <- c("y", "a", "b", "c")
library(randomForest)
#smaller nodesize "not as important" when there number of observartion is increased
#more tress can smooth flattening so boundery regions have best possible signal to             noise, data specific how many needed

plot.partial = function() {
partialPlot(rf.model, Data[,2:4], x.var = "a",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "b",xlim=c(1,100),ylim=c(1,100))
partialPlot(rf.model, Data[,2:4], x.var = "c",xlim=c(1,100),ylim=c(1,100))
}

#worst case! : with 100 samples from Data and nodesize=30
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=30)
plot.partial()

#reasonble settings for least partial flattening by few observations: 100 samples and nodesize=3 and ntrees=2000
#more tress can smooth flattening so boundery regions have best possiblefidelity
rf.model <- randomForest(y ~ a + b + c, data = Data[sample(5000,100),],nodesize=5,ntress=2000)
plot.partial()

#more observations is great!
rf.model <- randomForest(y ~ a + b + c,
 data = Data[sample(5000,5000),],
 nodesize=5,ntress=2000)
plot.partial()

4

如上面的评论所述,gbm模型通过一些参数调整会更好。发现模型中的问题以及对此类参数的需求的一种简便方法是生成一些诊断图。例如,对于上面带有默认参数的gbm模型(并使用 plotmo 包创建图),我们有

gbm.gaus <- gbm(y~., data = Data, dist = "gaussian")
library(plotmo)   # for the plotres function
plotres(gbm.gaus) # plot the error per ntrees and the residuals

这使

情节

在左图中,我们看到误差曲线还没有触底。在右图中,残差不是我们想要的。

如果我们用更多的树来重建模型

gbm.gaus1 <- gbm(y~., data = Data, dist = "gaussian",
                 n.trees=5000, interact=3)
plotres(gbm.gaus1)

我们得到

情节

我们看到误差曲线随着大量树木而触底反弹,残差图更健康。我们还可以绘制新gbm模型和随机森林模型的部分依赖图

library(plotmo)
plotmo(gbm.gaus1, pmethod="partdep", all1=TRUE, all2=TRUE)
plotmo(rf.model,  pmethod="partdep", all1=TRUE, all2=TRUE)

这使

情节

gbm和随机森林模型图现在与预期的相似。


3

interaction.depth构建增强模型时,需要更新参数。它的默认值为1,这将导致该gbm算法构建的所有树仅分裂一次。这意味着每棵树都只是在变量c上分裂,并且根据它使用的观察样本,它将分裂约40-60。

这是与 interaction.depth = 3

在此处输入图片说明


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.