I olen kiinnostunut laskemaan käyrän alapuolisen alueen (AUC) tai c-tilaston käsin binäärilogistista regressiomallia varten.

Esimerkiksi validointiaineistolla minulla on todellinen arvo riippuvaiselle muuttujalle, retentio (1 = säilytetty; 0 = ei säilytetty), samoin kuin ennustettu retentio-tila jokaiselle havainnolle, joka on tuotettu regressioanalyysillä käyttäen mallia, joka on rakennettu koulutuksen avulla set (tämä vaihtelee 0: sta 1: een).

Aluksi ajatukseni oli tunnistaa malliluokitusten ”oikea” lukumäärä ja jakaa yksinkertaisesti ”oikeiden” havaintojen määrä laskettavien havaintojen kokonaismäärällä. c-tilasto. ”Oikealla”, jos havainnon todellinen retentio = 1 ja ennustettu retentio on> 0,5, se on ”oikea” luokitus. Lisäksi, jos havainnon todellinen retentio-tila = 0 ja ennustettu retentio-tila on < 0,5, niin se on myös ”oikea” luokitus. Oletan, että ”tasapeli” tapahtuisi, kun ennustettu arvo = 0,5, mutta kyseistä ilmiötä ei esiinny validointitiedostoissani. Toisaalta ”virheelliset” luokitukset olisivat, jos havainnon todellinen säilyvyys = 1 ja ennustettu säilytystila on < 0,5 tai jos lopputuloksen todellinen säilytystila = 0 ja ennustettu retentio-tila on> 0,5. Olen tietoinen TP: stä, FP: stä, FN: stä, TN: stä, mutta en ole tietoinen siitä, miten c-tilasto lasketaan näiden tietojen perusteella.

Vastaa

Suosittelisin Hanleyn & McNeilin vuoden 1982 paperia Vastaanottimen toimintaominaisuuden (ROC) alla olevan alueen merkitys ja käyttö ) käyrä .

Esimerkki

Heillä on seuraava taudin tilan ja testitulosten taulukko (vastaa esimerkiksi logistisen mallin arvioitua riskiä). Ensimmäinen numero oikealla on niiden potilaiden määrä, joilla todellinen taudin tila on normaali, ja toinen luku on niiden potilaiden lukumäärä, joilla todellinen taudin tila on poikkeava:

(1) Ehdottomasti normaali: 33/3
(2) Todennäköisesti normaali: 6/2
(3) Kyseenalainen: 6/2
(4) Todennäköisesti epänormaali: 11/11
(5) Ehdottomasti epänormaali: 2/33

Joten kaikkiaan 58 normaalia ja 51 poikkeavaa potilasta. Näemme, että kun ennustaja on 1, ehdottomasti normaali, potilas on yleensä normaali (totta 33 potilaasta 36 potilaasta) ja kun se on 5, ehdottomasti epänormaali, potilaat ovat yleensä poikkeavia (totta 33 potilaasta). 35 potilasta), joten ennustaja on järkevä. Mutta kuinka meidän pitäisi arvioida potilasta, jonka pisteet ovat 2, 3 tai 4? Se, mitä asetimme raja-arvolle potilaan arvioimiseksi epänormaaliksi tai normaaliksi, määrittää saadun testin herkkyyden ja spesifisyyden.

Herkkyys ja spesifisyys

Voimme laskea arvioidun herkkyys ja spesifisyys eri raja-arvoille. (Kirjoitan tästä lähtien vain ”herkkyys” ja ”spesifisyys”, jolloin arvojen arvioitu luonne on implisiittinen.)

Jos valitsemme raja-arvon niin, että luokitellaan kaikki potilaat epänormaaleina, riippumatta siitä, mitä testitulokset sanovat (eli valitsemme raja-arvon 1+), herkkyys on 51/51 = 1. Spesifisyys on 0/58 = 0. Eikö kuulostaa niin hyvältä.

OK, joten valitaan vähemmän tiukka raja. Me luokitamme potilaat poikkeaviksi vain, jos testitulos on vähintään 2. Meiltä puuttuu 3 epänormaalia potilasta, ja herkkyytemme on 48/51 = 0,94. Mutta meillä on paljon lisääntynyt spesifisyys, 33/58 = 0,57.

