Hanley's & McNeil'in 1982 yazısını, “ Alıcının çalışma karakteristiği (ROC) eğrisi altındaki alanın anlamı ve kullanımı ” makalesini tavsiye ederim .
Örnek
Bunlar aşağıdaki hastalık durumu ve test sonucuna sahiptir (örneğin bir lojistik modelden tahmin edilen riske karşılık gelir). Sağdaki ilk sayı, gerçek hastalık durumu 'normal' olan hasta sayısı ve ikinci sayı gerçek hastalık durumu 'anormal' olan hasta sayısıdır :
(1) Kesinlikle normal: 33/3
(2) Muhtemelen normal: 6/2
(3) Şüpheli: 6/2
(4) Muhtemelen anormal: 11/11
(5) Kesinlikle anormal: 2/33
Yani toplam 58 'normal' hasta ve '51' anormal hasta var. Öngörücü 1, 'Kesinlikle normal' olduğunda, hastanın genellikle normal olduğunu (36 hastanın 33'ünde gerçek) ve 5 olduğunda, 'Kesinlikle anormal' durumunun hastaların genellikle anormal olduğunu (33 (35 hasta), yani tahmin edici mantıklı. Fakat skoru 2, 3 veya 4 olan bir hastayı nasıl yargılamalıyız? Ortaya çıkan testin duyarlılığını ve özgüllüğünü belirlemek için hastaları anormal veya normal olarak değerlendirmek için sınırlarımızı belirledik.
Hassasiyet ve özgüllük
Farklı kesikler için tahmini hassasiyet ve özgüllüğü hesaplayabiliriz . (Bundan sonra, sadece değerlerin tahmini yapısının örtülü olmasını sağlayarak 'duyarlılık' ve 'özgüllük' yazacağım.)
Kesiktiğimizi seçersek, tüm hastaları anormal olarak sınıflandırırsak , test sonuçları ne olursa olsun (yani, kesikliği 1+ seçersek), 51/51 = 1 hassasiyetini alacağız. / 58 = 0. Kulağa hoş gelmiyor.
Tamam, daha az kesin bir kesim seçelim. Hastaları yalnızca 2 veya daha yüksek test sonuçlarına sahipse anormal olarak sınıflandırırız. Daha sonra 3 anormal hastayı özlüyoruz ve duyarlılığımız 48/51 = 0.94. Ancak, 33/58 = 0,57 olan çok fazla özgünlüğümüz var.
Şimdi çeşitli kesikler seçerek buna devam edebiliriz (3, 4, 5,> 5). (Son durumda, olası en yüksek 5 puanına sahip olsalar bile, hiçbir hastayı anormal olarak sınıflandırmayacağız .)
ROC eğrisi
Bunu tüm olası kesikler için yaparsak ve 1 eksi spesifikliğe karşı hassasiyeti işaretlersek, ROC eğrisini alırız. Aşağıdaki R kodunu kullanabiliriz:
# 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)) )
Çıktı:
testres
truestat 1 2 3 4 5
0 33 6 6 11 2
1 3 2 2 11 33
Çeşitli istatistikleri hesaplayabiliriz:
( 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
Ve bunu kullanarak, (tahmini) ROC eğrisini çizebiliriz:
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'yi manuel olarak hesaplama
Yamuk bölgesi formülü kullanılarak ROC eğrisi altındaki alanı kolayca hesaplayabiliriz:
height = (sens[-1]+sens[-length(sens)])/2
width = -diff(omspec) # = diff(rev(omspec))
sum(height*width)
Sonuç 0.8931711'dir.
Bir uyum ölçüsü
AUC ayrıca bir uyumluluk ölçüsü olarak da görülebilir. Birinin normal, diğerinin anormal olduğu tüm olası hasta çiftlerini alırsak, en yüksek (en 'anormal görünümlü') test sonucuna sahip anormal test sonucunun ne sıklıkta olduğunu hesaplayabiliriz (aynı değere sahipse, biz Bunu 'yarım zafer' olarak sayın):
o = outer(abnorm, norm, "-")
mean((o>0) + .5*(o==0))
Cevap yine ROC eğrisinin altındaki alan olan 0.8931711'dir. Bu her zaman böyle olacak.
Uyumun grafiksel bir görüntüsü
Harrell'in cevabında işaret ettiği gibi, bunun da grafik bir yorumu var. Şimdi y- ekseni üzerinde test puanını (risk tahmini) ve x- ekseni üzerindeki gerçek hastalık durumunu belirleyelim (burada bazı titremelerle, örtüşen noktaları göstermek için):
plot(jitter(truestat,.2), jitter(testres,.8), las=1,
xlab="True disease status", ylab="Test score")
Şimdi soldaki her nokta ('normal' bir hasta) ile sağdaki her nokta ('anormal' bir hasta) arasına bir çizgi çizelim. Pozitif eğimli çizgilerin oranı (yani uyumlu çiftlerin oranı ) uygunluk endeksidir (düz çizgiler '% 50 uygunluk' olarak sayılır).
Bu örnekteki gerçek çizgileri görselleştirmek biraz zor, çünkü ilişkilerin sayısı (eşit risk puanı), ancak biraz titizlik ve şeffaflık ile makul bir komplo elde edebiliriz:
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))
Çizgilerin çoğunun yukarı doğru eğimli olduğunu görüyoruz, bu nedenle uyum endeksi yüksek olacak. Ayrıca her bir gözlem çifti türünün endekse katkısını görüyoruz. Bunların çoğu, risk riski 5 olan (1-5 çift) anormal hastalarla eşleştirilmiş 1 risk skoru olan normal hastalardan gelirken, oldukça fazla da 1-4 ve 4-5 çift arasındadır. Eğim tanımına göre gerçek uyum indeksini hesaplamak çok kolaydır:
d = transform(d, slope=(y_norm-y_abnorm)/(x_norm-x_abnorm))
mean((d$slope > 0) + .5*(d$slope==0))
Cevap yine 0.8931711, yani AUC'dir.
Wilcoxon – Mann – Whitney testi
Uyum ölçüsü ile Wilcoxon-Mann-Whitney testi arasında yakın bir bağlantı var. Aslında sonuncusu, uyumluluk olasılığının (yani, en çok 'anormal görünümlü' test sonucuna sahip olacak rastgele normal-anormal bir çiftte anormal bir hasta olduğu ) test eder. Test istatistiği tahmin edilen uyumluluk olasılığının basit bir dönüşümüdür:
> ( 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
Test istatistiği ( W = 2642
), uygun çiftlerin sayısını sayar. Olası çift sayısına bölersek, familar bir sayı alırız:
w = wi$statistic
w/(length(abnorm)*length(norm))
Evet, ROC eğrisinin altındaki alan 0,8931711.
AUC'yi hesaplamanın daha kolay yolları (R cinsinden)
Ama hayatı kendimiz için kolaylaştıralım. AUC'yi bizim için otomatik olarak hesaplayan çeşitli paketler var.
Epi paketi
Epi
Paket gömülü (AUC dahil) çeşitli istatistikleri ile güzel ROC eğri oluşturur:
library(Epi)
ROC(testres, truestat) # also try adding plot="sp"
PROC paketi
Ayrıca pROC
paketi seviyorum , çünkü ROC tahminini pürüzsüzleştirebiliyor (ve düzleştirilmiş ROC'ye dayanarak bir AUC tahminini hesaplıyor):
(Kırmızı çizgi orijinal ROC ve siyah çizgi düzleştirilmiş ROC'dir. Ayrıca varsayılan 1: 1 en boy oranına dikkat edin. Hem duyarlılık hem de özgüllüğü 0-1 aralığına sahip olduğundan, bunu kullanmak mantıklı olur.)
Düzleştirilen ROC'den tahmin edilen AUC, düzleştirilmemiş ROC'den AUC'ye benzer, ancak biraz daha büyük olan 0.9107'dir (şekle bakarsanız, neden daha büyük olduğunu kolayca görebilirsiniz). (Pürüzsüz bir AUC hesaplamak için gerçekten çok az olası farklı test sonucu değerimiz olsa da).
Rms paketi
Harrell rms
paketi, rcorr.cens()
işlevi kullanarak ilgili çeşitli uygunluk istatistiklerini hesaplayabilir . C Index
Çıktıda AUC geçerli:
> library(rms)
> rcorr.cens(testres,truestat)[1]
C Index
0.8931711
CaTools paketi
Sonunda, caTools
pakete ve colAUC()
işlevine sahibiz . Bazen yardımcı ?colAUC
olabilecek diğer paketlere (çoğunlukla hız ve çok boyutlu verilerle çalışma yeteneği - bakınız ) göre birkaç avantajı vardır . Ama elbette, tekrar tekrar hesapladığımız aynı cevabı veriyor:
library(caTools)
colAUC(testres, truestat, plotROC=TRUE)
[,1]
0 vs. 1 0.8931711
Son sözler
Birçok insan AUC'nin bize bir testin ne kadar iyi olduğunu söylediğini düşünüyor gibi görünüyor. Bazı insanlar AUC'nin testin hastayı doğru şekilde sınıflandırması olasılığını düşünüyor. Öyle değil . Yukarıdaki örnekten ve hesaplamalardan görebileceğiniz gibi, AUC bize bir test ailesi hakkında , her olası kesim için bir test hakkında bir şeyler anlatır .
Ve AUC, pratikte asla kullanılmayacak olan kesimlere dayanarak hesaplanmaktadır. Neden 'saçma' kesme değerlerinin duyarlılığı ve özgüllüğünü önemsemeliyiz? Yine de, AUC'nin (kısmen) dayandığı şey budur. (Tabii ki, AUC 1'e çok yakınsa, mümkün olan her testin büyük bir ayırt edici gücü olacaktır ve hepimiz çok mutlu oluruz.)
AUC'nin 'rastgele normal-anormal' çifti yorumu güzeldir (ve örneğin en erken ölen en yüksek (göreceli) tehlikeye sahip olan kişi olup olmadığını görmek için hayatta kalma modellerine uzatılabilir). Ancak hiç kimse pratikte kullanmaz. Biri nadir durum bilen birine sahiptir birini sağlıklı ve bir hasta kişiyi hasta biri olan kişinin bilmediği ve tedavi etmek bunlardan hangileri karar vermelidir. (Her durumda, karar kolaydır; tahmini riski en yüksek olanı ele alın.)
Bu nedenle, gerçek ROC eğrisini incelemek sadece AUC özet ölçütüne bakmaktan daha faydalı olacağını düşünüyorum. ROC'yi , yanlış pozitiflerin ve yanlış negatiflerin maliyetleriyle (tahminlerini) birlikte kullanırsanız, okuduğunuz şeyin temel oranları ile birlikte, bir yere gidebilirsiniz.
Ayrıca, AUC'nin kalibrasyonu değil sadece ayrımcılığı ölçtüğünü unutmayın . Yani, risk puanına göre iki kişi (biri hasta diğeri sağlıklı) arasında ayrım yapıp yapamayacağınızı ölçer. Bunun için, sadece bakar göreceli risk değerlerine (ya da eğer sen Wilcoxon-Mann-Whitney testi yorumlama bakınız, rütbeleri) hangi değil mutlak olanlar gerektiğini ilgi duyun. Örneğin, her riski bölmek eğer Lojistik modelinizden 2 ile tahmin ederseniz, aynı AUC (ve ROC) elde edersiniz.
Bir risk modelini değerlendirirken, kalibrasyon da çok önemlidir. Bunu incelemek için, yaklaşık 0.7 gibi bir risk skoru olan tüm hastalara bakacak ve bunların yaklaşık% 70'inin gerçekten hasta olup olmadığını göreceksiniz. Bunu her olası risk puanı için yapın (muhtemelen bir çeşit düzleştirme / yerel regresyon kullanarak). Sonuçları çizdiğinizde, grafiksel bir kalibrasyon ölçümü elde edersiniz .
Hem iyi kalibrasyon hem de iyi ayrımcılığa sahip bir modeliniz varsa, iyi bir modeliniz olmaya başlar. :)