Migliora la classificazione con molte variabili categoriali


37

Sto lavorando a un set di dati con oltre 200.000 campioni e circa 50 funzioni per campione: 10 variabili continue e le altre ~ 40 sono variabili categoriali (paesi, lingue, campi scientifici ecc.). Per queste variabili categoriche, hai ad esempio 150 paesi diversi, 50 lingue, 50 campi scientifici ecc ...

Finora il mio approccio è:

  1. Per ogni variabile categoriale con molti valori possibili, prendi solo quella con più di 10000 campioni che accetta questo valore. Ciò riduce a 5-10 categorie anziché a 150.

  2. Costruisci una variabile fittizia per ciascuna categoriale (se 10 paesi quindi per ogni campione aggiungi un vettore binario di dimensione 10).

  3. Alimenta un classificatore di foresta casuale (convalida incrociata dei parametri ecc ...) con questi dati.

Attualmente con questo approccio, riesco solo ad ottenere una precisione del 65% e sento che si può fare di più. Soprattutto non sono soddisfatto del mio 1) poiché sento che non dovrei rimuovere arbitrariamente i "valori meno rilevanti" in base al numero di campioni che hanno, perché questi valori meno rappresentati potrebbero essere più discriminatori. D'altra parte, la mia RAM non può permettersi di aggiungere 500 colonne * 200000 righe ai dati mantenendo tutti i possibili valori.

Avresti qualche suggerimento per far fronte a queste variabili categoriche?


2
Se sei ancora interessato, potresti voler controllare la mia risposta sulla riduzione della dimensionalità e la mia risposta sulla classificazione gerarchica .
Aleksandr Blekh,

1
Quando dici "costruisci una variabile fittizia per ciascuna categorica" , sembra che tu stia usando Python non R? La foresta casuale può gestire nativamente i categorici, anche la conseguente riduzione della memoria. Prova R.
smci,

Risposte:


20

1) Le foreste casuali dovrebbero essere in grado di gestire i valori categorici in modo nativo, quindi cerca un'implementazione diversa in modo da non dover codificare tutte queste funzionalità e consumare tutta la tua memoria.

2) Il problema con le caratteristiche categoriche di alta cardinalità è che è facile adattarsi a queste. Potresti avere abbastanza dati che questo non è un problema, ma fai attenzione.

3) Suggerisco di esaminare la selezione casuale delle caratteristiche basate sulla foresta usando il metodo proposto da Brieman o contrasti artificiali . Il metodo dei contrasti artificiali (ACE) è interessante perché confronta l'importanza della funzione con l'importanza di una versione mescolata di se stessa che combatte alcuni dei problemi di alta cardinalità. Esiste un nuovo documento "Module Guided Random Forests" che potrebbe essere interessante se si disponessero di molte altre funzionalità in quanto utilizza un metodo di selezione delle funzionalità che è a conoscenza di gruppi di funzionalità altamente correlate.

4) Un'altra opzione utilizzata qualche volta è quella di modificare l'algoritmo in modo che utilizzi le custodie out-of-bag per fare la selezione della funzione finale dopo aver adattato le divisioni sulle custodie in bag che a volte aiutano a combattere l'eccessivo adattamento.

C'è un'implementazione quasi completa dell'asso qui e ho un'implementazione di memoria più veloce / veloce che gestisce nativamente le variabili categoriche qui ... l'opzione -evaloob supporta l'opzione 4 Sto lavorando per aggiungere supporto per ACE e un paio di altre RF basato su metodi di selezione delle funzionalità ma non è ancora stato fatto.


4
Tutti questi suggerimenti sono interessanti, concordo sul fatto che la foresta casuale dovrebbe gestire nativamente le variabili categoriche, ma scikit-learn non ... Penso che sia uno dei principali difetti di scikit tra l'altro. Proverò il tuo codice sui miei dati per vedere cosa succede e vedrò altri tuoi suggerimenti!
Bertrand R,

