从数据框中手动创建 ROC 曲线

Posted

技术标签:

【中文标题】从数据框中手动创建 ROC 曲线【英文标题】:Create ROC curve manually from data frame 【发布时间】:2021-11-09 08:27:02 【问题描述】:

我有以下概念性问题,我无法理解。

以下是调查数据示例,其中我有一个时间列,指示某人需要多长时间才能回答某个问题。

现在,我感兴趣的是清洁量将如何根据此阈值发生变化,即如果我增加阈值会发生什么,如果我降低它会发生什么。

所以我的想法是创建一条 ROC 曲线(或其他模型指标),以获得关于潜在阈值的视觉提示。问题是我没有类似机器学习的模型来给我分类概率。所以我想知道是否有任何方法可以使用这种类型的数据创建 ROC 曲线。我的想法是在大约 100 个不同的阈值处循环遍历我的数据,计算每个阈值的假阳性率和真阳性率,然后做一个简单的线图,但我希望有一个更优雅的解决方案,不需要我循环.

有什么想法吗?

示例数据:

time 列表示每个案例所需的时间 truth 列表示我想要比较的当前决定 predicted 列表示我是否会在时间阈值2.5s 进行切割时的清洁决定。这是我需要更改/循环的内容。
set.seed(3)
df <- data.frame(time      = c(2.5 + rnorm(5), 3.5 + rnorm(5)),
                 truth     = rep(c("cleaned", "final"), each = 5)) %>%
  mutate(predicted = if_else(time < 2.5, "cleaned", "final"))

【问题讨论】:

因为您需要计算每个阈值的 ROC 点,所以除了循环的某些变体之外,我没有看到其他选择。 【参考方案1】:

所以我的想法是创建一条 ROC 曲线

创建 ROC 曲线很简单

library(pROC)
set.seed(3)
data.frame(time      = c(2.5 + rnorm(5), 3.5 + rnorm(5)),
           truth     = rep(c("cleaned", "final"), each = 5)) |>
    roc(truth, time) |>
    plot()

问题是我没有类似机器学习的模型来提供类概率。

抱歉,我不明白这个问题是什么机器学习

我的想法是在大约 100 个不同的阈值处循环遍历我的数据

如果您有 10 个观察值,则循环超过 100 个可能的阈值是没有意义的。合理的截止值是位于您的time 值之间的九个。你可以从roc得到那些:

df <- data.frame(time      = c(2.5 + rnorm(5), 3.5 + rnorm(5)),
                truth     = rep(c("cleaned", "final"), each = 5))

thresholds <- roc(df, truth, time)$thresholds
print(thresholds)

> print(thresholds)
 [1]     -Inf 1.195612 1.739608 1.968531 2.155908 2.329745 2.561073
 [8] 3.093424 3.969994 4.586341      Inf

“循环”一词的确切含义以及您是否只想排除 forwhile 循环或您认为是循环的任何内容都需要一些精确的定义。 c(1, 2, 3, 4) * 5 是循环吗?引擎盖下会有一个循环运行。

【讨论】:

有趣。但是,我有点惊讶该函数如何确定不同阈值的清理/最终类,即预测类。该函数没有关于做什么的任何信息,例如在阈值 1.968531(阈值示例中的第 4 个值)。 至于数据本身,只是一个例子,有10个案例。在现实生活中可能是100k。对于“类似机器学习”,我的意思是我需要将真实情况与某个预测的“类”进行比较,这通常在机器学习的训练/测试设置中完成。 ROC 隐含预测方法:如果我们假设低于阈值的值为cleaned,高于阈值的值为final,那么给定样本内的敏感性和特异性是多少。为每个可能的阈值画一条线。 @Shibaprasadb 使用的函数甚至对沿线的阈值进行颜色编码。将数据划分为训练和测试数据集并不是 ROC 固有的。那是你最初想做的吗? “函数如何确定不同阈值下的清理/最终类”完全由 ROC 算法定义。 感谢您的回复(尽管我接受了另一个带有 ROCR 包的回复)。我还看到我对包将如何确定预测类别的概念误解。所以我猜它只是使用数字时间列并在不同的位置进行切割,并假设“真相”列的设置方式是它只“清理”低于某个阈值而其他一切都是“最终的”,那么它可以只需计算如果阈值发生变化会发生什么。【参考方案2】:

您也可以为此使用ROCR

library(ROCR)

set.seed(3)
df <- data.frame(time      = c(2.5 + rnorm(5), 3.5 + rnorm(5)),
                 truth     = rep(c("cleaned", "final"), each = 5)) %>%
  mutate(predicted = if_else(time < 2.5, "cleaned", "final"))

pred <- prediction(df$time, df$truth)
perf <- performance(pred,"tpr","fpr")
plot(perf,colorize=TRUE)

您也可以查看AUC值:

auc <- performance(pred, measure = "auc")
auc@y.values[[1]]

[1] 0.92

pROC交叉检查AUC值

library(pROC)

roc(df$truth, df$time)

Call:
roc.default(response = df$truth, predictor = df$time)

Data: df$time in 5 controls (df$truth cleaned) < 5 cases (df$truth final).
Area under the curve: 0.92

这两种情况都是一样的!

【讨论】:

感谢您的回答。我喜欢 ROCR 包的 plot 版本,所以我会接受这是我的首选答案,尽管我通常喜欢是否可以在 tidyverse 管道中调用包函数(而且我还没有设法将 pred/perf 计算放入我的烟斗。

以上是关于从数据框中手动创建 ROC 曲线的主要内容,如果未能解决你的问题,请参考以下文章

详解支持向量机-基于SVM的ROC曲线和AUC面积菜菜的sklearn课堂笔记

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

如何从真实类和预测类绘制多类 Roc 曲线

r R脚本用于从数据生成和绘制ROC曲线

如何从分类树概率中绘制 ROC 曲线

ROC曲线怎么做啊