如何计算随机森林的OOB?

5

我正在比较一些模型,以获得最佳模型。现在,我想获取随机森林模型的OOB误差,以将其与其他一些模型的交叉验证误差进行比较。我能做这个比较吗?如果可以,如何通过R代码获取OOB误差?


1
尝试使用 model$err.rate[,1] - 第 i 个元素表示所有树木的 (OOB) 错误率,直到第 i 个。顺便说一句,虽然 OOB 应该与 k-fold CV 相关,但我仍然只比较模型之间的 k-fold CV。 - missuse
@missuse 谢谢你的回复!但是如何为随机森林计算k折交叉验证?一些人使用rfcv()函数,但这似乎是用于计算交叉验证误差以便在随机森林之间进行比较。但我需要将随机森林的交叉验证误差与Ridge模型的交叉验证误差进行比较。我该怎么办? - grace
1个回答

11
要在R中获取随机森林模型的OOB,您可以执行以下操作:
library(randomForest)

set.seed(1)
model <- randomForest(Species ~ ., data = iris)

OOB错误出现在:

model$err.rate[,1]

第i个元素是所有树直到第i个的(OOB)错误率。

可以绘制它并检查是否与为rf模型定义的plot方法中的OOB相同:

par(mfrow = c(2,1))
plot(model$err.rate[,1], type = "l")
plot(model)

在此输入图片描述

OOB对于选择超参数mtryntree非常有用,并且应该与k-fold交叉验证相关,但不应将其用于将随机森林与通过k-fold交叉验证测试的不同类型的模型进行比较。OOB很棒,因为它几乎是免费的,而k-fold交叉验证需要运行k次。

R中运行k-fold交叉验证的简单方法是:

定义折叠(将5替换为k(正整数> 1)以运行k-fold交叉验证:

folds <- sample(1:5, size = nrow(iris), replace = T) #5 fold CV

这种方法不会给出相等大小的折叠(特别是对于较小的数据集),通常这并不是一个大问题。

table(folds)
#output
 1  2  3  4  5 
30 28 28 33 31 

为了解决这个问题:
folds <- sample(rep(1:5, length.out = nrow(iris)), size = nrow(iris), replace = F)

table(folds)
#output
 1  2  3  4  5 
30 30 30 30 30 

在每个折叠中训练模型并预测第五个折叠。在这里,我只返回包含预测和真实值的数据帧列表,可以自定义调用以返回所需的任何统计信息。

CV_rf <- lapply(1:5, function(x){ #5 corresponds to the number of folds defined earlier
  model <- randomForest(Species ~ ., data = iris[folds != x,])
  preds <- predict(model,  iris[folds == x,], type="response")
  return(data.frame(preds, real = iris$Species[folds == x]))
  })

您可以使用相同的代码来获取岭回归模型的性能。

将数据框的列表转换为数据框:

CV_rf <- do.call(rbind, CV_rf)

检查准确性

caret::confusionMatrix(CV_rf$preds, CV_rf$real) 
#part of output:
Overall Statistics

               Accuracy : 0.9533         
                 95% CI : (0.9062, 0.981)
    No Information Rate : 0.3333         
    P-Value [Acc > NIR] : < 2.2e-16 

这里的准确率为0.9533。

而500棵树中第500棵(在随机森林中默认拟合500棵树)的袋外误差为:

model$err.rate[500,1]
#OOB 
0.04666667 

它们完全打破了我的观点,但例如尝试运行10倍交叉验证或3倍交叉验证,您会发现它们并不相同。

另一种方法是使用caretmlr库。我不使用mlr,但caret非常适合这样的任务。这里有一些东西可以帮助您开始使用caret和rf。此外,caret具有出色的文档。即使您不打算使用该软件包,我也可以推荐它。


当我使用xtest和ytest时,rf模型对象中没有err.rate,我该如何获得OOB r2? - Herman Toothrot
如果您需要OOB,请不要使用“xtest”和“ytest”参数,而是使用生成的模型上的预测来获取测试集的预测。 - missuse
有没有办法从由caret生成的finalModel中提取OOB错误,类似于使用randomForest直接训练的模型时的model$err.rate[500,1]?谢谢! - undefined
@MarkH,tail(caretTrainOutout$finalModel$err.rate[,1], 1) 这个能用吗? - undefined
@missuse,我有同样的想法,但它不起作用。虽然我的模型对象有一个fit对象finalModel,但它不包含err.rate项,建议的代码返回NULL。在finalModel中有两个长度为ntree的向量:msersq,但是caret文档没有超出finalModel的层级,所以我不确定它们到底是什么,以及如何使用它们来访问oob错误。 - undefined
@missuse,我刚刚找到了这个链接,也许没有其他办法可以从caret训练的随机森林中获取oob错误...虽然这看起来有些奇怪。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接