2015-06-22 8 views
49

Ho molti problemi a capire come funziona il parametro class_weight nella regressione logistica di scikit-learn.Come funziona il parametro class_weight in scikit-learn?

La situazione

voglio usare la regressione logistica per fare classificazione binaria su un insieme di dati molto sbilanciato. Le classi sono contrassegnate con 0 (negativo) e 1 (positivo) ei dati osservati sono in un rapporto di circa 19: 1 con la maggior parte dei campioni con esito negativo.

primo tentativo: Preparazione manuale dei dati di allenamento

ho diviso i dati che ho avuto in insiemi disgiunti per la formazione e la sperimentazione (circa 80/20). Quindi ho campionato a caso i dati di allenamento a mano per ottenere dati di allenamento in proporzioni diverse da 19: 1; da 2: 1 a 16: 1.

Ho quindi addestrato la regressione logistica su questi diversi sottoinsiemi di dati di allenamento e il richiamo tracciato (= TP/(TP + FN)) in funzione delle diverse proporzioni dell'allenamento. Naturalmente, il richiamo è stato calcolato sui campioni TEST disgiunti che avevano le proporzioni osservate di 19: 1. Nota, anche se ho addestrato i diversi modelli su diversi dati di allenamento, ho calcolato il richiamo per tutti loro sullo stesso (disgiunto) dati di test.

I risultati sono stati come previsto: il richiamo era di circa il 60% alle proporzioni di allenamento 2: 1 e cadde piuttosto velocemente quando è arrivato a 16: 1. C'erano diverse proporzioni 2: 1 -> 6: 1 in cui il richiamo era decentemente superiore al 5%.

secondo tentativo: Griglia Cerca

Successivamente, ho voluto mettere alla prova diversi parametri di regolarizzazione e quindi ho usato GridSearchCV e ha fatto una griglia di diversi valori del parametro C così come il parametro class_weight. Per tradurre il mio n: m proporzioni di negativo: campioni di addestramento positivi nella lingua del dizionario di class_weight ho pensato che basta specificare vari dizionari come segue:

{ 0:0.67, 1:0.33 } #expected 2:1 
{ 0:0.75, 1:0.25 } #expected 3:1 
{ 0:0.8, 1:0.2 } #expected 4:1 

e ho anche incluso None e auto.

Questa volta i risultati sono stati completamente risolti. Tutti i miei richiami sono usciti in piccolo (< 0,05) per ogni valore di class_weight eccetto auto. Quindi posso solo supporre che la mia comprensione di come impostare il dizionario class_weight sia errata. È interessante notare che il valore di class_weight di "auto" nella ricerca della griglia era di circa il 59% per tutti i valori di C e ho indovinato che fosse salito a 1: 1?

Le mie domande

1) Come si usa correttamente class_weight di raggiungere equilibri diversi in dati di allenamento da quello che in realtà dà? In particolare, quale dizionario devo passare a class_weight per utilizzare proporzioni n: m negative: campioni di allenamento positivi?

2) Se si passano vari dizionari class_weight a GridSearchCV, durante la convalida incrociata, ribilancerà i dati di allenamento in base al dizionario, ma utilizzerà le proporzioni campione effettive fornite per calcolare la funzione di calcolo del punteggio sulla piega di prova?Questo è fondamentale poiché qualsiasi metrica mi è utile solo se proviene dai dati nelle proporzioni osservate.

3) Che valore ha il valore autoclass_weight fino alle proporzioni? Ho letto la documentazione e presumo che "equilibri i dati inversamente proporzionali alla loro frequenza" significa solo che lo rende 1: 1. È corretto? In caso contrario, qualcuno può chiarire?

Grazie mille, qualsiasi chiarimento sarebbe molto apprezzato!

risposta

49

Prima di tutto, potrebbe non essere buono andare solo con il richiamo da solo. Puoi semplicemente ottenere un richiamo del 100% classificando tutto come classe positiva. Io di solito suggerisco di usare l'AUC per la selezione dei parametri, e poi trovare una soglia per il punto di lavoro (per esempio un dato livello di precisione) che siete interessati a

Per quanti class_weight lavori:. Si penalizza errori in campioni di class[i] con class_weight[i] invece di 1. Quindi, un peso di classe più alto significa che vuoi mettere più enfasi su una classe. Da quello che dici sembra che la classe 0 sia 19 volte più frequente della classe 1. Quindi dovresti aumentare lo class_weight della classe 1 rispetto alla classe 0, ad esempio {0: .1, 1: .9}. Se lo class_weight non somma a 1, cambierà sostanzialmente il parametro di regolarizzazione.

Per come funziona class_weight="auto", è possibile dare un'occhiata a this discussion. Nella versione dev è possibile utilizzare class_weight="balanced", che è più facile da capire: fondamentalmente significa replicare la classe più piccola finché non si dispone di tanti campioni come in quello più grande, ma in modo implicito.

+0

Grazie! Domanda veloce: ho menzionato il richiamo per chiarezza e in effetti sto cercando di decidere quale AUC usare come misura. La mia comprensione è che dovrei massimizzare l'area sotto la curva ROC o l'area sotto la curva di richiamo rispetto alla precisione per trovare i parametri. Dopo aver selezionato i parametri in questo modo, credo di scegliere la soglia per la classificazione scorrendo lungo la curva. È questo che intendevi? Se è così, quale delle due curve ha più senso da guardare se il mio obiettivo è quello di catturare quanti più TP possibile? Inoltre, grazie per il tuo lavoro e i tuoi contributi allo scikit-learn !!! – ministry

+1

Penso che l'utilizzo di ROC sarebbe la soluzione più standard, ma non credo che ci sarà un'enorme differenza. Hai bisogno di qualche criterio per scegliere il punto sulla curva, però. –

+0

Non c'è anche l'idea di penalizzare più pesantemente una errata classificazione del set più piccolo in questo scenario? Anche se sono d'accordo, la cosa da provare è l'impostazione bilanciata per il parametro class_weight. –

Problemi correlati