Come calcolare gli intervalli di confidenza per le metriche delle prestazioni in Machine Learning utilizzando un metodo bootstrap automatico

Nodo di origine: 1178501

Come calcolare gli intervalli di confidenza per le metriche delle prestazioni in Machine Learning utilizzando un metodo bootstrap automatico

Le misurazioni delle prestazioni del modello sono molto precise a causa di un set di test "ampio" o molto incerte a causa di un set di test "piccolo" o sbilanciato?


By David B Rosen (dottorato), Lead Data Scientist per l'approvazione automatizzata del credito presso IBM Global Financing



La linea arancione mostra l'89.7% come limite inferiore dell'intervallo di confidenza dell'accuratezza bilanciata, verde per l'accuratezza bilanciata osservata originale=92.4% (stima puntuale) e rosso per il limite superiore del 94.7%. (Questa e tutte le immagini sono dell'autore se non diversamente specificato.)

Introduzione

 
 
Se riporti le prestazioni del tuo classificatore con Precisione=94.8% e F1=92.3% su un set di test, ciò non significa molto senza sapere qualcosa sulla dimensione e la composizione del set di test. Il margine di errore di tali misurazioni delle prestazioni varierà molto a seconda delle dimensioni del set di test o, per un set di dati sbilanciato, principalmente a seconda del numero di istanze indipendenti del minoranza class che contiene (più copie delle stesse istanze dal sovracampionamento non aiutano a questo scopo).

Se fossi in grado di raccogliere un altro set di test indipendente di origine simile, è improbabile che Accuracy e F1 del tuo modello su questo set di dati siano gli stessi, ma quanto potrebbero essere diversi in modo plausibile? Una domanda simile a questa trova risposta nelle statistiche come il intervallo di confidenza della misura.

Se dovessimo estrarre molti set di dati campione indipendenti dalla popolazione sottostante, allora per il 95% di tali set di dati, il vero valore della popolazione sottostante della metrica sarebbe compreso nell'intervallo di confidenza del 95% che calcoleremmo per quel particolare set di dati campione.

In questo articolo ti mostreremo come calcolare gli intervalli di confidenza per qualsiasi numero di metriche delle prestazioni di Machine Learning contemporaneamente, con un metodo bootstrap che automaticamente determina quanti set di dati di esempio di avvio generare per impostazione predefinita.

Se vuoi solo vedere come invocare questo codice per calcolare gli intervalli di confidenza, vai alla sezione "Calcola i risultati!" in basso.

La metodologia bootstrap

 
 
Se fossimo in grado di trarre set di dati di test aggiuntivi dalla vera distribuzione alla base dei dati, saremmo in grado di vedere la distribuzione delle metriche di performance di interesse tra quei set di dati. (Quando disegniamo quei set di dati non faremmo nulla per impedire di disegnare un'istanza identica o simile più volte, anche se ciò potrebbe accadere solo raramente.)

Dal momento che non possiamo farlo, la cosa migliore da fare è disegnare set di dati aggiuntivi dal file distribuzione empirica di questo set di dati di test, il che significa campionare, con sostituzione, dalle sue istanze per generare nuovi set di dati di esempio bootstrap. Campionamento con sostituzione significa che una volta che disegniamo una particolare istanza, la reinseriamo in modo da poterla disegnare di nuovo per lo stesso set di dati di esempio. Pertanto, ciascuno di questi set di dati ha generalmente più copie di alcune delle istanze e non include tutte le istanze che si trovano nel set di test di base.

Se abbiamo campionato senza sostituzione, otterremmo semplicemente una copia identica del set di dati originale ogni volta, mescolata in un ordine casuale diverso, che non sarebbe di alcuna utilità.

Il percentile La metodologia bootstrap per la stima dell'intervallo di confidenza è la seguente:

  1. Generare nboots Set di dati "campione bootstrap", ciascuno della stessa dimensione del set di test originale. Ogni set di dati di esempio viene ottenuto estraendo istanze a caso dal set di test con sostituzione.
  2. Su ciascuno dei set di dati di esempio, calcola la metrica e salvala.
  3. L'intervallo di confidenza al 95% è dato da 2.5th alla 97.5th percentile tra i nboots valori calcolati della metrica. Se nboots=1001 e hai ordinato i valori in una serie/array/elenco X di lunghezza 1001, lo 0th percentile è X[0] e il 100th percentile è X[1000], quindi l'intervallo di confidenza sarebbe dato da X[25] a X[975].

Ovviamente puoi calcolare tutte le metriche che desideri per ogni set di dati di esempio nel passaggio 2, ma nel passaggio 3 troverai i percentili per ogni parametro separatamente.

Esempio di set di dati e risultati dell'intervallo di confidenza

 
 
Useremo i risultati di questo articolo precedente come esempio: Come affrontare una classificazione squilibrata, senza riequilibrare i datiPrima di prendere in considerazione l'oversampling dei dati distorti, prova a regolare la soglia di decisione della classificazione.

In quell'articolo abbiamo usato il vivamente- Kaggle a due classi sbilanciato set di dati per l'identificazione delle frodi con carta di credito. Abbiamo scelto di utilizzare una soglia di classificazione piuttosto diversa dalla soglia predefinita di 0.5 che è implicita nell'utilizzo del metodo predict(), rendendo superfluo il bilanciamento dei dati. Questo approccio è talvolta definito soglia in movimento, in cui il nostro classificatore assegna la classe applicando la soglia scelta alla probabilità prevista della classe fornita dal metodo predict_prova() metodo.

Limiteremo lo scopo di questo articolo (e codice) alla classificazione binaria: classi 0 e 1, con la classe 1 per convenzione che è la classe "positiva" e specificamente la classe di minoranza per i dati sbilanciati, sebbene il codice dovrebbe funzionare per la regressione (singola obiettivo continuo).

Generazione di un set di dati di esempio di avvio

 
 
Sebbene il nostro codice dell'intervallo di confidenza possa gestire vari numeri di argomenti di dati da passare alle funzioni metriche, ci concentreremo sulle metriche in stile sklearn, che accettano sempre due argomenti di dati, y_true e y_pred, dove y_pred sarà o previsioni di classe binaria (0 o 1), o previsioni continue di probabilità di classe o funzione decisionale, o anche previsioni di regressione continua se anche y_true è continua. La funzione seguente genera un singolo set di dati di esempio di avvio. Accetta qualsiasi data_args ma nel nostro caso questi argomenti lo saranno ytest(il nostro test effettivo/vero imposta i valori target nel formato articolo precedente) e hardpredtst_tuned_thresh (la classe prevista). Entrambi contengono zeri e uno per indicare la classe vera o prevista per ogni istanza.

Custom metric specificity_score() e funzioni di utilità

 
 
Definiremo una funzione metrica personalizzata per la specificità, che è solo un altro nome per il richiamo del negativo. classe (classe 0). Anche una funzione calc_metrics che applica una sequenza di metriche di interesse ai nostri dati e un paio di funzioni di utilità per esso:

Qui creiamo il nostro elenco di metriche e le applichiamo ai dati. Non abbiamo considerato l'accuratezza un parametro rilevante perché un falso negativo (classificazione errata di una vera frode come legittima) è molto più costoso per l'azienda di un falso positivo (classificazione errata di una vera frode come una frode), mentre Accuratezza tratta entrambi i tipi di errata classificazione sono ugualmente cattivi e quindi favoriscono la corretta classificazione di quelli la cui vera classe è la classe maggioritaria perché questi si verificano molto più spesso e quindi contribuiscono molto di più alla precisione complessiva.

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



Creazione di ogni set di dati campione di avvio e calcolo delle metriche per esso

 
 
In raw_metric_samples() genereremo effettivamente più set di dati di esempio uno per uno e salveremo le metriche di ciascuno:

Fornisci a raw_metric_samples() un elenco di metriche (o solo una metrica) di interesse, nonché i dati di classe veri e previsti, e ottiene set di dati di esempio nboots e restituisce un frame di dati con solo i valori delle metriche calcolati da ciascun set di dati. Attraverso _boot_generator() invoca one_boot() uno alla volta in un'espressione del generatore piuttosto che archiviare tutti i set di dati contemporaneamente come potenzialmente-Enorme elenco.

Guarda le metriche su 7 set di dati di esempio di avvio

 
 
Creiamo il nostro elenco di funzioni metriche e invochiamo raw_metric_samples() per ottenere i risultati per soli 7 set di dati di esempio. Stiamo invocando raw_metric_samples() qui per capire — non è necessario per ottenere gli intervalli di confidenza usando ci_auto() qui sotto, sebbene specifichi un elenco di metriche (o solo una metrica) per ci_auto() is necessario.

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



Ogni colonna sopra contiene le metriche calcolate da un set di dati di esempio di avvio (numerato da 0 a 6), pertanto i valori delle metriche calcolate variano a causa del campionamento casuale.

Numero di set di dati di avvio, con valore predefinito calcolato

 
 
Nella nostra implementazione, per impostazione predefinita il numero di set di dati di avvio nboots sarà calcolato automaticamente dal livello di confidenza desiderato (ad es. 95%) in modo da soddisfare la raccomandazione entro North, Curtis e Sham per avere un numero minimo di risultati di avvio in ogni coda della distribuzione. (In realtà questa raccomandazione si applica a p-valori e quindi test di ipotesi regioni di accettazione, ma intervalli di confidenza sono abbastanza simili a quelli da utilizzare come regola generale.) Sebbene quegli autori raccomandino un minimo di 10 risultati di avvio nella coda, Davidson & MacKinnon consigliamo almeno 399 stivali per una sicurezza del 95%, che richiede 11 stivali nella coda, quindi usiamo questa raccomandazione più conservativa.

Specifichiamo alfa che è 1 – livello di confidenza. Ad esempio, la confidenza al 95% diventa 0.95 e alfa=0.05. Se specifichi un numero esplicito di boots (forse un numero più piccolo nboots perché desideri risultati più rapidi) ma non è sufficiente per l'alfa richiesto, verrà scelto automaticamente un alfa più alto per ottenere un intervallo di confidenza accurato per quel numero di stivali. Verrà utilizzato un minimo di 51 stivali perché qualsiasi numero inferiore può calcolare con precisione solo livelli di confidenza stranamente piccoli (come il 40% di confidenza che fornisce un intervallo dai 30th percentile al 70th percentile, che ha il 40% all'interno dell'intervallo ma il 60% al di fuori di esso) e non è chiaro se la raccomandazione per gli scarponi minimi contemplasse un caso del genere.

La funzione get_alpha_nboots() imposta gli nboots predefiniti o modifica l'alpha e gli nboots richiesti come sopra:

Mostriamo gli nboot predefiniti per vari valori di 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')



Ecco cosa succede se richiediamo un nboots esplicito:

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



I piccoli valori di nboots aumentano l'alfa a 0.05 e 0.40 e nboots=2 viene modificato al minimo di 51.

Istogramma dei set di dati campione bootstrap che mostra l'intervallo di confidenza solo per Balanced Accuracy

 
 
Ancora una volta non abbiamo bisogno di farlo per ottenere gli intervalli di confidenza sottostanti invocando ci_auto().

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



La linea arancione mostra l'89.7% come limite inferiore dell'intervallo di confidenza dell'accuratezza bilanciata, verde per l'accuratezza bilanciata osservata originale=92.4% (stima puntuale) e rosso per il limite superiore del 94.7%. (La stessa immagine appare nella parte superiore di questo articolo.)

Come calcolare tutti gli intervalli di confidenza per l'elenco delle metriche

 
 
Ecco la funzione principale che invoca quanto sopra e calcola gli intervalli di confidenza dai percentili dei risultati della metrica e inserisce le stime puntuali come prima colonna del dataframe di output dei risultati.

Calcola i risultati!

 
 
Questo è tutto ciò di cui avevamo veramente bisogno: richiamare ci_auto() come segue con un elenco di metriche (met assegnato sopra) per ottenere i loro intervalli di confidenza. La formattazione percentuale è facoltativa:

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



Discussione degli intervalli di confidenza risultanti

 
 
Ecco la matrice di confusione da articolo originale. La classe 0 sono i negativi (classe maggioritaria) e la classe 1 sono i positivi (classe molto rara)



Il richiamo (tasso di veri positivi) di 134/(134+14) ha l'intervallo di confidenza più ampio perché si tratta di una proporzione binomiale che coinvolge piccoli conteggi.

La specificità (tasso di veri negativi) è 80,388/(80,388+4,907), che coinvolge molti conteggi più grandi, quindi ha un intervallo di confidenza estremamente ristretto di appena [dal 94.11% al 94.40%].

Poiché l'accuratezza bilanciata è calcolata semplicemente come una media del richiamo e della specificità, l'ampiezza del suo intervallo di confidenza è intermedio tra il loro.

Imprecisione della misurazione metrica dovuta a variazioni nei dati di prova rispetto a variazioni nei dati del treno

 
 
Qui non abbiamo considerato la variabilità nel modello basato sulla casualità del nostro formazione dati (sebbene ciò possa anche essere interessante per alcuni scopi, ad esempio se si dispone di un riaddestramento automatico ripetuto e si desidera sapere quanto potrebbero variare le prestazioni dei modelli futuri), ma piuttosto solo la variabilità nella misurazione delle prestazioni di questo particolare modello (creato da alcuni dati di addestramento particolari) a causa della casualità del nostro test dati.

Se avessimo abbastanza dati di test indipendenti, potremmo misurare le prestazioni di questo particolare modello sulla popolazione sottostante in modo molto preciso e sapremmo come si comporterà se questo modello viene implementato, indipendentemente da come lo abbiamo costruito e se potremmo ottenere un modello migliore o peggiore con un set di dati campione di addestramento diverso.

Indipendenza delle singole istanze

 
 
Il metodo bootstrap presuppone che ciascuna delle tue istanze (casi, osservazioni) sia disegnata indipendentemente da una popolazione sottostante. Se il tuo set di test ha gruppi di righe che non sono indipendenti l'uno dall'altro, ad esempio osservazioni ripetute della stessa entità che potrebbero essere correlate tra loro o istanze sovracampionate/replicate/generate da altre istanze nel tuo test impostato, i risultati potrebbero non essere validi. Potrebbe essere necessario utilizzare raggruppati campionamento, in cui si disegnano interi gruppi insieme a caso piuttosto che singole righe, evitando di suddividere qualsiasi gruppo o di utilizzarne solo una parte.

Inoltre, vuoi assicurarti di non avere gruppi divisi tra il set di addestramento e di test, perché in tal caso il set di test non è necessariamente indipendente e potresti ottenere un overfitting non rilevato. Ad esempio, se usi il sovracampionamento, generalmente dovresti farlo solo dopo è stato separato dal set di test, non prima. E normalmente dovresti sovracampionare il set di addestramento ma non il set di test, poiché il set di test deve rimanere rappresentativo delle istanze che il modello vedrà al momento della distribuzione futura. E per la convalida incrociata vorresti usare scikit-learn model_selection.GroupKFold().

Conclusione

 
 
Puoi sempre calcolare gli intervalli di confidenza per le tue metriche di valutazione per vedere con quanta precisione i tuoi dati di test ti consentono di misurare le prestazioni del tuo modello. Sto pianificando un altro articolo per dimostrare gli intervalli di confidenza per le metriche che valutano le previsioni di probabilità (o i punteggi di confidenza - nessuna relazione con la confidenza statistica), ad esempio la classificazione soft, come Log Loss o ROC AUC, piuttosto che le metriche che abbiamo usato qui che valutano il scelta discreta della classe da parte del modello (classificazione rigida). Lo stesso codice funziona per entrambi, così come per la regressione (previsione di una variabile target continua): devi solo passargli un diverso tipo di previsione (e diversi tipi di veri obiettivi nel caso della regressione).

Questo taccuino jupyter è disponibile in github: bootConfIntAutoV1o_standalone.ipynb

Questo articolo è stato informativo e/o utile? Si prega di pubblicare un commento di seguito se si hanno commenti o domande su questo articolo o su intervalli di confidenza, bootstrap, numero di avvii, questa implementazione, set di dati, modello, spostamento della soglia o risultati.

Oltre a quanto sopra articolo precedente, potrebbe interessarti anche il mio Come rilevare automaticamente le colonne Data/Datetime e impostare il loro tipo di dati durante la lettura di un file CSV in Pandas, sebbene non sia direttamente correlato al presente articolo.

Alcuni diritti riservati

 
Bio: David B Rosen (dottorato) è Lead Data Scientist per l'approvazione automatizzata del credito presso IBM Global Financing. Trova altri scritti di David su dabruro.medium.com.

Originale. Ripubblicato con il permesso.

Correlato:

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

Timestamp:

Di più da KDnuggets