Voimme nyt jatkaa tätä valitsemalla erilaisia raja-arvoja (3, 4, 5,> 5). (Viimeisessä tapauksessa emme luokittele yhtään potilasta epänormaaliksi, vaikka heillä olisi korkein mahdollinen testipiste 5.)

ROC-käyrä

Jos teemme tämän kaikkien mahdollisten raja-arvojen suhteen ja piirrämme herkkyyden 1: een miinus spesifisyys, saadaan ROC-käyrä. Voimme käyttää seuraavaa R-koodia:

 # 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)) )  

Lähtö on:

  testres truestat 1 2 3 4 5 0 33 6 6 11 2 1 3 2 2 11 33  

Voimme laskea erilaisia tilastoja:

 ( 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  

Ja tätä käyttämällä voimme piirtää (arvioidun) ROC-käyrän:

 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-käyrä

Lasketaan manuaalisesti AUC

Voimme helposti laskea ROC-käyrän alla olevan alueen käyttämällä trapetsin pinta-alan kaavaa:

 height = (sens[-1]+sens[-length(sens)])/2 width = -diff(omspec) # = diff(rev(omspec)) sum(height*width)  

Tulos on 0.8931711.

Vastaavuusmitta

AUC voidaan nähdä myös yhdenmukaistamismittana.Jos otamme kaikki mahdolliset parit potilaita, joissa toinen on normaali ja toinen epänormaali, voimme laskea, kuinka usein epänormaalilla on korkein (eniten ”epänormaalin näköinen”) testitulos (jos niillä on sama arvo, laskemme tämän olevan puoli voitto):

 o = outer(abnorm, norm, "-") mean((o>0) + .5*(o==0))  

Vastaus on jälleen 0.8931711, ROC-käyrän alla oleva alue. Näin on aina.

Graafinen näkymä yhdenmukaisuudesta

Kuten Harrell huomautti vastauksessaan, tällä on myös graafinen tulkinta. Piirretään testitulos (riskiarvio) y -akselista ja todellisesta taudin tilasta x -akselista (tässä on jonkin verran tärinää, jotta voidaan näyttää päällekkäisiä pisteitä):

 plot(jitter(truestat,.2), jitter(testres,.8), las=1, xlab="True disease status", ylab="Test score")  

Hajota riskitulos reaalista tautia vastaan tila.

Piirretään nyt viiva vasemmanpuoleisen pisteen (”normaali” potilas) ja oikeanpuoleisen pisteen (”epänormaali” potilas) välille. Positiivisen kaltevuuden viivojen osuus (ts. vastaavien parien osuus) on vastaavuusindeksi (tasaiset viivat lasketaan 50%: n vastaavuudeksi).

Tämän esimerkin varsinaisten rivien visualisointi on hieman vaikeaa johtuen siteiden lukumäärästä (sama riskipiste), mutta jonkin verran värisemällä ja läpinäkyvyydellä voimme saada kohtuullisen juonen:

 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))  

Hajota riskipisteiden diagrammi taudin todellisen tilan mukaan viivat kaikkien mahdollisten havainnointiparien välillä.

Näemme, että suurin osa linjoista kallistuu ylöspäin, joten vastaavuusindeksi on korkea. Näemme myös jokaisen havaintoparin tyypin vaikutuksen indeksiin. Suurin osa siitä tulee normaaleilta potilailta, joiden riskipisteet ovat 1, yhdistettynä epänormaaleihin potilaisiin, joiden riskipisteet ovat 5 (1–5 paria), mutta melko paljon tulee myös 1–4 parista ja 4–5 parista. Ja todellisen vastaavuusindeksin laskeminen kaltevuusmäärityksen perusteella on erittäin helppoa:

 d = transform(d, slope=(y_norm-y_abnorm)/(x_norm-x_abnorm)) mean((d$slope > 0) + .5*(d$slope==0))  

Vastaus on jälleen 0.8931711, ts. AUC.

Wilcoxon – Mann – Whitney -testi

