在R中使用randomForest包,如何从分类模型中获取概率?

23

简述:

在原始 randomForest 调用中是否有什么我可以标记,以避免重新运行 predict 函数来获取预测类别的概率,而不仅仅是可能的类别?

详情:

我正在使用randomForest包。

我的模型类似于:

model <- randomForest(x=out.data[train.rows, feature.cols],
                      y=out.data[train.rows, response.col],
                      xtest=out.data[test.rows, feature.cols],
                      ytest=out.data[test.rows, response.col],
                      importance= TRUE)

其中,out.data是一个数据框,feature.cols包含数值型和分类变量,而response.col是一个TRUE/FALSE二元变量,我将其强制转换为factor,以便于randomForest模型正确处理它。

所有运行良好,变量model被正确地返回给我。然而,我无法找到一个标志或参数传递给randomForest函数,使得model可以返回TRUEFALSE的概率。相反,我只能得到预测值。也就是说,如果我查看model$predicted,我会看到类似以下内容:

FALSE
FALSE
TRUE
TRUE
FALSE
.
.
.

相反,我希望看到类似这样的内容:

   FALSE  TRUE
1  0.84   0.16
2  0.66   0.34
3  0.11   0.89
4  0.17   0.83
5  0.92   0.08
.   .      .
.   .      .
.   .      .

我能理解上述内容,但为了实现这一点,我需要像这样做:

tmp <- predict(model, out.data[test.rows, feature.cols], "prob")

[test.rows 捕获了在模型测试期间使用的行号。 这里没有显示详细信息,但很简单,因为测试行ID被输出到 model 中。]

然后一切都正常。 问题在于模型很大,运行时间非常长,甚至预测本身也需要一段时间。由于预测应该是完全不必要的(我只是想在测试数据集上计算ROC曲线,该数据集应该已经被计算),所以我希望跳过这一步。 在原始的 randomForest调用中是否有标志可以标记以避免重新运行predict函数?


1
randomForest 函数可用于任何类型的分析; 本问题可能会受益于一个可复现的示例,该示例展示了您正在运行的内容以及一些样本/代表性数据。我认为如果您只是使用 predict(model, type="prob"),速度会更快。这里,您需要从拟合的模型中得出预测,因此不需要传递 newdata= 参数。但是,由于您没有提供任何测试方式,很难说这是否会解决您的问题。 - MrFlick
1
那么你没有注意到随机森林对象的投票组件吗?文档中对它有一个相当清晰的描述。 - joran
谢谢,@joran...我以为“votes”可能只是指概率。(例如,如果300/500棵树被观察者体验到投票“TRUE”,那么它将给出60%的真实值。)然而,这似乎不是统计学上的“紧密”,因为IID是通过代理假设的。由于接近性和其他数据可用,我想也许可以通过某种方式调整权重来提取更精确的概率。我认为这样做是不行的。感谢确认! - Mike Williamson
1
你的评论让我觉得你或许应该花些时间阅读有关随机森林的一些参考资料,特别是可能是Breiman的原始论文(在pckg文档中引用)。正如“votes”的文档所述,比例是针对OOB(袋外)投票的,因此每个案例只运行到它不在自助样本中的树上。还有一些其他细节需要注意的,如OOB误差率的计算方式(请参见“oob.times”),但“votes”中的内容相当严谨… - joran
有一些对OOB错误率的批评,但我仍然建议阅读有关RF文献的相关主题。 - joran
1个回答

31

model$predicted 不是由 predict() 返回的相同东西。如果您想要 TRUEFALSE 类的概率,则必须运行 predict() 或传递 x,y,xtest,ytest

randomForest(x,y,xtest=x,ytest=y), 

x=out.data[, feature.cols], y=out.data[, response.col],其中x包含特征列,y包含响应列。

model$predicted根据每个记录在model$votes中的值大小返回类别。正如@joran所指出的那样,votes是随机森林中OOB(out of bag)‘votes’的比例,仅当记录在OOB样本中被选中时才计算投票。另一方面,predict()根据所有树的投票结果返回每个类别的真实概率。

与上述示例中传递公式或简单地传递randomForest(x,y)不同,使用randomForest(x,y,xtest=x,ytest=y)函数略有不同。 randomForest(x,y,xtest=x,ytest=y)将为每个类别返回概率,尽管听起来有点奇怪,但可以在model$test$votes下找到,预测类别在model$test$predicted下找到,它仅根据model$test$votes中哪个类别具有更大值而选择类别。此外,使用randomForest(x,y,xtest=x,ytest=y)时,model$predictedmodel$votes的定义与上述相同。

最后,需要注意的是,如果使用randomForest(x,y,xtest=x,ytest=y),那么为了使用predict()函数,keep.forest标志应该设置为TRUE。

model=randomForest(x,y,xtest=x,ytest=y,keep.forest=TRUE). 
prob=predict(model,x,type="prob")

prob 将会model$test$votes 等价,因为测试数据的输入都是x


嗨,奥斯卡,我已经提供并一直在提供“测试”数据集。抱歉我最初没有明确说明...我已经编辑了我的原始帖子。感谢您指出它在“$test$votes”下...这正是我正在寻找的,尽管它仍然似乎做出了很多假设,比如IID。(据我所知)没有进行任何协方差测试或其他测试。谢谢! - Mike Williamson
嗨,Mike,我很高兴你搞定了。如果你想使用predict()函数并且想传递其他测试数据点,请不要忘记设置keep.forest=TRUE。我不认为有协方差测试,但我没有深入研究过,所以不确定。 - Oscar

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