Slik beregner du konfidensintervaller for ytelsesmålinger i maskinlæring ved hjelp av en automatisk oppstartsmetode

Kilde node: 1178501

Slik beregner du konfidensintervaller for ytelsesmålinger i maskinlæring ved hjelp av en automatisk oppstartsmetode

Er modellytelsesmålingene dine veldig presise på grunn av et "stort" testsett, eller veldig usikkert på grunn av et "lite" eller ubalansert testsett?


By David B Rosen (PhD), Lead Data Scientist for Automated Credit Approval hos IBM Global Financing



Den oransje linjen viser 89.7 % som nedre grense for konfidensintervallet for balansert nøyaktighet, grønn for den opprinnelige observerte balanserte nøyaktigheten = 92.4 % (punktestimat), og rød for øvre grense på 94.7 %. (Dette og alle bildene er av forfatteren med mindre annet er angitt.)

Introduksjon

 
 
Hvis du rapporterer at klassifisererens ytelse har Nøyaktighet=94.8 % og F1=92.3 % på et testsett, betyr ikke dette mye uten å vite noe om størrelsen og sammensetningen av testsettet. Feilmarginen til disse ytelsesmålingene vil variere mye avhengig av størrelsen på testsettet, eller, for et ubalansert datasett, først og fremst avhengig av hvor mange uavhengige forekomster av minoritet klasse den inneholder (flere kopier av de samme forekomstene fra oversampling hjelper ikke for dette formålet).

Hvis du var i stand til å samle inn et annet, uavhengig testsett med lignende opprinnelse, er det usannsynlig at nøyaktigheten og F1 til modellen din på dette datasettet er den samme, men hvor mye forskjellig kan de være? Et spørsmål som ligner på dette besvares i statistikken som konfidensintervall av målingen.

Hvis vi skulle trekke mange uavhengige utvalgsdatasett fra den underliggende populasjonen, ville den sanne underliggende populasjonsverdien til metrikken for 95 % av disse datasettene være innenfor 95 % konfidensintervallet som vi ville beregnet for det aktuelle utvalgsdatasettet.

I denne artikkelen vil vi vise deg hvordan du beregner konfidensintervaller for et hvilket som helst antall maskinlæringsytelsesmålinger samtidig, med en bootstrap-metode som automatisk bestemmer hvor mange oppstartseksempeldatasett som skal genereres som standard.

Hvis du bare vil se hvordan du aktiverer denne koden for å beregne konfidensintervaller, hopp til delen "Beregn resultatene!" nedenfor.

Bootstrap-metodikken

 
 
Hvis vi var i stand til å trekke flere testdatasett fra den sanne distribusjonen som ligger til grunn for dataene, ville vi kunne se fordelingen av ytelsesberegningen(e) av interesse på tvers av disse datasettene. (Når vi tegner disse datasettene, ville vi ikke gjøre noe for å forhindre å tegne en identisk eller lignende forekomst flere ganger, selv om dette kanskje bare skjer sjelden.)

Siden vi ikke kan gjøre det, er det nest beste å tegne flere datasett fra empirisk fordeling av dette testdatasettet, som betyr sampling, med erstatning, fra dets forekomster for å generere nye bootstrap-eksempeldatasett. Sampling med erstatning betyr at når vi først har tegnet en bestemt forekomst, setter vi den inn igjen slik at vi kan tegne den igjen for det samme prøvedatasettet. Derfor har hvert slikt datasett generelt flere kopier av noen av forekomstene, og inkluderer ikke alle forekomstene som er i basistestsettet.

Hvis vi samplet uten erstatning, så ville vi ganske enkelt få en identisk kopi av det originale datasettet hver gang, blandet i en annen tilfeldig rekkefølge, noe som ikke ville være til noen nytte.

De persentil bootstrap-metodikk for å estimere konfidensintervallet er som følger:

  1. Generere nboots «bootstrap sample»-datasett, hver i samme størrelse som det originale testsettet. Hvert prøvedatasett oppnås ved å trekke instanser tilfeldig fra testsettet med erstatning.
  2. Beregn beregningen på hvert av prøvedatasettene og lagre den.
  3. 95 % konfidensintervall er gitt av 2.5th til 97.5th persentil blant nboots beregnede verdier av metrikken. Hvis nboots=1001 og du sorterte verdiene i en serie/matrise/liste X av lengde 1001, 0th persentil er X[0] og de 100th persentil er X[1000], så konfidensintervallet vil bli gitt av X[25] til X[975].

Selvfølgelig kan du beregne så mange beregninger du vil for hvert eksempeldatasett i trinn 2, men i trinn 3 vil du finne persentilene for hver beregning separat.