Vastaavuusmittauksen ja Wilcoxon – Mann – Whitney -laitteen välillä on läheinen yhteys. testata. Itse asiassa jälkimmäinen testaa, onko yhdenmukaisuuden todennäköisyys (eli että epänormaalilla potilaalla satunnainen normaali-epänormaali pari saa eniten ”epänormaalin näköisen” testituloksen) 0,5. Ja sen testitilasto on vain yksinkertainen muunnos arvioidusta vastaavuuden todennäköisyydestä:

 > ( 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  

Testitilasto (W = 2642) laskee samanaikaisten parien määrän. Jos jaamme sen mahdollisten parien määrällä, saamme kuuluisan numeron:

 w = wi$statistic w/(length(abnorm)*length(norm))  

Kyllä, se on 0.8931711, ROC-käyrän alla oleva pinta-ala.

Helpompia tapoja laskea AUC (R-kirjaimina)

Mutta helpottakaamme elämäämme itsellemme. On olemassa useita paketteja, jotka laskevat AUC: n meille automaattisesti.

Epi-paketti

Paketti Epi luo mukavan ROC-käyrän erilaisilla upotetut tilastot (mukaan lukien AUC):

 library(Epi) ROC(testres, truestat) # also try adding plot="sp"  

ROC-käyrä Epi-paketista

pROC-paketti

Pidän myös pROC -paketista, koska se voi tasoita ROC-estimaatti (ja laske AUC-estimaatti tasoitetun ROC: n perusteella):

ROC-käyrä (tasoittamaton ja tasoitettu) pROC-paketista

(Punainen viiva on alkuperäinen ROC ja musta viiva on tasoitettu ROC. Huomaa myös oletussuhde 1: 1. On järkevää käyttää tätä, koska sekä herkkyydellä että spesifisyydellä on 0–1 alue.)

Arvioitu AUC tasoitetusta ROC: sta on 0,9107, samanlainen mutta hieman suurempi kuin tasoittamattoman ROC: n AUC (jos katsot Kuvasta näet helposti, miksi se on suurempi). (Vaikka meillä onkin liian vähän mahdollisia erillisiä testitulosarvoja sujuvan AUC: n laskemiseksi).

RMS-paketti

Harrellin rms -paketti osaa laskea erilaisia siihen liittyviä konkordanssitilastoja funktion rcorr.cens() avulla. Lähdön C Index on AUC:

 > library(rms) > rcorr.cens(testres,truestat)[1] C Index 0.8931711  

caTools-paketti

Lopuksi meillä on paketti caTools ja sen funktio colAUC(). Sillä on muutamia etuja muihin paketteihin verrattuna (lähinnä nopeus ja kyky työskennellä moniulotteisen datan kanssa – katso ?colAUC), joista voi joskus olla hyödyllistä .Mutta tietysti se antaa saman vastauksen, jonka olemme laskeneet yhä uudelleen:

 library(caTools) colAUC(testres, truestat, plotROC=TRUE) [,1] 0 vs. 1 0.8931711  

ROC-käyrä caTools-paketista

Viimeiset sanat

Monet ihmiset näyttävät ajattelevan, että AUC kertoo meille kuinka hyvä testi on. Ja jotkut ihmiset ajattelevat, että AUC on todennäköisyys, että testi luokittelee potilaan oikein. Se ei ole ei . Kuten yllä olevasta esimerkistä ja laskelmista näet, AUC kertoo meille jotain testiperheestä , yhden testin jokaiselle mahdolliselle raja-arvolle.

Ja AUC lasketaan raja-arvoja, joita ei koskaan käytettäisi käytännössä. Miksi meidän pitäisi välittää ”järjettömien” raja-arvojen herkkyydestä ja spesifisyydestä? Silti siihen AUC perustuu (osittain). (Tietenkin, jos AUC on hyvin lähellä arvoa 1, melkein kaikilla mahdollisilla testeillä on suuri syrjivä voima, ja me kaikki olisimme erittäin onnellisia.)

Satunnainen normaali – epänormaali AUC-paritulkinta on mukava (ja se voidaan laajentaa esimerkiksi selviytymismalleihin, joissa näemme, kuoleeko aikaisintaan korkeimman (suhteellisen) vaaran omaava henkilö). Mutta sitä ei koskaan käytettäisi käytännössä. Se on harvinainen tapaus, jossa tietää hänellä on yksi terve ja yksi sairas henkilö, hän ei tiedä mikä henkilö on sairas, ja hänen on päättää kumpi heistä hoitaa. (Joka tapauksessa päätös on helppo; kohtele sitä, jolla on suurin arvioitu riski.)

Joten mielestäni todellisen ROC-käyrän tutkiminen on hyödyllisempää kuin vain tarkastelemalla AUC-yhteenvetotoimenpide. Ja jos käytät ROC-arvoa yhdessä (väärien positiivisten ja väärien negatiivisten) kustannusten kanssa sekä opiskelemiesi perusasteiden kanssa, voit päästä jonnekin.

Huomaa myös, että AUC mittaa vain erottelua , ei kalibrointia. Toisin sanoen se mittaa, pystytkö erottamaan kaksi henkilöä (yhden sairaan ja toisen terveellisen) riskipisteiden perusteella. Tätä varten se tarkastelee vain suhteellisia riskiarvoja (tai rivejä, jos haluat, vrt. Wilcoxon – Mann – Whitney -testitulkinta), ei absoluuttisia, joita pitäisi olla kiinnostunut. Jos esimerkiksi jaat jokaisen riskiarvion logistisesta mallistasi kahdella, saat täsmälleen saman AUC: n (ja ROC).

Kun arvioit riskimallia, kalibrointi on myös erittäin tärkeä. Tämän tutkimiseksi tarkastellaan kaikkia potilaita, joiden riskipisteet ovat noin, esimerkiksi 0,7, ja näet, olivatko noin 70% näistä todella sairaita. Tee tämä jokaiselle mahdolliselle riskipisteelle (mahdollisesti käyttämällä jonkinlaista tasoitusta / paikallista regressiota). Piirrä tulokset ja saat graafisen mittasuhteen kalibroinnista .

Jos sinulla on malli, jossa molemmat hyvä kalibrointi ja hyvä erottelu, alkaa olla hyvä malli. 🙂

Kommentit

  • Kiitos, @Karl Ove Hufthammer, tämä on perusteellisin vastaus, jonka olen koskaan saanut. Arvostan erityisesti ” loppusanat ” -osi. Erinomaista työtä! Kiitos vielä kerran!
  • Paljon kiitoksia tästä yksityiskohtaisesta vastauksesta. Työskentelen tietojoukon kanssa, jossa Epi :: ROC () v2.2.6 on vakuuttunut siitä, että AUC on 1,62 (ei se ei ole mentalistinen tutkimus), mutta ROC: n mukaan uskon paljon enemmän 0,56: een, jonka yllä oleva koodi tuottaa sisään.
  • Luulen, että sens=c(sens,0); omspec=c(omspec,0) -ohjelmassa on pieni virhe, ei ’ t tämän pitäisi olla sens=c(0, sens); omspec=c(0, omspec)? Se piirtää oikein etusivun 0 kanssa, mutta ei tällä hetkellä vastauksessa.
  • Ei, nykyinen määritelmä on AFAICS, correct, @steveb, ja tuloksena on oikea juoni. Mielestäni hämmentävää on ehkä se, että ROC-käyrä piirretään oikealta vasemmalle (ts. Oikeasta yläkulmasta vasempaan alakulmaan), ei vasemmalta oikein , kuten useimmat juoni ovat. Tämä on vain tulos siitä, miten määritin muuttujat; yhtä hyvin olisi voitu piirtää se vasemmalta oikealle (kääntämällä sens ja omspec ennen piirtämistä).

Vastaus

Katsokaa tätä kysymystä: ROC-käyrän ymmärtäminen

ROC-käyrän rakentaminen (tästä kysymyksestä):

ROC-käyrän piirtäminen

antaa käyttäjän käsittelemän tietojoukon sijoituksen luokittelija

  • sijoituskoe-esimerkit laskevasta pisteestä
  • alkavat $ (0, 0) $: sta
  • jokaisesta esimerkistä $ x $ laskeva järjestys)
    • jos $ x $ on positiivinen, siirrä $ 1 / \ text {pos} $ ylöspäin
    • jos $ x $ on negatiivinen, siirrä $ 1 / \ text {neg} $ oikealle

