Проблемы с двоичным One-hot (one-of-K) кодированием в python

двоичное one-hot (также известное как one-of-K) кодирование заключается в создании одного двоичного столбца для каждого отдельного значения для категориальной переменной. Например, если у вас есть столбец цвета (категориальная переменная), который принимает значения "красный", "синий", "желтый" и "неизвестный", то двоичное однократное кодирование заменяет столбец цвета столбцами двоичных файлов "цвет=красный", "цвет=синий" и "цвет=желтый". Я начинаю с данных в фрейме данных pandas, и я хочу использовать эти данные для обучения модели с помощью scikit-learn. Я знайте два способа сделать двоичное одно-горячее кодирование, ни один из них не удовлетворяет меня.

  1. Панды и get_dummies в категориальных столбцах фрейма данных. Этот метод кажется отличным, поскольку исходный фрейм данных содержит все данных. То есть вы выполняете однократное кодирование перед разделением данных в наборах обучения, проверки и тестирования. Однако, если данные уже разделены в разных наборах, этот метод не работает очень что ж. Почему? Потому что один из наборов данных (скажем, тестовый набор) может содержать меньше значений для данной переменной. Например, может случиться так, что если обучающий набор содержит значения красного, синего, желтого и неизвестного для переменной цвета, то тестовый набор содержит только красный и синий. Таким образом, тестовый набор будет иметь меньше столбцов, чем учебный набор. (Я также не знаю, как сортируются новые столбцы, и если даже те же столбцы, это может быть в другом порядке в каждом набор.)

  2. Sklearn и DictVectorizer это решает предыдущую проблему, так как мы можем убедиться, что применяем одно и то же преобразование к тестовому набору. Однако результатом преобразования является массив numpy вместо фрейма данных pandas. Если мы хотим восстановить вывод в виде фрейма данных pandas, нам нужно (или, по крайней мере, так я это делаю): 1) панды.DataFrame (data=результат преобразования Диктвекторизатора, index=индекс исходных панд фрейм данных, столбцы= DictVectorizer ().get_features_names) и 2) объединить по индексу результирующий фрейм данных с исходным, содержащим числовые столбцы. Это работает, но это несколько громоздко.

есть ли лучший способ сделать двоичную горячую кодировку в кадре данных pandas, если у нас есть разделение данных в обучении и тестовом наборе?

2 ответов


Если ваши столбцы находятся в том же порядке, вы можете объединить dfs, используйте get_dummies, а затем разделить их обратно, например,

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

Если ваши столбцы не в том же порядке, то у вас будут проблемы независимо от того, какой метод вы пытаетесь.


вы можете установить тип данных в 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

посмотреть этот вопрос панд.