Eksempeldatasett og konfidensintervallresultater

 
 
Vi vil bruke resultater fra denne forrige artikkelen som et eksempel: Hvordan håndtere ubalansert klassifisering, uten å balansere dataeneFør du vurderer å oversample de skjeve dataene dine, kan du prøve å justere terskelen for klassifiseringsbeslutning.

I den artikkelen brukte vi svært-ubalansert to-klasser Kaggle identifikasjonsdatasett for kredittkortsvindel. Vi valgte å bruke en klassifiseringsterskel som er ganske forskjellig fra standard 0.5-terskelen som er implisitt i bruk av predict()-metoden, noe som gjør det unødvendig å balansere dataene. Denne tilnærmingen kalles noen ganger terskelen beveger seg, der klassifisereren vår tildeler klassen ved å bruke den valgte terskelen på den predikerte klassesannsynligheten gitt av prediksjonen_proba() metode.

Vi vil begrense omfanget av denne artikkelen (og koden) til binær klassifisering: klasse 0 og 1, med klasse 1 etter konvensjon som den "positive" klassen og spesifikt minoritetsklassen for ubalanserte data, selv om koden skal fungere for regresjon (enkelt). kontinuerlig mål) også.

Genererer ett oppstartseksempeldatasett

 
 
Selv om konfidensintervallkoden vår kan håndtere forskjellige antall dataargumenter som skal sendes til metriske funksjoner, vil vi fokusere på sklearn-stilberegninger, som alltid aksepterer to dataargumenter, y_true og y_pred, der y_pred vil være enten binære klasseprediksjoner (0 eller 1), eller kontinuerlige klasse-sannsynlighets- eller beslutningsfunksjonsprediksjoner, eller til og med kontinuerlig regresjonsprediksjoner hvis y_true også er kontinuerlig. Følgende funksjon genererer et enkelt oppstartseksempeldatasett. Den aksepterer alle data_args, men i vårt tilfelle vil disse argumentene være det ytest(våre faktiske/sanne test satt målverdier i forrige artikkel) Og hardpredtst_tuned_thresh (den spådde klassen). Begge inneholder nuller og enere for å indikere den sanne eller predikerte klassen for hver forekomst.

Egendefinert metrisk specificity_score() og verktøyfunksjoner

 
 
Vi vil definere en egendefinert metrisk funksjon for spesifisitet, som bare er et annet navn for Recall of the negativ klasse (klasse 0). Også en calc_metrics-funksjon som bruker en sekvens av metrikker av interesse på dataene våre, og et par verktøyfunksjoner for den:

Her lager vi vår liste over beregninger og bruker dem på dataene. Vi anså ikke nøyaktighet for å være en relevant beregning fordi en falsk negativ (feilklassifisering av en ekte svindel som legitim) er mye mer kostbar for virksomheten enn en falsk positiv (feilklassifisering av en ekte legitim som en svindel), mens nøyaktighet behandler begge typer feilklassifisering er like dårlige og favoriserer derfor riktig klassifisering av de hvis sanne klasse er majoritetsklassen fordi disse forekommer mye oftere og dermed bidrar mye mer til den generelle nøyaktigheten.

met=[ metrics.recall_score, specificity_score, metrics.balanced_accuracy_score ]
calc_metrics(met, ytest, hardpredtst_tuned_thresh)



Lage hvert oppstartseksempeldatasett og beregne beregninger for det

 
 
I raw_metric_samples() vil vi faktisk generere flere eksempeldatasett én etter én og lagre beregningene for hver:

Du gir raw_metric_samples() en liste over beregninger (eller bare én beregning) av interesse, så vel som sanne og predikerte klassedata, og den henter nboots-eksempeldatasett og returnerer en dataramme med bare metrikkens verdier beregnet fra hvert datasett. Gjennom _boot_generator() påkaller den one_boot() én om gangen i et generatoruttrykk i stedet for å lagre alle datasettene samtidig som en potensielt-stort liste.

Se på beregninger på 7 oppstartseksempeldatasett

 
 
Vi lager vår liste over metriske funksjoner og påkaller raw_metric_samples() for å få resultatene for bare 7 eksempeldatasett. Vi påkaller raw_metric_samples() her for å forstå - det er ikke nødvendig for å få konfidensintervaller ved å bruke ci_auto() nedenfor, selv om det spesifiseres en liste over beregninger (eller bare én metrikk) for ci_auto() is nødvendig.

np.random.seed(13)
raw_metric_samples(met, ytest, hardpredtst_tuned_thresh, nboots=7).style.format('{:.2%}') #optional #style



