r - 这种优化 ROC 绘图的基本原理是什么?
问题描述
我正在阅读2004 年 6 月的 Rnews 文档,第 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 画在一起,看看结果是否一样。
左边的情节是由产生的,drawROC.A
而右边的情节是 的结果drawROC.B
。乍一看,它们并不完全相同,但如果仔细观察,Y轴的范围是不同的,所以它们实际上是同一个图。
编辑:
现在我已经明白什么drawROC.B
是正确的结果了(见下面我的回答),但我仍然不知道显着的性能提升来自哪里......
解决方案
我想我已经想通了。这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)
操作来构建表,并且所有后续操作都一样昂贵。
推荐阅读
- bison - 野牛难悬垂的其他去除
- angular - ng alain 将 2 个自定义小部件并排放置
- vue.js - vue-i18n 抛出错误“无法读取未定义的属性(读取'hasOwnProperty')”
- java - 使用 Gradle 构建 .jar,在线程“main”java.lang.NoClassDefFoundError 中执行 .jar local throws Exception
- reactjs - React无法解构'this.props.match'的属性'params',因为它是未定义的
- javascript - 如何简化 Wix 中 Mega Menu 的代码,以填充由一个主菜单中的按钮过滤的类别?
- hl7-fhir - 如何使用 Hl7.Fhir.Rest 客户端搜索 HealthCareService 的
- c - 如果 y==0,如何让 C 接受
- javascript - 基于彼此同时对两个数组进行排序
- r - 如何在 R 中排除 group_by 中的值