caret中使用训练数据绘制ROC曲线

32

使用R语言包caret,我如何基于train()函数的交叉验证结果生成ROC曲线?

比如说,我执行了以下操作:

data(Sonar)
ctrl <- trainControl(method="cv", 
  summaryFunction=twoClassSummary, 
  classProbs=T)
rfFit <- train(Class ~ ., data=Sonar, 
  method="rf", preProc=c("center", "scale"), 
  trControl=ctrl)

训练函数会涉及一系列的mtry参数,并计算ROC AUC。我想查看关联的ROC曲线--如何实现?
注意:如果采样方法是LOOCV,则rfFit将在rfFit$pred位置包含非空数据帧,这似乎正是我所需要的。但是,我需要的是k折交叉验证方法("cv"方法),而不是LOO。
另外:不,Caret以前版本中包含的roc函数不是答案--这是一个底层函数,如果您没有每个交叉验证样本的预测概率,则无法使用它。

http://www.inside-r.org/packages/cran/caret/docs/roc - Frash
1
不,这不是答案。首先,现代版本的caret没有这个功能。其次,该函数需要一个“要切割的变量”——具体来说,是预测概率,但我如何从train()函数返回的对象中获取这些概率呢? - January
3个回答

48

只需要在ctrl中添加savePredictions = TRUE参数即可(这也适用于其他重抽样方法):

library(caret)
library(mlbench)
data(Sonar)
ctrl <- trainControl(method="cv", 
                     summaryFunction=twoClassSummary, 
                     classProbs=T,
                     savePredictions = T)
rfFit <- train(Class ~ ., data=Sonar, 
               method="rf", preProc=c("center", "scale"), 
               trControl=ctrl)
library(pROC)
# Select a parameter setting
selectedIndices <- rfFit$pred$mtry == 2
# Plot:
plot.roc(rfFit$pred$obs[selectedIndices],
         rfFit$pred$M[selectedIndices])

ROC

也许我错过了什么,但小小的担忧是,train总是估计略有不同的AUC值,与plot.rocpROC::auc(绝对差异<0.005),尽管twoClassSummary使用pROC::auc来估计AUC。编辑:我认为这是因为train中的ROC是使用单独的CV-Sets计算AUC的平均值,在此我们同时计算所有重采样的AUC以获取整体AUC。

更新由于这引起了一些关注,这里提供了一个使用plotROC::geom_roc()进行ggplot2的解决方案:

library(ggplot2)
library(plotROC)
ggplot(rfFit$pred[selectedIndices, ], 
       aes(m = R, d = factor(obs, levels = c("R", "M")))) + 
    geom_roc(hjust = -0.4, vjust = 1.5) + coord_equal()

ggplot_roc


9
你对于计算多个AUC和仅使用OOB样本创建的AUC进行平均的评论是正确的。它们会有所不同。 - topepo
2
可以使用 rfFit$finalModel$mtry 提取 finalModel mtry。 - Brian D
1
获取交叉验证AUC的正确方法是什么 - 创建单个总体AUC还是对分开的交叉验证集合中的AUC进行平均? - samleighton87
我可以问一下,M和obs是什么吗? - Nadia Nadou
1
@NadiaNadou rfFit$pred$MrfFit$pred$R 是 M 和 R 的预测类别概率。obs 是交叉验证集中的正确(观察到的)值。 - thie1e

16

我将修改@thei1e的图表,希望对其他人有所帮助。

训练模型并进行预测

library(caret)
library(ggplot2)
library(mlbench)
library(plotROC)

data(Sonar)

ctrl <- trainControl(method="cv", summaryFunction=twoClassSummary, classProbs=T,
                     savePredictions = T)

rfFit <- train(Class ~ ., data=Sonar, method="rf", preProc=c("center", "scale"), 
               trControl=ctrl)

# Select a parameter setting
selectedIndices <- rfFit$pred$mtry == 2

更新的ROC曲线图

g <- ggplot(rfFit$pred[selectedIndices, ], aes(m=M, d=factor(obs, levels = c("R", "M")))) + 
  geom_roc(n.cuts=0) + 
  coord_equal() +
  style_roc()

g + annotate("text", x=0.75, y=0.25, label=paste("AUC =", round((calc_auc(g))$AUC, 4)))

enter image description here


4

2019年更新。这是最简单的方法https://cran.r-project.org/web/packages/MLeval/index.html。从Caret对象中获取最优参数和概率,然后计算多种指标和图形,包括:ROC曲线,PR曲线,PRG曲线和校准曲线。您可以将来自不同模型的多个对象放入其中以比较结果。

library(MLeval)
library(caret)

data(Sonar)
ctrl <- trainControl(method="cv", 
  summaryFunction=twoClassSummary, 
  classProbs=T)
rfFit <- train(Class ~ ., data=Sonar, 
  method="rf", preProc=c("center", "scale"), 
  trControl=ctrl)

## run MLeval

res <- evalm(rfFit)

## get ROC

res$roc

## get calibration curve

res$cc

## get precision recall gain curve

res$prg

enter image description here

enter image description here

enter image description here


2
我尝试了你的解决方案,但是出现了错误:Error in evalm(rfFit) : No probabilities found in Caret output - Bolle
2
@Bolle 我得到了和你一样的结果。你需要在trainControl中设置savePredictions = TRUE。 - SomeDutchGuy
1
现在我该如何将这个最佳截断应用于测试数据集,并使用MLeval获取混淆矩阵? - skan

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