missä $ \ text {pos} $ ja $ \ text {neg} $ ovat vastaavien positiivisten ja negatiivisten esimerkkien murto-osia.

Voit käyttää tätä ajatusta AUC ROC: n manuaaliseen laskemiseen seuraavaa algoritmia käyttäen:

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 

Tämän hienon gif-animoidun kuvan tulisi havainnollistaa tätä prosessin selkeämpi

käyrän rakentaminen

kommentit

  • kiitos @Alexey Grigorev, tämä on hieno visuaalinen ja se todennäköisesti osoittautuu hyödylliseksi tulevaisuudessa! +1
  • Voisitteko selittää hieman ” positiivisten ja negatiivisten esimerkkien murtoluvuista ”, tarkoitatteko kahden akselin pienin yksikköarvo?
  • @Allan Ruin: pos tarkoittaa tässä positiivisten tietojen määrää. Sanotaan, että sinulla on 20 datapistettä, joista 11 pistettä on 1. Joten kaaviota piirrettäessä meillä on suorakulmio 11×9 (korkeus x leveys). Alexey Grigorev skaalasi, mutta vain antoi sen ’ s, jos haluat. Siirrä nyt vain 1 kaaviossa kussakin vaiheessa.

Vastaa

Karlin viestissä on paljon Mutta en ole vielä 20 viime vuoden aikana nähnyt esimerkkiä ROC-käyrästä, joka muutti kenenkään ajattelua hyvään suuntaan. Ainoa arvo ROC-käyrälle nöyrän mielestäni on, että sen pinta-ala sattuu yhtä suureksi kuin hyödyllinen konkordanssitodennäköisyys. Itse ROC-käyrä houkuttelee lukijaa käyttämään raja-arvoja, mikä on huonoa tilastokäytäntöä.

