2015-08-27 12 views
7

La codifica binaria one-hot (anche nota come one-of-K) consiste nel creare una colonna binaria per ogni valore distinto per una variabile categoriale. Ad esempio, se si ha una colonna di colore (variabile categoriale) che assume i valori "rosso", "blu", "giallo" e "sconosciuto", allora una codifica binaria one-hot sostituisce la colonna di colore con le colonne dei binari "color = rosso ',' colore = blu 'e' colore = giallo '. Comincio con i dati in un frame di dati panda e voglio utilizzare questi dati per addestrare un modello con scikit-learn. Conosco due modi per fare la codifica binaria di uno solo, nessuno di loro soddisfacente per me.Problemi con una codifica binaria one-of-K (one-of-K) in python

  1. Pandas e get_dummies nelle colonne categoriali del frame di dati. Questo metodo sembra eccellente fino a quando il frame di dati originale contiene tutti i dati disponibili. Cioè, fai la codifica one-hot prima di dividere i tuoi dati in training, validation e test set. Tuttavia, se i dati sono già suddivisi in set diversi, questo metodo non funziona molto bene. Perché? Perché uno dei set di dati (ad esempio, il set di test) può contenere meno valori per una determinata variabile. Ad esempio, può succedere che mentre il set di allenamento contiene i valori rosso, blu, giallo e sconosciuto per il colore variabile, il set di test contiene solo rosso e blu. Quindi il set di test finirebbe con meno colonne del set di allenamento. (Non so nemmeno come siano ordinate le nuove colonne, e se anche le stesse colonne abbiano, questo potrebbe essere in un ordine diverso in ciascun set).

  2. Sklearn e DictVectorizer Questo risolve il problema precedente, in quanto possiamo assicurarci che stiamo applicando la stessa trasformazione al set di test. Tuttavia, il risultato della trasformazione è una matrice numpy invece di una cornice dati panda. Se vogliamo recuperare l'output come frame di dati panda, dobbiamo (o almeno questo è il modo in cui lo faccio): 1) pandas.DataFrame (data = esito della trasformazione di DictVectorizer, index = indice dei dati originali di panda frame, columns = DictVectorizer(). get_features_names) e 2) uniscono lungo l'indice il frame di dati risultante con quello originale contenente le colonne numeriche. Funziona, ma è piuttosto ingombrante.

Esiste un modo migliore per fare un binario codifica un caldo all'interno di un data-frame panda se abbiamo la nostra scissione dei dati nel campo della formazione e di prova set?

+1

Beh, quello che faccio è concatenare i DFS, utilizzare get_dummies, e poi dividerli di nuovo, per esempio, 'codificati = pd.get_dummies (pd.concat ([treno, prova], asse = 0))' 'train_encoded = encoded.iloc [: train.shape [0],:]' ' test_encoded = encoded.iloc [train.shape [0] :,:]' – inversion

+0

Ma, d'altra parte, se il le colonne non sono nello stesso ordine, quindi il mio suggerimento non funzionerà. – inversion

+0

Grazie, @inversion Perché non trasformi il tuo commento in una risposta? – drake

risposta

9

Se le colonne sono nello stesso ordine, è possibile concatenare le DFS, utilizzare get_dummies, e poi li dividere di nuovo, per esempio,

encoded = pd.get_dummies(pd.concat([train,test], axis=0)) 
train_rows = train.shape[0] 
train_encoded = encoded.iloc[:train_rows, :] 
test_encoded = encoded.iloc[train_rows:, :] 

Se le colonne non sono nello stesso ordine, quindi avrai delle sfide indipendentemente dal metodo che provi.

0

È possibile impostare il tipo di dati a categorica:

In [5]: df_train = pd.DataFrame({"car":Series(["seat","bmw"]).astype('category',categories=['seat','bmw','mercedes']),"color":["red","green"]}) 

In [6]: df_train 
Out[6]: 
    car color 
0 seat red 
1 bmw green 

In [7]: pd.get_dummies(df_train) 
Out[7]: 
    car_seat car_bmw car_mercedes color_green color_red 
0   1  0    0   0   1 
1   0  1    0   1   0 

Vedi this issue di panda.