1
Prova l'implementazione R. Eseguirlo è una fodera. La lettura dei dati è estremamente semplice e c'è un'implementazione paralell nuova che è velocissima ed efficiente in termini di memoria: r-bloggers.com/… D'altra parte. Le tue lezioni sono squilibrate? nell'implementazione r puoi far crescere ogni albero da un campione bootstrap bilanciato sampsize = c (x, x). Ciò ha prodotto migliori classificazioni binarie per me. Puoi giocare con le dimensioni e modificare la classificazione molto facilmente usando gli output R della matrice di confusione OOB.
JEquihua,

2
L'implementazione randomForest di R consente fattori con un massimo di 32 livelli. scikit-learn è meno restrittivo, poiché consente di creare prima variabili fittizie (vedere la pandas.get_dummiesfunzione). L'implementazione di H2O della foresta casuale ha funzionato davvero bene per me (vedi 0xdata.com/docs/master/model/rf ).
Alex Woolford,

1
c'è un'implementazione più recente e più veloce della foresta casuale, il pacchetto si chiama ranger. Grandi cose davvero. Gli ordini di grandezza sono più veloci e non hanno un limite di 32 livelli.
Marbel

6

Invece di ridimensionare le tue categorie, perché non dovresti semplicemente utilizzare una singola variabile numerica per ciascuna? Nel contesto di foreste casuali, mi sono spesso chiesto delle conseguenze di farlo (perché sono d'accordo che sembra sospetto introdurre l'ordinalità nei dati categorici con cui se spesso non ha senso), ma in pratica (almeno con l'implementazione scikit-learning delle RF che ho usato), ho spesso osservato che non fa differenza sui risultati (non sono sicuro del perché).


1
Questo va bene per le caratteristiche categoriali con n <= 3 in quanto puoi generare tutte le stesse divisioni come considereresti nativamente come categoriche. Per n più grandi è possibile ottenere serie di divisioni equivalenti alla suddivisione categoriale ma l'algoritmo può o meno trovarle nel modo più efficiente ... tuttavia se si divide la funzione in n caratteristiche numeriche si riduce anche l'efficienza con cui l'algoritmo può trovare divisioni. Qualcuno ha bisogno di aggiungere il supporto categoriale variabile all'implementazione di scikit-learn in quanto è ottimo altrimenti.
Ryan Bressler,

Sono d'accordo con te quando dici che sembra sospetto introdurre l'ordinalità nei dati categorici ... Preferirei non doverlo fare, ma posso almeno provarlo e vedere cosa succede!
Bertrand R,

4
Ho avuto una lunga discussione su questa domanda nella mailing list di sklearn (puoi leggere alcune parti qui: mail-archive.com/scikit-learn-general@lists.sourceforge.net/… ). L'opinione di uno degli implementatori era che con alberi sufficientemente profondi, le caratteristiche categoriali con codifica ordinale potevano funzionare ragionevolmente bene (oltre ad essere più efficienti dal punto di vista computazionale). Ad ogni modo, se lo provi, sarei molto interessato a conoscere i tuoi risultati / conclusioni, in quanto questo è un problema che continuo a risolvere.
cjauvin,

1
Quindi ho cercato di mantenere una singola variabile numerica per quelle categoriche, e in realtà funziona sorprendentemente bene, e molto meglio dell'aggiunta di un gran numero di voci binarie ... Ho anche cercato di ordinare i valori in base al loro wrt medio sul target . E funziona anche bene
Bertrand R

Non sono sorpreso da questo in realtà .. è in linea con ciò che ho osservato in un paio di impostazioni diverse, anche se a giudicare dal numero di voti, questa è un'idea piuttosto controintuitiva.
cjauvin,

5

Penso che dovresti considerare una / più tecniche di riduzione variabile . Si sbarazza dei predittori non così influenti.

Ho letto molto sulla pre-elaborazione dei dati ed è un'ottima soluzione per ridurre il n ° delle tue variabili.

I miei suggerimenti sono i seguenti:

  • per variabili qualitative , sostituire i valori mancanti con la categoria "mancante". Può introdurre una distorsione se i dati non mancano in modo casuale, ma almeno avrai tutte le tue osservazioni intatte e la mancanza potrebbe rivelare un comportamento diverso.
  • elimina i predittori di varianza zero o predittori di varianza quasi zero (fai attenzione a non eliminare variabili fittizie con categorie sbilanciate elevate che possono separare la tua Y in modo efficiente. Crea dei grafici per le variabili che ritieni possano essere importanti). In R, è possibile utilizzare la 'nzv'funzione dal 'caret'pacchetto. Ciò ridurrà notevolmente la dimensione dei dati.
  • elimina i predittori correlati . Usa la matrice di correlazione di Kendall perché è più adatta da costruire in presenza di variabili categoriali. Il rovescio della medaglia è che devi trasformare tutti i tuoi parametri nominali in categorici.
  • ci sono metodi di selezione delle caratteristiche che ne ridurranno ulteriormente il numero (clustering: si sceglie un singolo rappresentante di ciascun cluster, la regressione LASSO, ecc ...). Non ho ancora avuto la possibilità di testarli perché gli altri passaggi hanno ridotto le mie variabili a meno di 100.

Inoltre, suggerirei di utilizzare l' algoritmo AdaBoost invece della RF. Personalmente, le ricerche che ho fatto mi hanno dato coefficienti Gini molto simili per entrambi questi metodi. La parte buona di AdaBoost è che in R, gestisce le osservazioni mancanti. Quindi puoi saltare il primo passaggio di questo elenco

Spero che abbia aiutato un po '. In bocca al lupo


4

Potresti prendere in considerazione modelli a effetti misti. Sono popolari nelle scienze sociali a causa della loro performance su dati categorici ad alta cardinalità e li ho usati per creare grandi modelli predittivi che superano gli approcci di apprendimento automatico popolare come alberi potenziati a gradiente, foreste casuali e regressione logistica regolarizzata a rete elastica. L'implementazione più nota è il pacchetto lme4 di R; la funzione che useresti per la classificazione è più brillante, che implementa la regressione logistica ad effetti misti. Potresti avere problemi con il ridimensionamento del tuo set di dati, ma ho fatto 80k righe con 15 funzionalità senza troppe difficoltà.


2
  1. Quando dici "costruisci una variabile fittizia per ciascuna categorica" , sembra che tu stia usando Python non R? La foresta casuale può gestire nativamente i categorici, anche la conseguente riduzione della memoria. Prova R.

  2. Successivamente, non è necessario potare / unire manualmente i livelli categorici, il che sembra un grande dolore. E anche se lo facessi, non sei sicuro che le categorie più popolose siano le più predittive. Controlla la complessità della foresta casuale con il parametro nodesize : inizia con un nodo di grandi dimensioni e ridurlo progressivamente (questa è la ricerca dell'iperparametro).

  3. La selezione delle variabili sarà utile. @lorelai dà buoni consigli. Cerca di eliminare le funzioni inutili (di bassa importanza o altamente correlate). La costruzione dell'albero è quadratica rispetto al numero di funzioni, quindi se ne elimini un terzo pagherà i dividendi.


0

Dovresti guardare il pacchetto H2O.ai. Gestisce le variabili categoriche fuori dalla scatola senza dover eseguire alcuna codifica (assicurarsi che le variabili siano fattori).

Mi piace particolarmente la loro implementazione di Gradient Boosted Machine (GBM) perché puoi quindi vedere l'importanza variabile dopo aver creato il modello. I GBM hanno anche la bella caratteristica di essere resistenti agli overfitting.

Se vuoi esplorare altri modelli, hanno: GLM, Random Forest, Naive Bayes, Deep Learning, ecc.

Vedi: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/gbm.html

È anche facile da installare (Windows, Linux, Mac) e facile da eseguire con le API usando R, Python, Java e Scala.

Può usare più core per velocizzare le cose.

Nel prossimo futuro, supporteranno le GPU.

È anche open source e gratuito (c'è il supporto Enterprise).

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.