이진 로지스틱 회귀 모델의 수작업으로 곡선 아래 면적 (AUC) 또는 c- 통계량을 계산하는 데 관심이 있습니다.
예를 들어, 유효성 검사 데이터 집합에서 종속 변수에 대한 실제 값, 보존 (1 = 유지; 0 = 유지되지 않음)은 다음과 같은 모형을 사용하여 회귀 분석에 의해 생성 된 각 관측치의 예측 보존 상태를 갖습니다. 훈련 세트를 사용하여 작성됩니다 (0에서 1까지).
저의 초기 생각은 “정확한”모델 분류 수를 식별하고 “정확한”관측 수를 총 관측 수로 나누어 c- 통계량을 계산하는 것입니다. “정확한”기준, 관측치의 실제 보유 상태가 1이고 예측 된 보유 상태가> 0.5이면 “정확한”분류입니다. 또한 관측치의 실제 보유 상태 = 0이고 예측 된 보유 상태가 <0.5 인 경우 “정확한”분류이기도합니다. 예측 값이 0.5 일 때 “tie”가 발생한다고 가정하지만 유효성 검사 데이터 세트에서 해당 현상이 발생하지 않습니다. 반면, “정확하지 않은”분류는 관측치의 실제 보유 상태 = 1이고 예측 된 보유 상태가 <0 인 경우입니다. 5 또는 결과의 실제 보존 상태가 0이고 예측 보존 상태가> 0.5 인 경우. 나는 TP, FP, FN, TN을 알고 있지만이 정보가 주어지면 c 통계를 계산하는 방법을 알지 못합니다.
답변
Hanley ‘s & McNeil의 1982 년 논문 ‘ ROC (수신기 동작 특성) 곡선 아래 영역의 의미와 사용 ‘을 추천합니다.
예
다음과 같은 질병 상태 및 검사 결과 표가 있습니다 (예 : 물류 모델의 예상 위험에 해당). 오른쪽의 첫 번째 숫자는 실제 질병 상태가 ‘정상’인 환자의 수이고 두 번째 숫자는 실제 질병 상태가 ‘비정상’ 인 환자의 수입니다 .
(1) 확실히 정상 : 33/3
(2) 아마 정상 : 6/2
(3) 의심스러운 : 6/2
(4) 아마도 비정상 : 11/11
(5) 확실히 비정상 : 2/33
따라서 총 58 명의 ‘정상적인’환자와 ’51’의 비정상적인 환자가 있습니다. 예측 변수가 1, ‘정확히 정상’인 경우 환자는 일반적으로 정상이며 (36 명의 환자 중 33 명에 대해 참), 5 일 때 ‘확실히 비정상적인’환자는 일반적으로 비정상입니다 ( 35 명의 환자), 예측자가 의미가 있습니다. 그러나 2, 3 또는 4 점의 환자를 어떻게 판단해야합니까? 결과 검사의 민감도와 특이성을 결정하기 위해 환자를 비정상 또는 정상으로 판단하기 위해 컷오프를 설정했습니다.
감도와 특이성
다른 컷오프에 대한 추정 감도 및 특이도를 계산할 수 있습니다 . (이제부터는 ‘민감도’와 ‘특이성’을 작성하여 값의 추정 특성을 암시합니다.)
검사 결과에 상관없이 모든 환자를 비정상으로 분류하기 위해 컷오프를 선택하면 (즉, 컷오프 1+를 선택하더라도) 감도는 51/51 = 1이됩니다. 특이도는 0입니다. / 58 = 0. 소리가 잘 들리지 않습니다.
이제 덜 엄격한 컷오프를 선택하겠습니다. 검사 결과가 2 이상인 환자 만 비정상으로 분류합니다. 그런 다음 3 명의 비정상 환자를 그리워하고 48/51 = 0.94의 감도를 갖습니다. 그러나 우리는 33/58 = 0.57의 훨씬 더 높은 특이성을 가지고 있습니다.
이제 다양한 컷오프 (3, 4, 5,> 5)를 선택하여이 작업을 계속할 수 있습니다. (마지막으로, 우리는 가능한 가장 높은 시험 점수가 5 인 경우에도 환자를 비정상으로 분류 하지 않습니다 .)
ROC 곡선
가능한 모든 컷오프에 대해이 작업을 수행하고 1에서 특이성을 뺀 민감도를 플롯하면 ROC 곡선이 나타납니다. 다음과 같은 R 코드를 사용할 수 있습니다.
# Data
norm = rep(1:5, times=c(33,6,6,11,2))
abnorm = rep(1:5, times=c(3,2,2,11,33))
testres = c(abnorm,norm)
truestat = c(rep(1,length(abnorm)), rep(0,length(norm)))
# Summary table (Table I in the paper)
( tab=as.matrix(table(truestat, testres)) )
출력은 다음과 같습니다.
testres
truestat 1 2 3 4 5
0 33 6 6 11 2
1 3 2 2 11 33
다양한 통계를 계산할 수 있습니다.
( tot=colSums(tab) ) # Number of patients w/ each test result
( truepos=unname(rev(cumsum(rev(tab[2,])))) ) # Number of true positives
( falsepos=unname(rev(cumsum(rev(tab[1,])))) ) # Number of false positives
( totpos=sum(tab[2,]) ) # The total number of positives (one number)
( totneg=sum(tab[1,]) ) # The total number of negatives (one number)
(sens=truepos/totpos) # Sensitivity (fraction true positives)
(omspec=falsepos/totneg) # 1 − specificity (false positives)
sens=c(sens,0); omspec=c(omspec,0) # Numbers when we classify all as normal
이를 사용하여 (추정) ROC 곡선을 그릴 수 있습니다.
plot(omspec, sens, type="b", xlim=c(0,1), ylim=c(0,1), lwd=2,
xlab="1 − specificity", ylab="Sensitivity") # perhaps with xaxs="i"
grid()
abline(0,1, col="red", lty=2)
AUC 수동 계산
사다리꼴 면적에 대한 공식을 사용하여 ROC 곡선 아래 면적을 매우 쉽게 계산할 수 있습니다.
height = (sens[-1]+sens[-length(sens)])/2
width = -diff(omspec) # = diff(rev(omspec))
sum(height*width)
결과는 0.8931711입니다.
일치 측정
AUC는 또한 일치 측정으로 볼 수 있습니다. 우리는 모든 가능한 걸릴 경우 쌍 하나가 정상이고 다른 하나는 비정상이다 환자를, 우리는 (가장 높은 (가장 ‘비정상 보이는’)의 테스트 결과가 비정상 하나 빈도를 계산할 수 있습니다 그들은 같은 값이있는 경우, 우리 이것을 ‘승리의 절반’으로 세십시오).
o = outer(abnorm, norm, "-")
mean((o>0) + .5*(o==0))
답은 다시 ROC 곡선 아래 인 0.8931711입니다. 항상 그렇습니다.
일치의 그래픽보기
Harrell이 그의 답변에서 지적했듯이 이것은 그래픽으로 해석됩니다. y 축 에 대한 테스트 점수 (위험 추정치) 와 x 축 에 대한 실제 질병 상태 (여기서 약간의 지 터링이 있음)를 표시합니다.
plot(jitter(truestat,.2), jitter(testres,.8), las=1,
xlab="True disease status", ylab="Test score")
이제 왼쪽의 각 지점 ( ‘정상’환자)과 오른쪽의 각 지점 ( ‘비정상’환자) 사이에 선을 그리겠습니다. 양의 기울기를 가진 선의 비율 (즉, 일치 쌍 의 비율 )은 일치 지수 (평평한 선은 ’50 % 일치 ‘로 계산)입니다.
동점 수 (동일한 위험 점수)로 인해이 예제의 실제 선을 시각화하는 것은 약간 어렵지만 약간의 지 터링과 투명성을 통해 합리적인 플롯을 얻을 수 있습니다.
d = cbind(x_norm=0, x_abnorm=1, expand.grid(y_norm=norm, y_abnorm=abnorm))
library(ggplot2)
ggplot(d, aes(x=x_norm, xend=x_abnorm, y=y_norm, yend=y_abnorm)) +
geom_segment(colour="#ff000006",
position=position_jitter(width=0, height=.1)) +
xlab("True disease status") + ylab("Test\nscore") +
theme_light() + theme(axis.title.y=element_text(angle=0))
우리는 대부분의 선이 위쪽으로 기울어 짐에 따라 일치 지수가 높아질 것입니다. 또한 각 유형의 관측 쌍에서 지수에 대한 기여도를 볼 수 있습니다. 그것의 대부분은 위험 점수가 1 인 정상 환자와 위험 점수가 5 (1-5 쌍) 인 비정상 환자와 짝을 이루고 있지만, 1-4 쌍과 4-5 쌍에서도 상당히 많습니다. 그리고 경사 정의를 기반으로 실제 일치 지수를 계산하는 것은 매우 쉽습니다.
d = transform(d, slope=(y_norm-y_abnorm)/(x_norm-x_abnorm))
mean((d$slope > 0) + .5*(d$slope==0))
대답은 다시 0.8931711, 즉 AUC입니다.
Wilcoxon–Mann–Whitney 테스트
일치 측정과 Wilcoxon–Mann-Whitney 테스트 간에는 밀접한 관련이 있습니다. 실제로 후자는 일치 확률 (즉, 가장 ‘비정상적인’테스트 결과 를 갖는 임의의 정상-비정상 쌍 에서 비정상 환자 임을 확인)이 정확히 0.5인지 테스트합니다. 테스트 통계량은 추정 된 일치 성 확률의 간단한 변환 일뿐입니다.
> ( wi = wilcox.test(abnorm,norm) )
Wilcoxon rank sum test with continuity correction
data: abnorm and norm
W = 2642, p-value = 1.944e-13
alternative hypothesis: true location shift is not equal to 0
검정 통계량 ( W = 2642
)은 일치 쌍의 수를 계산합니다. 가능한 쌍의 수로 나누면 가족 수가 생깁니다.
w = wi$statistic
w/(length(abnorm)*length(norm))
예, ROC 곡선 아래 인 0.8931711입니다.
보다 쉬운 AUC 계산 방법 (R)
그러나 우리 자신을 위해 인생을 더 편하게합시다. 우리를 위해 자동으로 AUC를 계산하는 다양한 패키지가 있습니다.
Epi 패키지
이 Epi
패키지는 다양한 통계 (AUC 포함)가 포함 된 멋진 ROC 곡선을 만듭니다.
library(Epi)
ROC(testres, truestat) # also try adding plot="sp"
pROC 패키지
pROC
ROC 추정치를 매끄럽게 할 수 있고 (매끄러운 ROC를 기반으로 AUC 추정치를 계산할 수 있기 때문에) 패키지 도 좋아합니다 .
(빨간색 선은 원래 ROC이고 검은 색 선은 매끄럽게 된 ROC입니다. 기본 1 : 1 종횡비에 유의하십시오. 감도와 특이도는 모두 0-1 범위이므로이를 사용하는 것이 좋습니다.)
평활 ROC 의 추정 AUC 는 0.9107이며 평활 ROC의 AUC 와 비슷하지만 약간 더 큽니다 (그림을 보면 왜 더 큰지 쉽게 알 수 있습니다). (실제로 AUC를 계산할 수있는 고유 한 테스트 결과 값이 너무 적습니다).
rms 패키지
하렐의 rms
패키지는 사용하여 다양한 관련 용어 색인 통계를 계산할 수 있습니다 rcorr.cens()
기능. C Index
그 출력은 AUC이다 :
> library(rms)
> rcorr.cens(testres,truestat)[1]
C Index
0.8931711
caTools 패키지
마지막으로 caTools
패키지와 colAUC()
기능이 있습니다. 때로는 도움이 될 ?colAUC
수 있는 다른 패키지 (주로 속도 및 다차원 데이터 작업 기능 – 참조 )에 비해 몇 가지 장점 이 있습니다 . 그러나 물론 우리가 반복해서 계산 한 것과 같은 대답을 제공합니다.
library(caTools)
colAUC(testres, truestat, plotROC=TRUE)
[,1]
0 vs. 1 0.8931711
마지막 단어
많은 사람들이 AUC가 시험이 얼마나 ‘좋은’지를 말해 준다고 생각하는 것 같습니다. 그리고 어떤 사람들은 AUC가 검사가 환자를 올바르게 분류 할 확률이라고 생각합니다. 그것은이다 없습니다 . 위의 예와 계산에서 볼 수 있듯이 AUC는 가능한 각 컷오프마다 하나씩 테스트 패밀리 에 대해 알려줍니다 .
AUC는 실제로 사용하지 않는 컷오프를 기준으로 계산됩니다. ‘무의미한’차단 값의 민감도와 특이성에 관심을 가져야하는 이유는 무엇입니까? 여전히 AUC는 (부분적으로) 기반입니다. (물론 AUC가 1에 매우 가까우면 거의 모든 가능한 테스트에 큰 차별 력이 있으며, 우리는 모두 매우 행복 할 것입니다.)
AUC의 ‘무작위 정상-비정상’페어 해석은 훌륭합니다 (예를 들어 생존 모델로 확장 될 수 있으며, 여기서 가장 높은 (상대) 위험이있는 사람이 가장 빨리 사망하는지 확인). 그러나 실제로는 사용하지 않을 것입니다. 그것은 하나는 드문 경우입니다 알고 하나가 하나의 건강하고 하나 , 아픈 사람을 병 하나입니다 사람을 알고하지 않으며, 치료하는 그들의 결정해야합니다. (어쨌든 결정은 쉬우므로 추정 위험이 가장 높은 결정을 처리하십시오.)
따라서 실제 ROC 곡선을 연구하는 것이 AUC 요약 측정법을 보는 것보다 더 유용 하다고 생각 합니다. 그리고 ROC 를 오탐 (false positive) 및 오탐 (false negative ) 비용 (추정치) 과 함께 연구 대상의 기본 요율과 함께 사용하면 어딘가에 갈 수 있습니다.
또한 AUC는 교정이 아닌 차별 만 측정 합니다. 즉, 위험 점수에 따라 두 사람 (한 사람과 건강한 사람)을 구별 할 수 있는지 여부를 측정합니다. 이를 위해 관심 있는 절대 값이 아닌 상대 위험 값 (또는 윌 콕슨-맨-휘트니 테스트 해석 참조) 만 조사 합니다 . 예를 들어, 각 위험을 나누는 경우 로지스틱 모델에서 2를 추정하면 정확히 동일한 AUC (및 ROC)를 얻게됩니다.
위험 모델을 평가할 때는 교정 도 매우 중요합니다. 이를 검사하기 위해 위험 점수 (예 : 0.7)가있는 모든 환자를 살펴보고 이들 중 약 70 %가 실제로 아픈지 확인합니다. 가능한 모든 위험 점수에 대해이 작업을 수행하십시오 (일부 스무딩 / 로컬 회귀 분석 사용). 결과를 플롯하면 그래픽 보정 측정 값을 얻게 됩니다.
와 모델이있는 경우 모두 좋은 교정과 좋은 차별, 당신은 좋은 모델을 가지고 시작합니다.
답변
이 질문을 살펴보십시오 : ROC 곡선 이해
ROC 곡선을 만드는 방법은 다음과 같습니다.
ROC 곡선 그리기
순위 분류 기가 처리 한 데이터 세트
- 점수 감소에 대한 순위 테스트 예
- 에서 시작
이 알고리즘을 사용하여 다음 알고리즘을 사용하여 AUC ROC를 수동으로 계산할 수 있습니다.
auc = 0.0
height = 0.0
for each training example x_i, y_i
if y_i = 1.0:
height = height + tpr
else
auc = auc + height * fpr
return auc
이 멋진 gif 애니메이션 그림은이 과정을 명확하게 설명해야합니다.
답변
Karl의 게시물에는 훌륭한 정보가 많이 있습니다. 그러나 나는 지난 20 년 동안 누군가의 생각을 좋은 방향으로 바꾸는 ROC 곡선의 예를 아직 보지 못했습니다. 겸손한 견해에서 ROC 곡선의 유일한 가치는 그 영역이 매우 유용한 일치 확률과 같다는 것입니다. ROC 곡선 자체는 독자가 컷오프를 사용하도록 유혹합니다.
R Hmisc
패키지 rcorr.cens
기능의 경우 전체 결과를 인쇄하여 자세한 정보, 특히 표준 오류를보십시오.
답변
다음은 단순히 사다리꼴 규칙을 사용하여 ROC 곡선 아래 영역을 가져 와서 AUC를 계산하는 자연스러운 방법의 대안입니다.
AUC는 무작위로 샘플링 된 양성 관측치가 무작위로 샘플링 된 음성 관측치보다 예측 확률 (양수)이 클 확률과 같습니다. 이 기능을 사용하면 양성 및 음성 관측 값의 쌍별 조합을 통해 프로그래밍 언어에서 AUC를 매우 쉽게 계산할 수 있습니다. 표본 크기가 너무 큰 경우 관측치를 무작위로 표본 추출 할 수도 있습니다. 펜과 종이를 사용하여 AUC를 계산하려는 경우 샘플이 적거나 시간이 많지 않으면 이것이 최선의 방법이 아닐 수 있습니다. 예를 들어 R에서 :
n <- 100L
x1 <- rnorm(n, 2.0, 0.5)
x2 <- rnorm(n, -1.0, 2)
y <- rbinom(n, 1L, plogis(-0.4 + 0.5 * x1 + 0.1 * x2))
mod <- glm(y ~ x1 + x2, "binomial")
probs <- predict(mod, type = "response")
combinations <- expand.grid(positiveProbs = probs[y == 1L],
negativeProbs = probs[y == 0L])
mean(combinations$positiveProbs > combinations$negativeProbs)
[1] 0.628723
pROC
패키지를 사용하여 확인할 수 있습니다 .
library(pROC)
auc(y, probs)
Area under the curve: 0.6287
무작위 샘플링 사용 :
mean(sample(probs[y == 1L], 100000L, TRUE) > sample(probs[y == 0L], 100000L, TRUE))
[1] 0.62896
답변
- 관측 값에 대한 진정한 가치가 있습니다.
- 사후 확률을 계산 한 다음이 확률로 관측 값의 순위를 매 깁니다.