Как я могу выровнять панд get_dummies в процессе обучения / проверки / тестирования? - PullRequest
1 голос
/ 24 июня 2019

У меня есть 3 набора данных (обучение, проверка и тестирование), и при запуске:

    training_x = pd.get_dummies(training_x, columns=['a', 'b', 'c'])

Это дает мне определенное количество функций. Но потом, когда я проверяю данные проверки, мне дают другое и то же число для тестирования. Есть ли способ нормализовать (я знаю, что это неверное слово) для всех наборов данных, чтобы количество объектов совпадало?

Ответы [ 3 ]

2 голосов
/ 24 июня 2019

Макеты должны быть созданы до разделения набора данных на поезд, тест или подтверждение

предположим, что у меня есть поезд и тест фрейма данных следующим образом

import pandas as pd  
train = pd.DataFrame([1,2,3], columns= ['A'])
test= pd.DataFrame([7,8], columns= ['A'])

#creating dummy for train 
pd.get_dummies(train, columns= ['A'])

o/p
   A_1  A_2  A_3  A_4  A_5  A_6
0    1    0    0    0    0    0
1    0    1    0    0    0    0
2    0    0    1    0    0    0
3    0    0    0    1    0    0
4    0    0    0    0    1    0
5    0    0    0    0    0    1



# creating dummies for test data
pd.get_dummies(test, columns = ['A'])
    A_7  A_8
0    1    0
1    0    1

, поэтому манекен для категорий 7 и 8 будет толькоприсутствовать в тесте и, следовательно, будет иметь другую функцию

final_df = pd.concat([train, test]) 

dummy_created = pd.get_dummies(final_df)

# now you can split it into train and test 
from sklearn.model_selection import train_test_split
train_x, test_x = train_test_split(dummy_created, test_size=0.33)

Теперь поезд и тест будут иметь одинаковый набор функций

1 голос
/ 24 июня 2019

Как уже говорилось, обычно вы должны сделать одну горячую кодировку перед разделением. Но есть и другая проблема. Однажды вы наверняка захотите применить свою обученную модель ML к данным в дикой природе. Я имею в виду данные, которых вы раньше не видели, и вам нужно выполнить те же преобразования для манекенов, что и при обучении модели. Тогда вам придется иметь дело с двумя случаями.

  1. означает, что новые данные содержат категории, которых у вас не было в данных об обучении, и
  2. наоборот, категория больше не появляется в вашем наборе данных, но ваша модель была обучена этому. В случае 1. Вы должны просто игнорировать значение, так как ваша модель, скорее всего, не сможет с этим справиться, не обучаясь этому. В случае 2. вы все равно должны сгенерировать эти пустые категории, чтобы иметь ту же структуру в данных, которые вы хотите предсказать, как в вашем обучающем наборе. Обратите внимание, что метод pandas не будет генерировать пустышки для этих категорий и, следовательно, не может гарантировать, что вы получите ту же структуру из ваших данных прогнозирования, что и в ваших тренировочных данных, и, следовательно, скорее всего, ваша модель не будет применима к данным.

Вы можете решить эту проблему, используя sklearn, эквивалентный get_dummies (просто немного больше работы), который выглядит следующим образом:

import pandas as pd
from sklearn.preprocessing import OneHotEncoder

# create some example data
df= pd.DataFrame({'x': [1, 2, 3], 'y': [2, 4, 8]})

# create a one hot encoder to create the dummies and fit it to the data
ohe= OneHotEncoder(handle_unknown='ignore', sparse=False)
ohe.fit(df[['x']])

# now let's simulate the two situations A and B
df.loc[1, 'x']= 1
df= df.append(dict(x=5, y=5), ignore_index=True)

# the actual feature generation is done in a separate step
tr=ohe.transform(df[['x']])

# if you need the columns in your existing data frame, you can glue them together
df2=pd.DataFrame(tr, columns=['oh1', 'oh2', 'oh3'], index=df.index)
result= pd.concat([df, df2], axis='columns')

С помощью sklearn OneHotEncoder вы можете отделить идентификацию категорий от фактического горячего кодирования (создание манекенов). И вы также можете сохранить встроенный один горячий энкодер, чтобы иметь возможность применить его позже во время применения вашей модели. Обратите внимание на параметр handle_unknown, который сообщает одному горячему кодировщику, что в случае, если он обнаружит что-то неизвестное позже, он должен просто игнорировать это, вместо того, чтобы выдавать ошибку.

1 голос
/ 24 июня 2019

Вы можете преобразовать тип данных в category столбцов, которые необходимо преобразовать в фиктивную переменную

df.col_1=df.col_1.astype('category')
df1=df.iloc[:1,:].copy()
df2=df.drop(df1.index)
pd.get_dummies(df1,columns=['col_1'])
Out[701]: 
      col_2 col3  col_1_A  col_1_D  col_1_G  col_1_J
index                                               
0         B    C        1        0        0        0# it will show zero even missing in the sub-set
pd.get_dummies(df2,columns=['col_1'])
Out[702]: 
      col_2 col3  col_1_A  col_1_D  col_1_G  col_1_J
index                                               
1         E    F        0        1        0        0
2         H    I        0        0        1        0
3         K    L        0        0        0        1
...