Несоответствие формы при обучении One-Hot-Encoding и данных испытаний.Train_Data имеет больше пустых столбцов, чем Test_data, при использовании get_dummies с конвейером - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь создать класс get_dummies для своих данных, который я хочу использовать позже в Pipeline:

class Dummies(BaseEstimator, TransformerMixin):
     def transform(self, df):
           dummies=pd.get_dummies(df[self.cat],drop_first=True) ## getting dummy cols
           df=pd.concat([df,dummies],axis=1) ## concatenating our dummies
           df.drop(self.cat,axis=1,inplace=True) ## dropping our original cat_cols

     def fit(self, df):
           self.cat=[]    
           for i in df.columns.tolist():    
               if i[0]=='c': ## My data has categorical cols start with 'c'  
                  self.cat.append(i)  ## Storing all my categorical_columns for dummies
              else:
                continue

Теперь, когда я вызываю fit_transform для X_train, а затем преобразую X_test

z=Dummies()
X_train=z.fit_transform(X_train)
X_test=z.transform(X_test)

Столбцы в форме X_train и X_test различны:

X_train.shape
X_test.shape

Вывод:

(10983, 1797) (3661, 1529)

Естьбольше чайников в X_train, чем в моем X_test.Ясно, что мой X_test имеет меньше категорий, чем X_train.Как мне написать логику в моем классе так, чтобы категории в X_test передавались в форме X_train?Я хочу, чтобы в X_test было столько же фиктивных переменных, сколько в моем X_train.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Если мы начнем с двух небольших примеров фреймов данных:

train = pd.DataFrame({'job=carpenter': [0, 1, 0],
                   'job=plumber': [0, 0, 1],
                   'job=electrician': [1, 0, 0]})

    job=carpenter   job=plumber  job=electrician
0               0             0                1
1               1             0                0
2               0             1                0


test = pd.DataFrame({'job=carpenter': [0, 1, 0],
                   'job=plumber': [1, 1, 0]})

    job=carpenter   job=plumber
0               0             1
1               1             1
2               0             0

Мы можем использовать словарное понимание, чтобы получить каждый столбец в наборе поездов, отсутствующий в тестовом наборе, и присвоить ему значение 0, который затем будет использоваться для добавления определенного столбца к тестовому набору и заполнения его нулями (поскольку ни одна строка в тестовом наборе для начала не содержала ни одной из этих пропущенных категорий):

train_cols = list(train.columns)
test_cols = list(test.columns)
cols_not_in_test = {c:0 for c in train_cols if c not in test_cols}
test = test.assign(**cols_not_in_test)

Это даетнам следующий тестовый фрейм данных:

test

   job=carpenter   job=plumber  job=electrician
0              0             1                0
1              1             1                0
2              0             0                0
0 голосов
/ 02 февраля 2019

Здесь вы хотите использовать (я думаю) OneHotEncoder scikit learn

from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncode(categories = "auto")
X_train_encoded = encoder.fit_transform("X_train")
X_test_encoded = encoder.transform("X_test")

Это сохраняет синтаксис fit_transform и гарантирует, что X_test_encoded имеет ту же форму, что и X_train_encoded.Его также можно использовать в конвейере, как вы упомянули, вместо Dummies().Пример:

pipe1=make_pipeline(OneHotEncoder(categories = "auto"), StandardScaler(), PCA(n_components=7), LogisticRegression())
0 голосов
/ 02 февраля 2019

Вы можете добавить оба кадра данных, а затем выполнить get_dummies ().

...