Создать свой пользовательский Imputer для категориальных переменных sklearn - PullRequest
3 голосов
/ 17 апреля 2020

У меня есть набор данных с большим количеством категориальных значений, и я хотел бы создать пользовательский импутер, который будет заполнять пустые значения значением, равным "no-variable_name".

Например, если столбец "Workclass" имеет значение Nan, замените его на "No Workclass".

Я делаю это так

X_train['workclass'].fillna("No workclass", inplace = True)

Но я хотел бы сделать Imputer, чтобы я мог передать его в конвейер.

Ответы [ 3 ]

2 голосов
/ 17 апреля 2020

Вы можете определить собственный трансформатор, используя TransformerMixin. Вот простой пример того, как определить простой преобразователь и включить его в конвейер:

df = pd.DataFrame({'workclass':['class1', np.nan, 'Some other class', 'class1', 
                                np.nan, 'class12', 'class2', 'class121'], 
                   'color':['red', 'blue', np.nan, 'pink',
                            'green', 'magenta', np.nan, 'yellow']})
# train test split of X
df_train = df[:3]
df_test = df[3:]

print(df_test)

  workclass    color
3    class1     pink
4       NaN    green
5   class12  magenta
6    class2      NaN
7  class121   yellow

Идея состоит в том, чтобы соответствовать, используя df_train фрейм данных, и реплицировать преобразования на df_test. Мы могли бы определить наш пользовательский класс преобразования, унаследованный от TransformerMixin:

from sklearn.pipeline import Pipeline
from sklearn.base import TransformerMixin

class InputColName(TransformerMixin):

    def fit(self, X, y):
        self.fill_with = X.columns
        return self

    def transform(self, X):
        return np.where(X.isna(), 'No ' + self.fill_with, X)

, затем включить его в свой конвейер (просто используя InputColName здесь, чтобы упростить пример) и дополнить его данными обучения:

pipeline = Pipeline(steps=[
  ('inputter', InputColName())
])
pipeline.fit(df_train)

Теперь, если мы попробуем преобразовать с невидимыми данными:

print(pd.DataFrame(pipeline.transform(df_test), columns=df.columns))

      workclass     color
0        class1      pink
1  No workclass     green
2       class12   magenta
3        class2  No color
4      class121    yellow
1 голос
/ 18 апреля 2020

Вы можете настроить simpleImputer вот так!

from sklearn.impute import SimpleImputer

class customImputer(SimpleImputer):
    def fit(self, X, y=None):
        self.fill_value = ['No '+c for c in X.columns]
        return super().fit(X, y)


df = pd.DataFrame({'workclass': ['classA', 'classB', np.NaN],
                   'fruit': ['apple',np.NaN,'orange']})
df

#   workclass   fruit
#0  classA  apple
#1  classB  NaN
#2  NaN orange

customImputer(strategy='constant').fit_transform(df)

#array([['classA', 'apple'],
#       ['classB', 'No fruit'],
#       ['No workclass', 'orange']], dtype=object)
0 голосов
/ 17 апреля 2020

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

from sklearn.preprocessing import FunctionTransformer

def custom_fillna(X):
    return X.fillna('NONE')

custom_imputer = FunctionTransformer(custom_fillna)
custom_imputer.transform(X)
...