R's randomForest non può gestire più di 32 livelli. Che cos'è la soluzione alternativa?


22

Il pacchetto randomForest di R non può gestire il fattore con più di 32 livelli. Quando riceve più di 32 livelli, emette un messaggio di errore:

Impossibile gestire i predittori categorici con più di 32 categorie.

Ma i dati che ho hanno diversi fattori. Alcuni di essi hanno più di 1000 livelli e altri ne hanno 100+. Ha persino lo "stato" degli Stati Uniti che è 52.

Quindi, ecco la mia domanda.

  1. Perché esiste una tale limitazione? randomForest si rifiuta di correre anche per il semplice caso.

    > d <- data.frame(x=factor(1:50), y=1:50)
    > randomForest(y ~ x, data=d)
      Error in randomForest.default(m, y, ...) : 
      Can not handle categorical predictors with more than 32 categories.

    Se è semplicemente dovuto alla limitazione della memoria, come può scikit learning randomForeestRegressor casuale eseguire con più di 32 livelli?

  2. Qual è il modo migliore per gestire questo problema? Supponiamo che io abbia X1, X2, ..., X50 variabili indipendenti e Y sia variabile dipendente. E supponiamo che X1, X2 e X3 abbiano più di 32 livelli. Cosa dovrei fare?

    Quello a cui sto pensando è l'esecuzione di un algoritmo di clustering per ciascuno di X1, X2 e X3 in cui la distanza è definita come differenza in Y. Eseguirò tre cluster in quanto vi sono tre variabili problematiche. E in ogni cluster, vorrei poter trovare livelli simili. E li unirò.

    Come suona?


La ricerca nel Web con il nome del pacchetto e il messaggio di errore fornisce alcune risposte.
Roland

5
@Roland In realtà mi porta qui ...
isomorfismi

1
potresti provare la scienza dei dati in quanto diverse menti statistiche hanno esperienza nella programmazione di dati con molte dimensioni.
aeroNotAuto

2
AGGIORNAMENTO: dalla versione 4.6-9, è in randomForestgrado di gestire predittori categoriali con un massimo di 53 livelli. Notizie
Ben

In che modo la foresta casuale di R determina il numero di livelli? Immagino che livello significhi categorie.
Aj

Risposte:


25

In realtà è un vincolo abbastanza ragionevole perché una divisione su un fattore con livelli è in realtà una selezione di una delle possibili combinazioni 2 N - 2 . Quindi anche con N come 25 lo spazio delle combinazioni è così grande che tale inferenza ha un senso minore.N2N-2N

La maggior parte delle altre implementazioni considera semplicemente il fattore come ordinale (cioè numeri interi da 1 a ), e questa è un'opzione su come risolvere questo problema. In realtà RF è spesso abbastanza saggio da dividere questo in gruppi arbitrari con diverse divisioni.N

L'altra opzione è quella di cambiare la rappresentazione - forse il tuo risultato non dipende direttamente dall'entità statale ma, ad esempio, area, popolazione, numero di alberi di pino pro capite o altri attributi possono essere invece inseriti nel tuo sistema informativo.

Può anche essere che ogni stato sia un'entità così isolata e non correlata da richiedere un modello separato per se stesso.

Il clustering basato su una decisione è probabilmente una cattiva idea perché in questo modo si trasferiscono informazioni dalla decisione in attributi, che spesso si traducono in un eccesso di adattamento.


4
Può essere facilmente spostato, anche se in modo leggermente noioso. Ad esempio, se hai tra 33 e 1024 livelli, crea due fattori ciascuno di <= 32 livelli.
KalEl,

15

Il motivo principale è come viene implementato randomForest. L'implementazione da R segue molto dalle specifiche originali Breiman. Ciò che è importante notare qui è che per le variabili fattore / categoriali, i criteri di divisione sono binari con alcuni valori di etichetta a sinistra e gli altri valori di etichetta a destra.

Ciò significa che cerca tutte le combinazioni di valori delle etichette di raggruppamento in due gruppi. Se si indica con il gruppo sinistro e con 1 il gruppo destro e si enumera per ogni etichetta una cifra, si otterrà un numero nell'intervallo [ 001[0;2M-1]

Perché le implementazioni di Weka e Python funzionano?

L'implementazione di weka non utilizza alberi CART per impostazione predefinita. Utilizza alberi C45 che non presentano questo problema computazionale, poiché per input categoriali si divide in più nodi, uno per ciascun valore di livello.

L'implementazione della foresta casuale di Python non può usare variabili categoriali / fattoriali. Devi codificare quelle variabili in variabili fittizie o numeriche.

