插入符号中训练数据的 ROC 曲线

Posted

技术标签:

【中文标题】插入符号中训练数据的 ROC 曲线【英文标题】:ROC curve from training data in caret 【发布时间】:2015-09-17 06:40:38 【问题描述】:

使用 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 槽中包含一个非空数据帧,这似乎正是我所需要的。但是,对于“cv”方法(k 折验证)而不是 LOO,我需要它。

另外:不,以前版本的插入符号中包含的 roc 函数不是答案 - 这是一个低级函数,如果您没有预测概率,则无法使用它每个交叉验证的样本。

【问题讨论】:

inside-r.org/packages/cran/caret/docs/roc 不,这不是答案。首先,现代版的插入符号没有这个功能。其次,该函数需要一个“切入变量”——特别是预测概率,但我如何从 train() 函数返回的对象中获取这些? 【参考方案1】:

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

【讨论】:

我尝试了您的解决方案并收到错误:Error in evalm(rfFit) : No probabilities found in Caret output @Bolle 我和你一样。您需要在 trainControl 中设置 savePredictions = TRUE 现在如何将这个最佳截止值应用于测试数据集并使用 MLeval 获得混淆矩阵?【参考方案2】:

在这里,我正在修改@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)))

【讨论】:

【参考方案3】:

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])

也许我遗漏了一些东西,但一个小问题是 train 总是估计与 plot.rocpROC::auc 略有不同的 AUC 值(绝对差异 twoClassSummary 使用 pROC::auc 来估计曲线下面积。 编辑:我认为这是因为来自train 的 ROC 是使用单独 CV 集的 AUC 的平均值,在这里我们同时计算所有重新采样的 AUC 以获得整体 AUC。

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

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

【讨论】:

您关于平均许多 AUC 与从 OOB 样本创建的 AUC 的评论是正确的。它们会有所不同。 可以用rfFit$finalModel$mtry提取finalModel mtry 获得交叉验证 AUC 的正确方法是创建单个整体 AUC 还是在单独的交叉验证集上平均 AUC?

以上是关于插入符号中训练数据的 ROC 曲线的主要内容,如果未能解决你的问题,请参考以下文章

在 R 的插入符号训练函数中使用“ROC”度量的问题

在 R 中使用插入符号进行训练后,如何在 ROC 下计算 ROC 和 AUC?

从 R 中的交叉验证(训练)数据中绘制 ROC 曲线

python绘制影像组学训练集测试集对应的ROC曲线以及瀑布图(rad-score 瀑布图)

绘制测试集训练集的每一个病人或者样本的raidomics signiture图(绘制raidomics signature图),以及ROC曲线图

R - Caret - 在模型训练中使用 ROC 而不是准确性