Problemy z binarnym kodowaniem one-hot (one-of-K) w Pythonie

Kodowanie binarne one-hot (znane również jako one-of-K) polega na tworzeniu jednej kolumny binarnej dla każdej odrębnej wartości dla zmiennej kategorycznej. Na przykład, jeśli mamy kolumnę kolorów (zmienną kategoryczną), która przyjmuje wartości 'red', 'blue', 'yellow' i 'unknown', to kod binarny one-hot zastępuje kolumnę kolorów kolumnami binarnymi 'color=red', 'color=blue' I 'color=yellow'. Zaczynam od danych w ramce danych pandy i chcę wykorzystać te dane do szkolenia modelu z scikit-learn. I znam dwa sposoby na zrobienie binarnej jedynki-hot coding, żaden z nich mi nie odpowiada.

  1. Pandy i get_dummies w kolumnach kategorycznych ramki danych. Ta metoda wydaje się doskonała, o ile oryginalna ramka zawiera Wszystkie dostępne dane. Oznacza to, że wykonujesz kodowanie one-hot przed podzieleniem danych na zestawy treningowe, walidacyjne i testowe. Jeśli jednak dane są już podzielone na różne zestawy, metoda ta nie działa zbyt dobrze. Dlaczego? Ponieważ jeden z zestawy danych (np. zestaw testowy) mogą zawierać mniej wartości dla danej zmiennej. Na przykład może się zdarzyć, że podczas gdy zestaw treningowy zawiera wartości czerwony, niebieski, żółty i Nieznany dla zmiennej Kolor, Zestaw testowy zawiera tylko czerwony i niebieski. Tak więc zestaw testowy skończyłby mieć mniej kolumn niż zestaw treningowy. (Nie wiem też, jak są sortowane nowe kolumny, a jeśli nawet mają te same kolumny, może to być w innej kolejności w każdym zestawie).

  2. Sklearn i DictVectorizer {[6] } to rozwiązuje poprzedni problem, ponieważ możemy upewnić się, że stosujemy tę samą transformację do zestawu testowego. Jednak wynikiem transformacji jest tablica numpy zamiast ramki danych pandy. Jeśli chcemy odzyskać dane wyjściowe jako ramka danych pandy, musimy (a przynajmniej tak to robię): 1) pandy.DataFrame (data=wynik transformacji DictVectorizer, index=Indeks oryginalnej ramki danych, columns= DictVectorizer ().get_features_names) i 2) Połącz wzdłuż indeksu wynikową ramkę danych z oryginalną zawierającą kolumny liczbowe. To działa, ale jest nieco uciążliwe.

Czy jest lepszy sposób na kodowanie binarne jedno-gorące w ramce danych pandy, jeśli mamy nasz podział danych w zestawie treningowym i testowym?

Author: drake, 2015-08-27

2 answers

Jeśli Twoje kolumny są w tej samej kolejności, możesz połączyć dfs, użyć get_dummies, a następnie podzielić je z powrotem, np.

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:, :] 

Jeśli Twoje kolumny nie są w tej samej kolejności, będziesz miał wyzwania niezależnie od metody, którą wypróbujesz.

 9
Author: inversion,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-28 01:25:02

Możesz ustawić swój typ danych na categorical:

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

Zobacz ten numer pand.

 0
Author: Tarantula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 00:32:08