Laskemaan $ c $ -indexin manuaalisesti juoni, jossa $ Y = 0,1 $ on $ x $ -akseli ja jatkuva ennustaja tai ennustettu todennäköisyys, että $ Y = 1 $ $ y $ -akselilla. Jos yhdistät jokaisen pisteen $ Y = 0 $: lla jokaiseen pisteeseen, jonka $ Y = 1 $, positiivisen kaltevuuden viivojen osuus on vastaavuustodennäköisyys.

Kaikki mittarit, joiden nimittäjä on $ n $ tässä asetuksessa ovat virheellisiä tarkkuuden pisteytyssääntöjä ja niitä tulisi välttää. Tämä sisältää oikein luokitellun osuuden, herkkyyden ja spesifisyyden.

Tulosta R Hmisc -paketti rcorr.cens -toiminto koko tulos nähdäksesi lisätietoja, varsinkin tavallisen virheen.

Kommentit

  • Kiitos, @Frank Harell, kiitän näkökulmastasi. Käytän yksinkertaisesti c-tilastoa konkordanssitodennäköisyydenä, koska en pidä leikkauksista ’. Kiitos vielä kerran!

Vastaa

Tässä on vaihtoehto luonnolliselle AUC-laskentatavalle yksinkertaisesti käyttämällä trapetsia sääntö saada alue ROC-käyrän alle.

AUC on yhtä suuri kuin todennäköisyys, että satunnaisesti otetulla positiivisella havainnolla on ennustettu todennäköisyys (olla positiivinen) suurempi kuin satunnaisesti otetusta negatiivisesta havainnosta. Voit käyttää tätä laskeaksesi AUC: n melko helposti millä tahansa ohjelmointikielellä käymällä läpi kaikki parin yhdistelmät positiivisia ja negatiivisia havaintoja. Voit myös ottaa satunnaisesti otoksia havainnoista, jos otoksen koko on liian suuri. Jos haluat laskea AUC: n kynällä ja paperilla, tämä ei ehkä ole paras tapa, ellei sinulla ole hyvin pieni näyte / paljon aikaa. Esimerkiksi R: ssä:

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 

Voimme varmistaa käyttämällä pROC -pakettia:

library(pROC) auc(y, probs) Area under the curve: 0.6287 

Satunnaisotannan käyttäminen:

mean(sample(probs[y == 1L], 100000L, TRUE) > sample(probs[y == 0L], 100000L, TRUE)) [1] 0.62896 

vastaus

  1. Sinulla on todellinen arvo havainnoille.
  2. Laske takimmainen todennäköisyys ja sijoita sitten havainnot tämän todennäköisyyden mukaan.
  3. Oletetaan $ P $: n raja-todennäköisyys ja havaintojen lukumäärä $ N $:
    $$ \ frac {\ text {Todellisten riveiden summa} -0,5PN (PN + 1)} { PN (N-PN)} $$

kommentit

  • @ user73455 … 1) Kyllä, minulla on todellinen arvo havaintoja varten. 2) Onko takaosan todennäköisyys synonyymi ennustettujen todennäköisyyksien kanssa jokaiselle havainnolle? 3) Ymmärretty; mikä on kuitenkin ” todellisten riveiden summa ” ja miten tämä arvo lasketaan? Ehkä esimerkki auttaisi sinua selittämään vastauksen perusteellisemmin? Kiitos!

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *