Python: gestione delle classi di squilibrio in Machine Learning python


9

Ho un set di dati per il quale sto cercando di prevedere le variabili target.

Col1    Col2    Col3    Col4    Col5    
  1      2       23      11     1
  2      22      12      14     1
  22     11      43      38     3
  14     22      25      19     3
  12     42      11      14     1
  22     11      43      38     2
  1      2       23      11     4
  2      22      12      14     2
  22     11      43      38     3

Ho fornito un campione di dati, ma il mio ha migliaia di record distribuiti in modo simile. Qui, Col1, Col2, Col3, Col4 sono le mie caratteristiche e Col5 è la variabile target. Quindi la previsione dovrebbe essere 1,2,3 o 4 in quanto questi sono i miei valori per la variabile target. Ho provato a utilizzare algoritmi come foresta casuale, albero decisionale ecc. Per le previsioni.

Qui, se vedi, i valori 1,2 e 3 si verificano più volte rispetto a 4. Quindi, mentre predico, il mio modello è più distorto verso 1 2 e 3 mentre sto ottenendo solo un numero inferiore di previsioni per 4 (ne ho solo 1 previsto per policy4 su migliaia di record quando ho visto la matrice di confusione).

Per generalizzare il mio modello, ho rimosso in modo casuale la percentuale uguale di dati che appartiene ai valori 1,2 e 3. Ho raggruppato per ciascun valore in Col5 e quindi rimosso una certa percentuale, in modo da ridurre il numero di record. Ora potrei vedere un certo aumento della percentuale di accuratezza e anche un ragionevole aumento delle previsioni per il valore 4 nella matrice di confusione.

È questo l'approccio giusto da affrontare (rimuovere i dati in modo casuale da quei gruppi su cui il modello è distorto)?

Ho provato per algoritmi Python integrati come Adaboost, tecniche GradientBoost usando sklearn. Ho letto che questi algoritmi sono per la gestione della classe di squilibrio. Ma non sono riuscito a migliorare la mia precisione, piuttosto rimuovendo casualmente i dati, dove ho potuto vedere alcuni miglioramenti.

Questa riduzione è la tecnica del sottocampionamento ed è questo l'approccio giusto per il sottocampionamento?

Esistono pacchetti predefiniti in sklearn o qualche logica che posso implementare in python per farlo, se la mia rimozione casuale è errata?

Inoltre, ho imparato a conoscere la tecnica SMOTE, che si occupa di sovracampionamento. Dovrei provare questo per il valore 4? E possiamo farlo usando dei pacchetti integrati in Python? Sarebbe bello se qualcuno mi aiutasse in questa situazione.

Risposte:


5

Questo articolo suggerisce di usare la classifica (l'ho scritto). Invece di utilizzare direttamente SVM, ad esempio, utilizzare RankSVM. Poiché i ranghi confrontano l'osservazione con l'osservazione, l'allenamento è necessariamente equilibrato. Esistono due "ma": l'allenamento è molto più lento e, alla fine, ciò che fanno questi modelli è classificare le tue osservazioni in base alla probabilità che appartengano a una classe rispetto alla probabilità che appartengano a un'altra, quindi è necessario applicare successivamente una soglia.

Se hai intenzione di utilizzare la pre-elaborazione per correggere il tuo squilibrio, ti suggerisco di consultare MetaCost . Questo algoritmo prevede la creazione di una serie di modelli e quindi la modifica dei priori di classe per renderli bilanciati in base ai casi difficili da prevedere. È molto elegante. La cosa bella di metodi come SMOTE è che fabbricando nuove osservazioni, potresti rendere più robusti piccoli set di dati.

Comunque, anche se ho scritto alcune cose sullo squilibrio di classe, sono ancora scettico sul fatto che sia un problema importante nel mondo reale. Penso che non sia raro che tu abbia squilibrati i priori nel tuo set di addestramento, ma i priori equilibrati nei tuoi dati del mondo reale. Fai? Quello che succede di solito è che gli errori di tipo I sono diversi dagli errori di tipo II e scommetterei che la maggior parte delle persone starebbe meglio usando una matrice di costi, che la maggior parte dei metodi di allenamento accetta o che è possibile applicare pre-elaborazione usando MetaCost o SMOTE. Penso che molte volte "correggere lo squilibrio" sia breve "Non voglio preoccuparmi di pensare al relativo compromesso tra errori di tipo I e II".

Addendum:

Ho provato per algoritmi Python integrati come Adaboost, tecniche GradientBoost usando sklearn. Ho letto che questi algoritmi sono per la gestione della classe di squilibrio.

AdaBoost offre risultati migliori per lo squilibrio di classe quando si inizializza la distribuzione del peso tenendo presente lo squilibrio. Posso scavare la tesi in cui ho letto questo, se vuoi.

Comunque, ovviamente, questi metodi non daranno buone accuratezze. Hai uno squilibrio di classe sia nel tuo allenamento che nel tuo set di dati di validazione? È necessario utilizzare metriche come il punteggio F1 o passare una matrice di costo alla funzione di precisione. Lo squilibrio di classe "riparatore" si verifica quando i tuoi priori sono diversi nella formazione e nei casi di convalida.


4

Alcuni algoritmi di sklearn hanno un parametro chiamato class_weight che puoi impostare su "bilanciato" . In questo modo sklearn regolerà i pesi della sua classe in base al numero di campioni che hai di ogni classe.

Per il classificatore di foresta casuale, prova quanto segue e vedi se migliora il tuo punteggio:

rf = RandomForestClassifier(class_weight="balanced") # also add your other parameters!

(class_weight = "equilibrato") non sta fornendo miglioramenti sufficienti quando ho provato a usarlo
SRS

2
@Srinath cosa capisci per miglioramento? Quale metrica stai usando? Se sia il tuo allenamento che la tua validazione sono squilibrati, non puoi usare i punteggi di precisione. Quello che class_weightfa è costruire una matrice di costi per te dove per ogni classek, Ck=2NkN. Si dovrebbe passare sia sample_weight=[C_k for k in y]per accuracy_scoreo l'uso qualcosa di simile f1_score.
Ricardo Cruz,

2

Sì, questa è una tecnica eccellente per affrontare il problema dello squilibrio di classe. Tuttavia, i metodi di sottocampionamento portano alla perdita di informazioni nel set di dati (diciamo, hai appena rimosso uno schema interessante tra le restanti variabili, che avrebbe potuto contribuire a una migliore formazione del modello). Questo è il motivo per cui sono preferiti metodi di sovracampionamento, in particolare nel caso di set di dati più piccoli.

In risposta alla tua domanda relativa ai pacchetti Python, la toolbox sbilanciata è appositamente dedicata per la stessa attività. Fornisce diversi metodi di sottocampionamento e sovracampionamento. Consiglierei di provare la tecnica SMOTE .


1

Dipende dalla tecnica dell'ensemble che si desidera utilizzare. Il problema di base con cui si sta lavorando con un problema di squilibrio dei dati multi-classe. Il sottocampionamento può essere utilizzato in modo efficiente nel confezionamento e nelle tecniche di potenziamento. L'algoritmo SMOTE è molto efficiente nella generazione di nuovi campioni. Il problema dello squilibrio dei dati è stato ampiamente studiato in letteratura. Vi consiglio di leggere uno di questi algoritmi: SMOTE-Boost SMOTE-Bagging Rus-Boost EusBoost Queste sono tecniche di potenziamento / insaccamento progettate specificamente per il problema dei dati di squilibrio. Invece di SMOTE puoi provare ADA-SMOTE o Border-Line SMOTE. Ho usato e modificato SMOTE Border-Line per multi-classe ed è molto efficiente. Se la tua base di dati è molto grande e il problema è semplice, prova: viola - jones classifier. Ho usato anche con il problema dello squilibrio dei dati ed è davvero efficiente


Grazie per la guida. Sto esaminando gli argomenti da te menzionati. Ma la tecnica che ho usato per sottocampionare (riducendo i dati in modo casuale) è un modo giusto di fare?
SRS,

Puoi usarlo se il tuo database è molto grande. Ma se il tuo database è piccolo, perderai alcune delle informazioni. Leggi il Rus-Boosting, in questo metodo usano il campionamento casuale sotto parte dell'algoritmo di boosting per evitare di perdere informazioni. Sotto campionano il sottoinsieme che verrà usato per addestrare il prossimo apprendente di base ma non l'intero database
Bashar Haddad

Il mio set di dati ha quasi 80.000 record che sto usando come set di addestramento. Lo sto implementando in Python. Stavo cercando alcuni pacchetti in sklearn o qualcos'altro in Python. Non sono riuscito a trovarli. È qualcosa per cui dovrei mettere a posto una logica per implementarli?
SRS,

Non credo ci sia alcuna implementazione per questi metodi. Il problema dello squilibrio dei dati è ancora oggetto di ricerca. Se hai una buona implementazione per Adaboost.M1 o M2. Puoi facilmente modificarlo per diventare Rus Boost
Bashar Haddad il

Penso che il database che hai sia abbastanza grande e se vuoi puoi usare il classificatore viola - jones. Per questo potresti trovare l'implementazione disponibile
Bashar Haddad,

0

Ci sono già alcune buone risposte qui. Ho solo pensato di aggiungere un'altra tecnica dal momento che sembri usare gruppi di alberi. In molti casi stai cercando di ottimizzare la curva di sollevamento o l'AUC per il ROC. Per questo, consiglierei il criterio di distanza Hellinger per dividere i rami nei tuoi alberi. Al momento della stesura di questo documento non è incluso nel pacchetto di apprendimento sbilanciato ma sembra che ci sia un piano .


0

Quando si tratta di un problema di squilibrio di classe, è necessario concentrarsi principalmente sulla metrica di errore e si dovrebbe scegliere il punteggio F1 come metrica di errore.

Dopo aver scelto la metrica corretta, possiamo utilizzare diverse tecniche per affrontare questo problema.

Se sei interessato puoi consultare il seguente blog, è spiegato molto bene sulle tecniche utilizzate per risolvere questo problema di squilibrio di classe:

https://knowledgengg.wordpress.com/2019/03/04/this-is-suresh/

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.