5

Sto provando a prevedere un set di etichette utilizzando Logistic Regression from SciKit. I miei dati sono veramente sbilanciati (ci sono molti più '0' di etichette '1') quindi devo usare lo F1 score metric durante passo di convalida per "bilanciare" il risultato.Errore metrica F-score di Scikit

[Input] 
X_training, y_training, X_test, y_test = generate_datasets(df_X, df_y, 0.6) 
logistic = LogisticRegressionCV(
    Cs=50, 
    cv=4, 
    penalty='l2', 
    fit_intercept=True, 
    scoring='f1' 
) 
logistic.fit(X_training, y_training) 
print('Predicted: %s' % str(logistic.predict(X_test))) 
print('F1-score: %f'% f1_score(y_test, logistic.predict(X_test))) 
print('Accuracy score: %f'% logistic.score(X_test, y_test)) 

[Output] 
>> Predicted: [0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0] 
>> Actual: [0 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 1 1] 
>> F1-score: 0.285714 
>> Accuracy score: 0.782609 
>> C:\Anaconda3\lib\site-packages\sklearn\metrics\classification.py:958: 
    UndefinedMetricWarning: 
    F-score is ill-defined and being set to 0.0 due to no predicted samples. 

certamente sanno che il problema è legato al mio set di dati: è troppo piccolo (è solo un esempio di quello reale). Tuttavia, qualcuno può spiegare il significato dell'avviso "UndefinedMetricWarning" che sto vedendo? Cosa sta realmente succedendo dietro le tende?

+6

Nota a margine, se il set di dati è VERAMENTE squilibrato (ad esempio 100000 di "0" e solo 20 "1"), è possibile passare dall'impostazione di classificazione a rilevamento di anomalia. Per casi estremamente distorti funzionerà molto meglio. Dettagli: http://scikit-learn.org/stable/modules/outlier_detection.html –

+1

Lo squilibrio qui è del 70-30% circa, quindi penso che sia ancora adatto per utilizzare classificatori classici. Tuttavia, il tuo commento potrebbe essere estremamente prezioso per le persone alle prese con dataset davvero distorti quindi ti ringrazio comunque per il suggerimento :) – David

risposta

4

Sembra che sia un bug noto here che è stato corretto, credo che dovresti provare ad aggiornare sklearn.

+3

Ho questo messaggio di errore con scikit-learn 0.17. Eventuali aggiornamenti su questo argomento? Le mie lezioni sono quasi equilibrate. – OAK

0

Tuttavia, qualcuno può spiegare il significato dell'avviso "UndefinedMetricWarning" che sto vedendo? Cosa sta realmente succedendo dietro le tende?

Questo è ben descritto nel https://stackoverflow.com/a/34758800/1587329:

https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/metrics/classification.py

F1 = 2 * (precisione * sensitività)/(precisione + richiamo)

precisione = TP/(TP + FP) come hai appena detto se il predittore non prevede una classe positiva - la precisione è 0.

richiamo = TP/(TP + FN), nel caso in cui se predittore non predice positivo classe - TP è 0 - 0. richiamo è

Così ora stai dividendo 0/0.

Per risolvere il problema ponderazione (è facile per il classificatore a (quasi) prevedere sempre la classe più diffusa), è possibile utilizzare class_weight="balanced":

logistic = LogisticRegressionCV(
    Cs=50, 
    cv=4, 
    penalty='l2', 
    fit_intercept=True, 
    scoring='f1', 
    class_weight="balanced" 
) 

LogisticRegressionCV dice:

La modalità "bilanciata" utilizza i valori di y per regolare automaticamente i pesi inversamente proporzionali alle frequenze di classe nei dati di input come n_samples/(n_classes * np.bincount(y)).