Hver kolonne ovenfor inneholder beregningene som er beregnet fra ett oppstartseksempeldatasett (nummerert 0 til 6), så de beregnede metriske verdiene varierer på grunn av tilfeldig prøvetaking.

Antall oppstartsdatasett, med beregnet standard

 
 
I vår implementering er antallet oppstartsdatasett som standard nboots vil bli beregnet automatisk fra ønsket konfidensnivå (f.eks. 95 %) for å oppfylle anbefalingen av North, Curtis og Sham å ha et minimum antall oppstartsresultater i hver hale av distribusjonen. (Faktisk gjelder denne anbefalingen p-verdier og dermed hypotesetest aksept regioner, men tillitsintervaller ligner nok på de til å bruke dette som en tommelfingerregel.) Selv om disse forfatterne anbefaler minimum 10 støvelresultater i halen, Davidson og MacKinnon anbefaler minst 399 støvler for 95 % selvtillit, noe som krever 11 støvler i halen, så vi bruker denne mer konservative anbefalingen.

Vi spesifiserer alfa som er 1 – konfidensnivå. f.eks. 95 % konfidens blir 0.95 og alfa=0.05. Hvis du spesifiserer et eksplisitt antall støvler (kanskje et mindre nboots fordi du vil ha raskere resultater), men det er ikke nok for din forespurte alfa, en høyere alfa vil automatisk bli valgt for å få et nøyaktig konfidensintervall for det antallet støvler. Minst 51 støvler vil bli brukt fordi mindre enn bare kan nøyaktig beregne bisarre små konfidensnivåer (som 40 % konfidens som gir et intervall fra 30th persentil til 70th persentil, som har 40 % innenfor intervallet, men 60 % utenfor), og det er ikke klart at anbefalingen for minimumsstøvler i det hele tatt vurderte et slikt tilfelle.

Funksjonen get_alpha_nboots() setter standard nboots eller modifiserer de forespurte alpha og nboots per ovenfor:

La oss vise standard nboots for ulike verdier av alfa:

g = get_alpha_nboots pd.DataFrame( [ g(0.40), g(0.20, None), g(0.10), g(), g(alpha=0.02), g(alpha=0.01, nboots=None), g(0.005, nboots=None) ], columns=['alpha', 'default nboots'] ).set_index('alpha')



Her er hva som skjer hvis vi ber om en eksplisitt nboots:

req=[(0.01,3000), (0.01,401), (0.01,2)]
out=[get_alpha_nboots(*args) for args in req]
mydf = lambda x: pd.DataFrame(x, columns=['alpha', 'nboots'])
pd.concat([mydf(req),mydf(out)],axis=1, keys=('Requested','Using'))



Små nboots-verdier økte alfa til 0.05 og 0.40, og nboots=2 endres til minimum 51.

Histogram av bootstrap-prøvedatasett som viser konfidensintervall bare for balansert nøyaktighet

 
 
Igjen trenger vi ikke å gjøre dette for å få konfidensintervallene nedenfor ved å påkalle ci_auto().

np.random.seed(13)
metric_boot_histogram (metrics.balanced_accuracy_score, ytest, hardpredtst_tuned_thresh)



Den oransje linjen viser 89.7 % som nedre grense for konfidensintervallet for balansert nøyaktighet, grønn for den opprinnelige observerte balanserte nøyaktigheten = 92.4 % (punktestimat), og rød for øvre grense på 94.7 %. (Samme bilde vises øverst i denne artikkelen.)

Hvordan beregne alle konfidensintervallene for listen over beregninger

 
 
Her er hovedfunksjonen som påkaller det ovennevnte og beregner konfidensintervallene fra persentilene til de metriske resultatene, og setter inn punktestimatene som den første kolonnen i sin utdataramme med resultater.

Beregn resultatene!

 
 
Dette er alt vi egentlig trengte å gjøre: påkalle ci_auto() som følger med en liste over beregninger (met tildelt ovenfor) for å få konfidensintervallene deres. Prosentformateringen er valgfri:

np.random.seed(13)
ci_auto( met, ytest, hardpredtst_tuned_thresh ).style.format('{:.2%}')



Diskusjon av resulterende konfidensintervaller

 
 
Her er forvirringsmatrisen fra opprinnelige artikkelen. Klasse 0 er de negative (majoritetsklassen) og klasse 1 er de positive (svært sjelden klasse)



Tilbakekallingen (True Positive Rate) på 134/(134+14) har det bredeste konfidensintervallet fordi dette er en binomial andel som involverer små tellinger.

