Есть ли способ связать pd.cut FunctionTransformer в конвейере sklearn? - PullRequest
3 голосов
/ 18 июня 2020

Я работаю над созданием конвейера предварительной обработки DataFrame, используя sklearn и связывая различные типы шагов предварительной обработки.

Я хотел связать преобразователь SimpleImputer и FunctionTransformer, применяя pd.qcut (или pd.cut), но я продолжаю получать следующую ошибку:

ValueError: входной массив должен быть одномерным

Вот мой код:

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import FunctionTransformer

class FeatureSelector(BaseEstimator, TransformerMixin):
    def __init__(self, features):
        self._features = features

    def fit(self, X, y=None):
        return self

    def transform(self, X, y=None):
        return X[self._features]

fare_transformer = Pipeline([
    ('fare_selector', FeatureSelector(['Fare'])),
    ('fare_imputer', SimpleImputer(strategy='median')),
    ('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])

То же самое происходит, если я просто связываю преобразователь FeatureSelector и FunctionTransformer с pd.qcut и опускаю SimpleImputer:

fare_transformer = Pipeline([
    ('fare_selector', FeatureSelector(['Fare'])),
    ('fare_bands', FunctionTransformer(func=pd.qcut, kw_args={'q': 5}))
])

Я тщательно искал stackoverflow и google, но не смог найти решения этой проблемы. Любая помощь здесь будет принята с благодарностью!

1 Ответ

2 голосов
/ 18 июня 2020

sklearn уже имеет такой преобразователь, KBinsDiscretizer (чтобы соответствовать pd.qcut, используйте strategy='quantile').

Но обычно эта ошибка означает, что ваша функция qcut применяется только к 1D-массиву, тогда как FunctionTransformer отправляет весь фрейм данных. Вы можете определить тонкую оболочку вокруг qcut, чтобы это работало, например

def frame_qcut(X, y=None, q=10):
    return X.apply(pd.qcut, axis=0, q=q)

(при условии, что вы получите фрейм данных)

...