ROC绘图优化背后的理由是什么?

问题描述 投票:2回答:1

我正在阅读this Rnews document from June 2004,第33页的文章程序员利基提出了一种绘制接收器操作特性曲线和优化的方法。

第一个代码片段是微不足道的,与定义一致

drawROC.A <- function(T, D) {
    cutpoints <- c(-Inf, sort(unique(T)), Inf)
    sens <- sapply(cutpoints,
                   function(c) sum(D[T>c])/sum(D))
    spec <- sapply(cutpoints,
                   function(c) sum((1-D)[T<=c]/sum(1-D)))

    plot(1-spec, sens, type = "l")
}

然后作者说(我的编辑很少),

有一个相对简单的函数优化,大大提高了速度,但代价是要求T为数字,而不仅仅是定义><=的对象

drawROC.B <- function(T, D){
  DD <- table(-T, D)
  sens <- cumsum(DD[ ,2]) / sum(DD[ ,2])
  mspec <- cumsum(DD[ ,1]) / sum(DD[ ,1])

  plot(mspec, sens, type="l")
}

我花了很长时间阅读优化版本,但卡在第一行:它看起来像-之前的负号T用于以相反的顺序执行累积总和,但为什么呢?

混淆了,我把两个函数产生的ROC绘制在一起,检查结果是否相同。

enter image description here

左图由drawROC.A产生,而右图是drawROC.B的结果。乍一看,它们并不完全相同,但如果你仔细观察,Y轴的范围是不同的,所以它们实际上是相同的图。

编辑:

现在我已经明白了drawROC.B的结果是正确的(参见下面的答案),但我仍然不知道实质性的性能提升来自哪里......

r algorithm optimization vector roc
1个回答
0
投票

我想我已经搞清楚了。 DD <- table(-T, D)意味着以相反的顺序执行累积和,这是因为我们正在计算Pr(T> c),而表的累积和正在计算T中小于或等于当前的元素数量元件。

换句话说,这也可以,因为Pr(T> c)= 1 - Pr(T <= c)。

drawROC.B <- function(T, D){
  DD <- table(T, D)
  sens <- 1 - cumsum(DD[ ,2])/sum(DD[ ,2])
  mspec <- 1 - cumsum(DD[ ,1])/sum(DD[ ,1])

  plot(mspec, sens, type="l")
}

顺便说一句,您可以使用它将两点(0,0)和(1,1)添加到drawROC.B的结果中。

drawROC.C <- function(T, D){
  DD <- table(-T, D)
  sens <- c(0, cumsum(DD[ ,2])/sum(DD[ ,2]), 1)
  mspec <- c(0, cumsum(DD[ ,1])/sum(DD[ ,1]), 1)

  plot(mspec, sens, type="l")
}

至于性能增益,请注意drawROC.A需要执行(渐近)unique(T) * length(T)比较,而drawROC.A只需要length(T)操作来构建一个表,所有后续操作都是昂贵的。

© www.soinside.com 2019 - 2024. All rights reserved.