Spesifisiteten (true negativ rate) er 80,388 80,388/(4,907 XNUMX+XNUMX XNUMX), som innebærer mye større antall, så den har et ekstremt smalt konfidensintervall på bare [94.11 % til 94.40 %].

Siden den balanserte nøyaktigheten beregnes som et gjennomsnitt av tilbakekallingen og spesifisiteten, er bredden på konfidensintervallet mellom deres.

Metrisk måling unøyaktighet på grunn av variasjoner i testdata, kontra variasjoner i togdata

 
 
Her har vi ikke vurdert variasjonen i modell basert på tilfeldigheten vår trening data (selv om det også kan være av interesse for enkelte formål, for eksempel hvis du har automatisert gjentatt omtrening og ønsker å vite hvor mye ytelsen til fremtidige modeller kan variere), men heller bare variasjonen i målingen av ytelsen til denne Spesielt modell (skapt fra noen spesielle treningsdata) på grunn av tilfeldigheten vår test data.

Hvis vi hadde nok uavhengige testdata, kunne vi måle ytelsen til denne modellen på den underliggende populasjonen veldig nøyaktig, og vi ville vite hvordan den vil fungere hvis denne modellen blir distribuert, uavhengig av hvordan vi bygde modellen og om vi evt. få en bedre eller dårligere modell med et annet treningseksempeldatasett.

Uavhengighet av individuelle instanser

 
 
Bootstrap-metoden forutsetter at hver av forekomstene dine (tilfeller, observasjoner) er tegnet uavhengig av en underliggende populasjon. Hvis testsettet ditt har grupper med rader som ikke er uavhengige av hverandre, for eksempel gjentatte observasjoner av samme enhet som sannsynligvis er korrelert med hverandre, eller forekomster som er oversamplet/replikert/generert fra andre forekomster i testen din satt, kan det hende at resultatene ikke er gyldige. Du må kanskje bruke gruppert sampling, der du trekker hele grupper sammen tilfeldig i stedet for individuelle rader, samtidig som du unngår å bryte opp en gruppe eller bare bruke deler av den.

Du vil også forsikre deg om at du ikke har grupper som ble delt på tvers av trenings- og testsettet, for da er ikke testsettet nødvendigvis uavhengig og du kan få uoppdaget overtilpasning. For eksempel hvis du bruker oversampling, bør du vanligvis bare gjøre det etter den har blitt delt fra testsettet, ikke før. Og normalt vil du oversample treningssettet, men ikke testsettet, siden testsettet må forbli representativt for tilfeller modellen vil se ved fremtidig distribusjon. Og for kryssvalidering vil du gjerne bruke scikit-learn model_selection.GroupKFold().

konklusjonen

 
 
Du kan alltid beregne konfidensintervaller for evalueringsberegningen(e) for å se hvor nøyaktig testdataene dine gjør det mulig for deg å måle modellens ytelse. Jeg planlegger en annen artikkel for å demonstrere konfidensintervaller for beregninger som evaluerer sannsynlighetsprediksjoner (eller konfidenspoeng – ingen relasjon til statistisk konfidens), dvs. myk klassifisering, for eksempel loggtap eller ROC AUC, i stedet for beregningene vi brukte her som evaluerer diskret valg av klasse etter modellen (hard klassifisering). Den samme koden fungerer for begge, så vel som for regresjon (forutsi en kontinuerlig målvariabel) - du må bare gi den en annen type prediksjon (og annen type sanne mål i tilfelle regresjon).

Denne Jupyter-notatboken er tilgjengelig i github: bootConfIntAutoV1o_standalone.ipynb

Var denne artikkelen informativ og/eller nyttig? Legg inn en kommentar nedenfor hvis du har kommentarer eller spørsmål om denne artikkelen eller om konfidensintervaller, bootstrap, antall støvler, denne implementeringen, datasettet, modellen, terskelflytting eller resultater.

I tillegg til det nevnte forrige artikkel, kan du også være interessert i min Slik oppdager du dato/dato-kolonnene automatisk og angir datatype når du leser en CSV-fil i Pandas, selv om det ikke er direkte relatert til denne artikkelen.

Noen rettigheter forbeholdt

 
Bio: David B Rosen (PhD) er Lead Data Scientist for Automated Credit Approval hos IBM Global Financing. Finn mer av Davids forfatterskap på dabruro.medium.com.

original. Ompostet med tillatelse.

Relatert:

Kilde: https://www.kdnuggets.com/2021/10/calculate-confidence-intervals-performance-metrics-machine-learning.html

Tidstempel:

Mer fra KDnuggets