stringhe come funzioni nell'albero decisionale / foresta casuale


64

Sto riscontrando alcuni problemi su un'applicazione dell'albero decisionale / foresta casuale. Sto cercando di adattare un problema che ha numeri e stringhe (come il nome del paese) come funzionalità. Ora la libreria, scikit-learn prende solo i numeri come parametri, ma voglio iniettare le stringhe oltre a portare una notevole quantità di conoscenza.

Come gestisco un simile scenario?

Posso convertire una stringa in numeri tramite alcuni meccanismi come l'hash in Python. Ma vorrei conoscere le migliori pratiche su come vengono gestite le stringhe nei problemi dell'albero decisionale.


In caso di sckitlearn ho visto che dobbiamo codificare le variabili categoriali, altrimenti il ​​metodo fit genererebbe un errore che dice ValueError: impossibile convertire la stringa in float
Kar

Risposte:


56

Nella maggior parte dei sistemi di apprendimento automatico consolidati, le variabili categoriche sono gestite in modo naturale. Ad esempio in R useresti i fattori, in WEKA useresti le variabili nominali. Questo non è il caso di scikit-learn. Gli alberi decisionali implementati in scikit-learn utilizzano solo funzioni numeriche e queste funzionalità vengono sempre interpretate come variabili numeriche continue .

Pertanto, la semplice sostituzione delle stringhe con un codice hash dovrebbe essere evitata, poiché essendo considerata una caratteristica numerica continua qualsiasi codifica che utilizzerai indurrà un ordine che semplicemente non esiste nei tuoi dati.

Un esempio è codificare ['rosso', 'verde', 'blu'] con [1,2,3], produrrebbe cose strane come 'rosso' è inferiore a 'blu', e se in media un 'rosso' e un "blu" otterrai un "verde". Un altro esempio più sottile potrebbe accadere quando si codifica ['basso', 'medio', 'alto'] con [1,2,3]. In quest'ultimo caso potrebbe capitare di avere un ordinamento che abbia un senso, tuttavia, potrebbero insorgere alcune sottili incongruenze quando "medio" non è nel mezzo di "basso" e "alto".

Infine, la risposta alla tua domanda sta nel codificare la funzione categoriale in più funzioni binarie . Ad esempio, potresti codificare ['rosso', 'verde', 'blu'] con 3 colonne, una per ogni categoria, con 1 quando la categoria corrisponde e 0 altrimenti. Questo si chiama codifica one-hot, codifica binaria, codifica one-of-k o altro. Puoi consultare la documentazione qui per la codifica di caratteristiche categoriche e l' estrazione di funzioni - hashing e dicts . Ovviamente una codifica a caldo amplierà i tuoi requisiti di spazio e talvolta danneggia anche le prestazioni.


2
È l'implementazione di scikit che non gestisce correttamente le variabili categoriali. Ricodificare come suggerisce questa risposta è probabilmente il meglio che puoi fare. L'utente più serio potrebbe cercare un pacchetto alternativo.
SmallChess,

3
Si può usare sklearn.preprocessing.LabelBinarizer per la codifica a caldo di una variabile categoriale.
GuSuku,

@rapaio Penso che la codifica binaria non sia la stessa codifica a caldo. La codifica binaria è quando si rappresentano 8 categorie con 3 colonne o tra 9 e 16 categorie con 4 colonne e così via. Ho sbagliato?
Alok Nayak,

il pacchetto python patsy si occuperà della codifica one-hot di variabili categoriali. patsy.readthedocs.io/en/latest/quickstart.html
zhespelt

5
Non utilizzare LabelBinarizer, utilizzare sklearn.preprocessing.OneHotEncoder . Se stai utilizzando Panda per importare e pre-elaborare i tuoi dati, puoi anche farlo direttamente utilizzando Panda.get_dummies . Fa schifo che scikit-learn non supporti le variabili categoriali.
Ricardo Cruz,

11

Devi codificare le tue stringhe come caratteristiche numeriche che sci-kit può usare per gli algoritmi ML. Questa funzionalità è gestita nel modulo di preelaborazione (ad esempio, vedere sklearn.preprocessing.LabelEncoder per un esempio).


4
rapaio spiega nella sua risposta perché questo avrebbe ottenuto un risultato errato
Keith,

7

Di solito dovresti codificare a una sola variabile le variabili categoriali per i modelli di apprendimento di scikit, inclusa la foresta casuale. La foresta casuale spesso funziona bene senza la codifica a caldo, ma di solito funziona meglio se si esegue la codifica a caldo. La codifica one-hot e le variabili "fittizie" significano la stessa cosa in questo contesto. Scikit-learn ha sklearn.preprocessing.OneHotEncoder e Pandas ha pandas.get_dummies per raggiungere questo obiettivo.

Tuttavia, ci sono alternative. L'articolo "Beyond One-Hot" su KDnuggets fa un ottimo lavoro nel spiegare perché è necessario codificare variabili categoriche e alternative alla codifica one-hot.

Esistono implementazioni alternative di foreste casuali che non richiedono una codifica a caldo come R o H2O. L'implementazione in R è computazionalmente costosa e non funzionerà se le tue funzionalità hanno molte categorie . H2O funzionerà con un gran numero di categorie. Continuum ha reso H2O disponibile in Anaconda Python.

È in corso uno sforzo per far sì che scikit-learn gestisca direttamente le caratteristiche categoriche .

