r - 最大灵敏度/特异性与 ROC 曲线之间的关系是什么?
问题描述
在比较正常和下采样数据的机器学习模型的 ROC 曲线时,得到的灵敏度和特异性通常是非常不同的,因为下采样模型将类别平均化并且更强调捕获次要类别。为什么生成的 ROC 曲线看起来如此相似?
我认为这个问题最好用一个基于这个问题的简单例子来解释。
首先,获取声纳数据并手动对“R”类进行下采样以使数据不平衡并说明我的问题:
library(caret)
library(ggplot2)
library(mlbench)
library(plotROC)
data(Sonar)
set.seed(2019)
sonar_R <- Sonar %>% filter(Class == "R") %>% sample_n(., 20)
Sonar <- Sonar %>% filter(Class == "M") %>% rbind(sonar_R)
现在将插入符号用于具有主要类别的普通和下采样的随机森林模型:
ctrl <- trainControl(method="repeatedcv", number = 5, repeats = 5,
summaryFunction=twoClassSummary, classProbs=T,
savePredictions = T)
ctrl_down <- trainControl(method="repeatedcv", number = 5, repeats = 5,
summaryFunction=twoClassSummary, classProbs=T,
savePredictions = T, sampling = "down")
rfFit <- train(Class ~ ., data=Sonar, method="rf", preProc=c("center", "scale"),
trControl=ctrl)
rfFit_down <- train(Class ~ ., data=Sonar, method="rf", preProc=c("center", "scale"),
trControl=ctrl_down)
我现在可以定义一个函数来获得最大 ROC 以及相应的灵敏度和特异性:
max_accuracy <- function(model) {
model_accuracy <- as.data.frame(model$results)
model_accuracy <- model_accuracy %>%
select(ROC, Sens, Spec) %>%
arrange(desc(ROC))
model_accuracy <- model_accuracy[1,]
return(model_accuracy)
}
max_accuracy(rfFit)
max_accuracy(rfFit_down)
给予:
ROC Sens Spec
Normal 0.910 1 0.16
Down Sampled 0.872 0.827 0.77
并绘制 ROC 曲线:
selectedIndices <- rfFit$pred$mtry == 2
g <- ggplot(rfFit$pred[selectedIndices, ], aes(m=M, d=factor(obs, levels = c("R", "M")))) +
geom_roc(n.cuts=0, increasing = FALSE) +
coord_equal() +
style_roc(theme = theme_grey) +
ggtitle("Normal")
g +
annotate("text", x=0.75, y=0.25, label=paste("AUC =", round((calc_auc(g))$AUC, 4))) +
scale_x_continuous("1 - Specificity") + scale_y_continuous("Sensitivity")
selectedIndices_down <- rfFit$pred$mtry == 2
g_down <- ggplot(rfFit_down$pred[selectedIndices_down, ], aes(m=M, d=factor(obs, levels = c("R", "M")))) +
geom_roc(n.cuts=0, increasing = FALSE) +
coord_equal() +
style_roc(theme = theme_grey) +
ggtitle("Down Sampled")
g_down +
annotate("text", x=0.75, y=0.25, label=paste("AUC =", round((calc_auc(g_down))$AUC, 4))) +
scale_x_continuous("1 - Specificity") + scale_y_continuous("Sensitivity")
看起来像这样:
解决方案
推荐阅读
- r - 用列内类的平均值替换缺失值
- php - 我无法得到审讯的结果。(postgresql 和 php)
- ios - Swift:为浏览器创建搜索栏
- python - 使用 Pandas 创建一个矩阵,其中包含一组列范围和一组行范围
- python-3.x - 在 Jupyter Notebook 上导入 python 3.8.2 环境时所有模块的 ModuleNotFoundError
- version - 如何安装最新版本的 pytest,与旧版本共存?
- ios - MSL - 如何在金属着色器中指定统一的数组参数?
- c# - 如何获取 BLOB 并将其添加到我的配置中?
- loops - 结束连续循环并使用相同的热键重新启动脚本 - AutoHotkey
- r - 使用 merge() 和 sqldf::sqldf() 获得相同的交叉连接