梯度提升机的精度随着迭代次数的增加而降低


15

我正在通过caretR中的程序包尝试使用梯度增强机算法。

使用一个小的大学录取数据集,我运行了以下代码:

library(caret)

### Load admissions dataset. ###
mydata <- read.csv("http://www.ats.ucla.edu/stat/data/binary.csv")

### Create yes/no levels for admission. ### 
mydata$admit_factor[mydata$admit==0] <- "no"
mydata$admit_factor[mydata$admit==1] <- "yes"             

### Gradient boosting machine algorithm. ###
set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(5000,1000000,5000), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

令我惊讶的是,随着增强迭代次数的增加,模型的交叉验证准确性下降而不是增加,在〜450,000迭代时达到约0.59的最低精度。

在此处输入图片说明

我是否错误地实现了GBM算法?

编辑:按照Underminer的建议,我重新运行了上面的caret代码,但专注于运行100到5,000次增强迭代:

set.seed(123)
fitControl <- trainControl(method = 'cv', number = 5, summaryFunction=defaultSummary)
grid <- expand.grid(n.trees = seq(100,5000,100), interaction.depth = 2, shrinkage = .001, n.minobsinnode = 20)
fit.gbm <- train(as.factor(admit_factor) ~ . - admit, data=mydata, method = 'gbm', trControl=fitControl, tuneGrid=grid, metric='Accuracy')
plot(fit.gbm)

结果图表明,在约1,800次迭代中,精度实际上达到了近.705的峰值:

在此处输入图片说明

令人好奇的是,精度没有稳定在〜.70左右,而是在5,000次迭代后下降了。

Answers:


14

通常,增强误差会随着迭代次数的增加而增加,尤其是在数据嘈杂时(例如,标注错误的情况)。这可能是您的问题,但如果不了解您的数据,我将无法说出来

基本上,提高效率可以将“重点”放在正确预测包含错误信息的案例上,并且在此过程中,会使其他实质性案例的平均绩效下降。

这个链接(Boosting和Noise)显示了比我可以提供的更好的描述。

Long和Servedio的这篇论文(《随机分类噪声》)提供了该问题的更多技术细节。


16

您显示的是过度拟合的经典示例。错误的少量上升是由于交叉验证的数据集的验证部分的性能较差。更多的迭代几乎总会改善训练集上的错误,但是对于验证/测试集,情况恰恰相反。


因此,基于#次增强迭代的梯度增强过拟合吗?有趣。我认为在达到最佳迭代次数后,精度会趋于平稳。
RobertF

4
没错 在梯度增强中,每棵后续树都是从先前树的残差构建而成的,因此GBM会继续尝试消除训练数据集上的剩余错误,甚至以能够推广到验证/测试集为代价。这就是为什么你进行交叉验证-因为拟合算法本身不知道什么时候停止
瑞安佐蒂

1
梯度提升受AdaBoost的启发。AdaBoost很少过拟合,当它过拟合时,它只是略微过了很多次迭代。我认为@Underminer的解释比该评论更能代表正在发生的事情,尤其是考虑到此评论中没有引用。
里卡多·克鲁兹

2
@RicardoCruz我觉得有趣的是,您很少见到梯度增强过拟合。在我使用它的四年左右的时间里,我看到了相反的情况-太多的树木会导致过度拟合。我曾经不得不证明与某位同事类似的东西,并且能够将训练集上的错误减少到几乎为零,但是验证错误的上升幅度明显大于非过度拟合的GBM。我仍然认为梯度提升是一种很棒的算法。它通常是第一个算法我使用-你只是要小心,太多的树木,您可以通过交叉验证跟踪
瑞安佐蒂

2
@RyanZotti我会纠正。我已经阅读了Schapire等人关于AdaBoost的大量论文,因为我喜欢它美丽的强大理论基础。作者认为,增强容易导致过度拟合,但是这极其困难。我在使用它方面没有太多的经验,他们对此也没有扎实的理论基础,当然,作者是作家,他们自然热衷于他们的发明,因此,如果您有相反的经验,我站得住了。
里卡多·克鲁兹

4

无需网格搜索即可产生相似结果的代码,

mod = gbm(admit ~ .,
      data = mydata[,-5],
      n.trees=100000,
      shrinkage=0.001,
      interaction.depth=2,
      n.minobsinnode=10,
      cv.folds=5,
      verbose=TRUE,
      n.cores=2)

best.iter <- gbm.perf(mod, method="OOB", plot.it=TRUE, oobag.curve=TRUE, overlay=TRUE)
print(best.iter)
[1] 1487
pred = as.integer(predict(mod, newdata=mydata[,-5], n.trees=best.iter) > 0)
y = mydata[,1]
sum(pred == y)/length(y)
[1] 0.7225

3

gbm套件具有估算最佳迭代次数的功能(=树的数量或基函数的数量),

gbm.perf(mod, method="OOB", plot.it=TRUE, oobag=TRUE, overlay=TRUE)

您不需要插入符号的训练。


我不知道这是否可以解决我遇到的问题-在我的情况下,迭代的最佳次数是5,000,其中精度最高,接近0.70(图中的第一个数据点)。但这似乎是错误的。更多的迭代应该导致更高的精度,而不是更低,对吧?
罗伯特·F

1
@RobertF首先,我认为您不需要将承认变成一个因素。它也可以正常工作:mod = gbm(admit〜。,data = mydata [,-5],n.trees = 100000,收缩率= 0.001,interact.depth = 2,n.minobsinnode = 10,cv.folds = 5 ,详细= TRUE,n.cores = 2)。您可以通过以下方式查看gbm在何处选择最佳迭代:best.iter <-gbm.perf(mod,method =“ OOB”,plot.it = TRUE,oobag.curve = TRUE,overlay = TRUE)。也就是说,当偏差变化变为负值时(请参见由此生成的图)。
horaceT'6

1
@RobertF还有一件事。通过在gbm调用中指定n.trees =(一百万),您将运行从1到1,000,000的所有迭代次数。因此,您不需要插入符号即可为您执行此操作。
horaceT'6

1
@RobertF更多跟进。我只跑了10万棵树/迭代。通过选择gbm.perf的最佳迭代获得的精度为0.7225,这与您运行完整的迭代网格非常接近。
horaceT'6
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.