Questo articolo ha una spiegazione dell'algoritmo utilizzato in H2O. Fa riferimento al documento accademico A Streaming Parallel Decision Tree Algorithm e una versione più lunga dello stesso documento.


5

Aggiornamento 2018!

È possibile creare uno spazio di incorporamento (vettore denso) per le variabili categoriali. Molti di voi hanno familiarità con word2vec e fastext, che incorporano le parole in uno spazio vettoriale denso e significativo. Stessa idea qui: le variabili categoriali verranno mappate su un vettore con un certo significato.

Dalla carta Guo / Berkhahn :

L'incorporamento di entità non solo riduce l'utilizzo della memoria e accelera le reti neurali rispetto alla codifica a caldo, ma soprattutto mappando valori simili vicini l'uno all'altro nello spazio di incorporamento rivela le proprietà intrinseche delle variabili categoriali. Lo abbiamo applicato con successo in una recente competizione Kaggle e siamo riusciti a raggiungere la terza posizione con caratteristiche relativamente semplici.

Gli autori hanno scoperto che la rappresentazione di variabili categoriali in questo modo ha migliorato l'efficacia di tutti gli algoritmi di apprendimento automatico testati, inclusa la foresta casuale.

Il miglior esempio potrebbe essere l'applicazione della tecnica di Pinterest per raggruppare i pin correlati:

inserisci qui la descrizione dell'immagine

La gente di fastai ha implementato matrimoni categorici e creato un post sul blog molto bello con il taccuino demo compagno .

Dettagli e spiegazioni aggiuntivi

Una rete neurale viene utilizzata per creare gli incorporamenti, ovvero assegnare un vettore a ciascun valore categoriale. Una volta che hai i vettori, puoi usarli in qualsiasi modello che accetta valori numerici. Ogni componente del vettore diventa una variabile di input. Ad esempio, se hai utilizzato i vettori 3D per incorporare l'elenco categorico dei colori, potresti ottenere qualcosa del tipo: rosso = (0, 1,5, -2,3), blu = (1, 1, 0) ecc. Ne useresti tre input di variabili nella foresta casuale corrispondenti ai tre componenti. Per le cose rosse, c1 = 0, c2 = 1.5 e c3 = -2.3. Per le cose blu, c1 = 1, c2 = 1 e c3 = 0.

In realtà non è necessario utilizzare una rete neurale per creare incorporamenti (anche se non consiglio di allontanarsi dalla tecnica). Sei libero di creare i tuoi ornamenti a mano o in altro modo, quando possibile. Qualche esempio:

  1. Mappa i colori ai vettori RGB.
  2. Mappare le posizioni su lat / long vettori.
  3. In un modello politico americano, mappare le città su alcuni componenti vettoriali che rappresentano l'allineamento sinistra / destra, il carico fiscale, ecc.

Va bene ma a meno che non mi sia perso qualcosa, questo è per le reti che iniziano a finire. Come possiamo creare un incorporamento e poi passarlo in un Forrest? Immagino che devi allenare un'intera rete con tutte le funzionalità e quindi prendere i primi livelli e usarla come funzionalità di input per Forrest. Non è chiaro come questo sarebbe fatto.
Keith l'

@Keith viene utilizzata una rete neurale per creare gli incorporamenti, ovvero assegnare un vettore a ciascun valore categoriale. Una volta che hai i vettori, puoi usarli in qualsiasi modello che accetta valori numerici. Ogni componente del vettore diventa una variabile di input. Ad esempio, se hai utilizzato i vettori 3D per incorporare l'elenco categorico dei colori, potresti ottenere qualcosa del tipo: rosso = (0, 1.5, -2.3), blu = (1, 1, 0)ecc. Nella foresta casuale dovresti utilizzare tre variabili di input corrispondenti ai tre componenti. Per le cose rosse, c1 = 0, c2 = 1.5 e c3 = -2.3. Per le cose blu, c1 = 1, c2 = 1 e c3 = 0.
Pete

Capisco perfettamente il concetto poiché è piuttosto semplice. Voglio dire come si farebbe nell'implementazione? Il notebook demo fast.ai che colleghi ha un po 'con un RandomForestRegressor alla fine, ma non vedo davvero come questo si aggiunge negli incorporamenti.
Keith

Penso che questo possa essere un buon esempio di codice in Keras github.com/entron/entity-embedding-rossmann
Keith

3

È possibile utilizzare variabili fittizie in tali scenari. Con i panda panda.get_dummiespuoi creare variabili fittizie per le stringhe che vuoi inserire in Decision Tree o Random Forest.

Esempio:

import pandas as pd
d = {'one' : pd.Series([1., 2., 3.,4.], index=['a', 'b', 'c','d']),'two' :pd.Series(['Paul', 'John', 'Micheal','George'], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)

df_with_dummies= pd.get_dummies(df,columns=["two"],drop_first=False)
df_with_dummies

2

Trasformali in numeri, ad esempio per ciascun paese unico fornendo un numero univoco (come 1,2,3 e ...)

inoltre non è necessario utilizzare la codifica One-Hot (ovvero variabili fittizie) quando si lavora con foreste casuali, perché gli alberi non funzionano come altri algoritmi (come la regressione lineare / logistica) e non funzionano a distanza (essi lavorare con la ricerca di una buona suddivisione per le funzioni), quindi NESSUN BISOGNO per la codifica One-Hot


1
In realtà dipende dall'algoritmo particolare che addestra l'albero. In particolare, scikit NON supporta variabili categoriali.
scegli il
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.