在R中创建许多ROC曲线?

时间:2018-04-16 06:01:25

标签: r roc

我对150列标签(1/0)有150列分数。 我的目标是创造150个AUC分数。

以下是一个手动示例:

auc(roc(df$label, df$col1)),
auc(roc(df$label, df$col2)),

...

我可以在这里使用Map / sapply / lapply但是还有其他方法或函数吗?

3 个答案:

答案 0 :(得分:6)

这是一个XY问题。你真正想要实现的是加快计算速度。 gfgm's answer通过并行化解决问题,但这只是一种方法。

如果我假设您使用library(pROC) roc / auc函数,则可以通过为数据集选择合适的算法来获得更快的速度。

pROC基本上有两种算法,根据数据集的特征,这些算法的扩展方式会有很大差异。您可以通过将algorithm=0传递给roc

来确定哪一个最快
# generate some toy data
label <- rbinom(600000, 1, 0.5)
score <- rpois(600000, 10)

library(pROC)
roc(label, score, algorithm=0)
Starting benchmark of algorithms 2 and 3, 10 iterations...
  expr        min         lq       mean     median        uq      max neval
2    2 4805.58762 5827.75410 5910.40251 6036.52975 6085.8416 6620.733    10
3    3   98.46237   99.05378   99.52434   99.12077  100.0773  101.363    10
Selecting algorithm 3.

在这里,我们选择算法3,当阈值数量保持较低时,算法3会闪耀。但如果600000个数据点需要5分钟来计算,我强烈怀疑您的数据是非常连续的(没有相同值的测量值)并且您拥有与数据点(600000)一样多的阈值。在这种情况下,您可以直接跳到算法2,随着ROC曲线中阈值数量的增加,算法2的扩展性会更好。

然后您可以运行:

auc(roc(df$label, df$col1, algorithm=2)),
auc(roc(df$label, df$col2, algorithm=2)),

在我的机器上,每次调用roc现在大约需要5秒,这与阈值的数量无关。这样你就可以在不到15分钟的时间内完成。除非你有50个或更多核心,否则这将比并行化更快。但是你当然可以做到这两点......

答案 1 :(得分:4)

如果要并行化计算,可以这样做:

# generate some toy data
label <- rbinom(1000, 1, .5)
scores <- matrix(runif(1000*150), ncol = 150)
df <- data.frame(label, scores)

library(pROC)
library(parallel)

auc(roc(df$label, df$X1))
#> Area under the curve: 0.5103

auc_res <- mclapply(df[,2:ncol(df)], function(row){auc(roc(df$label, row))})
head(auc_res)
#> $X1
#> Area under the curve: 0.5103
#> 
#> $X2
#> Area under the curve: 0.5235
#> 
#> $X3
#> Area under the curve: 0.5181
#> 
#> $X4
#> Area under the curve: 0.5119
#> 
#> $X5
#> Area under the curve: 0.5083
#> 
#> $X6
#> Area under the curve: 0.5159

由于大多数计算时间似乎是对auc(roc(...))的调用,如果你有一台多核机器,这应该可以加快速度。

答案 2 :(得分:3)

cutpointr包中有这样做的功能。它还会计算分界点和其他指标,但您可以放弃它们。默认情况下,它会尝试除响应列之外的所有列作为预测变量。此外,您可以选择是否通过省略direction或手动设置ROC曲线的方向(无论较大值是否表示正类或相反)来自动确定。

dat <- iris[1:100, ]
library(tidyverse)
library(cutpointr)
mc <- multi_cutpointr(data = dat, class = "Species", pos_class = "versicolor", 
                silent = FALSE)
mc %>% select(variable, direction, AUC)

# A tibble: 4 x 3
  variable     direction   AUC
  <chr>        <chr>     <dbl>
1 Sepal.Length >=        0.933
2 Sepal.Width  <=        0.925
3 Petal.Length >=        1.00 
4 Petal.Width  >=        1.00  

顺便说一下,运行时不应该成为问题,因为计算ROC曲线(甚至包括一个切点)对于一个变量需要不到一秒钟,而使用cutpointr或{一百万个观测值{1}},所以你的任务大约需要一两分钟。

如果内存是限制因素,并行化可能会使问题变得更糟。如果上面的解决方案占用太多内存,因为它在删除这些列之前返回所有变量的ROC曲线,您可以尝试在调用ROCR时立即选择感兴趣的列:

map