Препроцессор на основе sklearn ColumnTransformer выводит разные столбцы в наборе данных Train и Test - PullRequest
0 голосов
/ 26 мая 2020

Я пытался научиться использовать конвейеры и ColumnTransformer для эффективной предварительной обработки данных перед регрессией. Вот моя попытка:

  def preprocess_data(X):
    cat_var = X.select_dtypes(['bool','object']).columns
    num_var = X.select_dtypes(['int64','float64']).columns

    steps = [('c', Pipeline(steps=[('s',SimpleImputer(strategy='most_frequent')),
                                   ('oe',OneHotEncoder(handle_unknown='ignore'))]), cat_var),
             ('n', SimpleImputer(strategy='median'), num_var)]

    transformer = ColumnTransformer(transformers=steps, remainder='passthrough')


    X = transformer.fit_transform(X=X)

    return X

Проблема в том, что когда я трансформирую наборы данных для поезда и тестирования, он выбирает другое количество (Меньше) столбцов для тестового набора данных. Это означает, что модель, которую я обучил, не будет работать с тестовыми данными.

Я хорошо отредактировал код, и нет утечки данных или связанных с этим проблем

В чем может быть причина этого? Есть ли неисправность в моем logi c?

Я использую следующий набор данных

Спасибо!

Решение: также верните трансформатор как предварительно обработанные данные.

   return X, transformer 

Затем используйте объект-преобразователь для преобразования тестовых данных перед прогнозами

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Вы не можете использовать эту функцию для обучения и тестирования, потому что тогда вы дважды поместите fit_transform. Вам нужно подогнать трансформатор с обучающими данными, но преобразовать только для тестовых данных. Я рекомендую использовать для этого конвейер sklearn, который выполняет этот процесс автоматически, например, так:

pipeline = Pipeline(
[
    ('preprocessing', preprocessor),
    ('clf', MLalgorithm())
]

)

0 голосов
/ 26 мая 2020

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

import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder

train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")

COL = x.select_dtypes(['bool','object']).columns
pd.DataFrame({'var':COL,
              'n_train':[len(train[i].unique()) for i in COL],
              'n_test':[len(test[i].unique()) for i in COL]})


    var n_train n_test
0   MSZoning    5   6
1   Street  2   2
2   Alley   3   3
3   LotShape    4   4
4   LandContour 4   4
5   Utilities   2   2
6   LotConfig   5   5
7   LandSlope   3   3
8   Neighborhood    25  25
9   Condition1  9   9
10  Condition2  8   5
11  BldgType    5   5
12  HouseStyle  8   7
13  RoofStyle   6   6
14  RoofMatl    8   4
15  Exterior1st 15  14
16  Exterior2nd 16  16
17  MasVnrType  5   5
18  ExterQual   4   4
19  ExterCond   5   5
20  Foundation  6   6
21  BsmtQual    5   5
22  BsmtCond    5   5
23  BsmtExposure    5   5
24  BsmtFinType1    7   7
25  BsmtFinType2    7   7
26  Heating 6   4
27  HeatingQC   5   5
28  CentralAir  2   2
29  Electrical  6   4
30  KitchenQual 4   5
31  Functional  7   8
32  FireplaceQu 6   6
33  GarageType  7   7
34  GarageFinish    4   4
35  GarageQual  6   5
36  GarageCond  6   6
37  PavedDrive  3   3
38  PoolQC  4   3
39  Fence   5   5
40  MiscFeature 5   4
41  SaleType    9   10
42  SaleCondition   6   6

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...