对ROC绘图进行优化的背后原理是什么?

时间:2019-03-15 02:39:14

标签: r algorithm optimization vector roc

我正在阅读this Rnews document from June 2004,第33页上的文章 Programmers'Niche 提供了一种绘制接收器工作特性曲线并对其进行优化的方法。

第一个代码段很简单,并且与定义一致

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的结果是正确的(请参阅下面的答案),但是我仍然不知道性能的显着提高来自何处...

1 个答案:

答案 0 :(得分:0)

我想我已经知道了。 DD <- table(-T, D)的意思是按相反的顺序执行累加和,这是因为我们正在计算Pr(T> c),而表的累加和正在计算T中小于或等于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)操作来建立表和所有后续操作操作成本很高。