Altre implementazioni potrebbero consentire più livelli (incluso weka qui) perché anche se usano CART, non implementano necessariamente due. Ciò significa che consentono di trovare la migliore divisione per una variabile fattore solo raggruppando un'etichetta rispetto a tutti gli altri valori. Ciò richiede un calcolo di gran lunga inferiore poiché deve controllare solo M punti di divisione.


2
Molte grazie! Dalla tua risposta segue che l'implementazione di R per il trattamento dei valori categorici è superiore a quella di Python (ricordo che Max Kuhn ha menzionato il raggruppamento delle variabili categoriali per RF fornisce risultati leggermente migliori rispetto a quelli che ne derivano), o almeno esegue Random Forest in R vs Python Ho ottime possibilità di ottenere risultati diversi (precisione, ecc ...)? In base alla tua esperienza, durante la modellazione, ha senso provare entrambi a raggruppare i var (in R) e a ridimensionarli e poi a confrontare due approcci?
Sergey Bushmanov,

2
La codifica fittizia funziona ma può produrre solo una categoria rispetto a tutte. Dopo la codifica, le variabili vengono testate una volta alla volta. Quindi, è impossibile implementare il due. Se questa funzione può aiutare, penso che praticamente non ci siano grandi differenze. Tuttavia, ci sono altre cose che potrebbero richiedere attenzione quando si lavora con importanza variabile: alcune implementazioni sono orientate verso categorie a più livelli. Vedi i documenti di Carolin Strobl per i dettagli: statistik.uni-dortmund.de/useR-2008/slides/Strobl+Zeileis.pdf . In R ci sono alcune implementazioni che non hanno questo pregiudizio.
Rapaio,

2

Potresti provare a rappresentare quella colonna in modo diverso. Potresti rappresentare gli stessi dati di un frame di dati sparsi.

Codice minimo praticabile;

example <- as.data.frame(c("A", "A", "B", "F", "C", "G", "C", "D", "E", "F"))
names(example) <- "strcol"

for(level in unique(example$strcol)){
      example[paste("dummy", level, sep = "_")] <- ifelse(example$strcol == level,     1, 0)
}

Notare come ogni valore nella colonna originale ora diventi una colonna fittizia separata.

Codice di esempio più ampio;

set.seed(0)
combs1 = sample.int(33, size= 10000, replace=TRUE)
combs2 = sample.int(33, size= 10000, replace=TRUE)
combs3 = combs1 * combs2 + rnorm(10000,mean=0,100)
df_hard = data.frame(y=combs3, first=factor(combs1), second=factor(combs2))

for(level in unique(df_hard$first)){
    df_hard[paste("first", level, sep = "_")] <- ifelse(df_hard$first == level, 1, 0)
}

for(level in unique(df_hard$second)){
    df_hard[paste("second", level, sep = "_")] <- ifelse(df_hard$second == level, 1, 0)
}

example$first <- NULL
example$second <- NULL

rf_mod = randomForest( y ~ ., data=example )

Anche se questo pezzo di codice mostra che effettivamente non otterrai più l'errore, noterai che l'algoritmo randomForest ora ha bisogno di molto tempo prima che finisca. Ciò è dovuto a un vincolo della CPU, è possibile mappare questa attività anche tramite campionamento ora.

Per ulteriori informazioni, consulta questo post sul blog:

https://blog.cloudera.com/blog/2013/02/how-to-resample-from-a-large-data-set-in-parallel-with-r-on-hadoop/


Il secondo blocco di codice sembra confuso, sebbene tu usi df_hard in tutto il corpo, alle ultime righe, imposti "first" e "second" su NULL, e usi anche "example" come dati per randomForest questo non ha senso io, dal momento che non esiste alcuna connessione tra esempio e df_hard.
Özgür,

Vincent, non pensi che finirò con problemi così grandi se avessi livelli dell'ordine di 100+, suggerisci di aggiungere ogni colonna come input a caso?
Hardik Gupta,

Un'altra alternativa è utilizzare l'implementazione di randomforest in h2o; questo ha un supporto migliore per set di dati di grandi dimensioni. Non capisco il bit "aggiungi ogni colonna come input per casuale".
Vincent Warmerdam,

0

È possibile invece utilizzare il pacchetto extraTrees. L'algoritmo di foreste estremamente randomizzate non prova alcun punto di interruzione / divisione, ma solo un sottoinsieme casuale di suddivisioni casuali.


1
extraTrees ha dei limiti, nel senso che il tuo input deve essere una matrice di dati numerici, giusto?
Hardik Gupta,

0

Un'altra opzione: a seconda del numero di livelli e del numero di osservazioni nei dati, è possibile unire alcuni livelli. Oltre a superare il limite, può ridurre la varianza se si hanno molti livelli con poche osservazioni. Hadley 's Forcats: fct_lump fa questo.

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.