Я читаю этот документ Rnews за июнь 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, созданный двумя функциями вместе, чтобы проверить, совпадают ли результаты.
Левый график получается drawROC.A
, тогда как правый - результат drawROC.B
.На первый взгляд, они не идентичны, но если присмотреться, диапазон оси Y отличается, поэтому они на самом деле представляют собой один и тот же график.
Редактировать:
Теперь я понял, что результат drawROC.B
правильный (см. Мой ответ ниже), но я до сих пор не представляю, откуда происходит существенное повышение производительности ...