Невозможно передать объединенный конвейер SMOTE и RandomUnderSampler в основной конвейер

В настоящее время я работаю с набором данных Imbalanced, и для обработки Imbalance я планирую объединить SMOTE и ADASYN с RandomUnderSampler, а также индивидуальную недостаточную выборку, передискретизацию, SMOTE и ADASYN (всего 6 способов выборки, которые я передам как параметр в GridSearchCV). Для этого я создал два конвейера.

Smote_Under_pipeline = imb_Pipeline([
     ('smote', SMOTE(random_state=rnd_state, n_jobs=-1)),
     ('under', RandomUnderSampler(random_state=rnd_state)),
])

Adasyn_Under_pipeline = imb_Pipeline([
     ('adasyn', ADASYN(random_state=rnd_state, n_jobs=-1)),
     ('under', RandomUnderSampler(random_state=rnd_state)), 
])

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

Main_Pipeline = imb_Pipeline([
     ('feature_handler', FeatureTransformer(list(pearson_feature_vector.index))),
     ('imb', Smote_Under_pipeline),
     ('scaler', StandardScaler()),
     ('pca', PCA(n_components=0.99)),
     ('model', LogisticRegression(max_iter=1750)),
])

FeatureTransformer () - это класс выбора функций:

class FeatureTransformer(BaseEstimator, TransformerMixin):

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

    def transform(self, X):
        return X[self.feature_vector]

Когда я вызываю Smote_Under_pipeline.fit () или Adasyn_Under_pipeline.fit (), он работает (пример кода ниже):

dumm_x, dumm_y = Smote_Under_pipeline.fit_resample(X_train, y_train)

Но когда я пытаюсь инициализировать Main_Pipeline в это время, интерпретатор выдает ошибку:

TypeError: All intermediate steps of the chain should be estimators that implement fit and transform or fit_resample. 'Pipeline(steps=[('smote', SMOTE(n_jobs=-1, random_state=42)),
            ('under', RandomUnderSampler(random_state=42))])' implements both)

Я использую конвейеры, предоставленные Imbalance-learn.

Я не могу понять ошибку. При использовании конвейеров scikit-learn все промежуточные оценщики имеют свои собственные методы fit () и fit_transform (), конвейеры imblearn предоставляют дополнительную функциональность обработки fit_resample ( ), который предоставляется обоими: Smote_Under_pipeline и Adasyn_Under_pipeline. Итак, его можно вызвать в Main_Pipeline, тогда почему возникает ошибка? Оба конвейера выборки также предоставляют метод fit () вместе с fit_resample (), это причина?


person Priyam Mehta    schedule 10.01.2021    source источник
comment
Сообщение об ошибке предполагает, что проблема в том, что Smote_Under_pipeline имеет как transform, так и fit_resample. Возможно, imblearn конвейеры должны решить, следует ли передискретизировать или преобразовать, и в этом случае неясно, что использовать? Может быть, лучше всего просто распаковать Smote_Under_pipeline, поместив сглаживание и недостаточную дискретизацию напрямую в более крупный конвейер?   -  person Ben Reiniger    schedule 10.01.2021
comment
@Ben Reiniger, но, поскольку RandomUnderSampler не имеет transform метода, Smote_Under_pipeline также не имеет transform метода. Присутствуют только методы fit и fit_resample. И в сообщении об ошибке должно присутствовать либо fit and transform, либо fit_resample. Поскольку transform отсутствует, первое условие не выполняется, а поскольку присутствует fit_resample, выполняется второе условие, то не следует ли его выполнять с использованием только fit_resample?   -  person Priyam Mehta    schedule 11.01.2021
comment
@BenReiniger Кроме того, о включении сглаживания и недостаточной дискретизации в более крупный конвейер, вы подразумеваете, что я должен поместить их в Main_Pipeline? Если это так, то, поскольку я упомянул, я хочу реализовать 6 способов обработки дисбаланса для сравнения всех, поэтому я не могу добавить сглаживание и недостаточную дискретизацию в Main_Pipeline. Если вы имеете в виду не это, я не смог понять, о чем вы говорите. Буду рад, если вы сможете уточнить. Спасибо.   -  person Priyam Mehta    schedule 11.01.2021
comment
Бен Рейнигер совершенно прав. Существует двусмысленность, поскольку конвейер несбалансированного обучения определяет как _1 _ / _ 2_, так и fit_resample. Решение состоит в том, чтобы сделать плоский трубопровод с избыточной выборкой, за которой следует недостаточная выборка. `` Main_Pipeline = imb_Pipeline ([('feature_handler', FeatureTransformer (list (pearson_feature_vector.index))), ('Smote', SMOTE ()), ('random_under_sampler', RandomUnderSampler ()), ('scaler', StandardScaler ()), ('pca', PCA (n_components = 0,99)), ('модель', LogisticRegression (max_iter = 1750)),]) ``   -  person glemaitre    schedule 11.01.2021


Ответы (1)


Чтобы подчеркнуть комментарий @ glemaitre, проблему вызывает конвейер (внутренний), который имеет как преобразование, так и повторную выборку.

Таким образом, выравнивание конвейера (включая ресамплеры непосредственно в основном конвейере) кажется решением. Вы можете протестировать различные стратегии передискретизации как гиперпараметры, отключив отдельные шаги:

Main_Pipeline = imb_Pipeline([
     ('feature_handler', FeatureTransformer(list(pearson_feature_vector.index))),
     ('oversamp', None),
     ('undersamp', None),
     ('scaler', StandardScaler()),
     ('pca', PCA(n_components=0.99)),
     ('model', LogisticRegression(max_iter=1750)),
])

param_space = {
    'oversamp': [None, SMOTE(...), ADASYN(...), RandomOverSampler(...)],
    'undersamp': [None, RandomUnderSampler(...)],
    ...,
}

Это даст 8 комбинаций, включая None-None и over-undersample в дополнение к тем, которые вы хотели. Но мне это кажется нормальным: было бы неплохо провести сравнение с конвейером без передискретизации, а избыточная недостаточная выборка аналогична комбинациям синт-недостаточная выборка.

person Ben Reiniger    schedule 11.01.2021
comment
Большое спасибо за такой подход !! - person Priyam Mehta; 11.01.2021
comment
Я не слишком знаком с imblearn, но меня беспокоит то, насколько они сбалансированы. Если oversamp уравновешивает классы, то RandomUnderSampler, вероятно, ничего не сможет сделать, но если oversamp балансирует только частично, то в паре с undersamp=None последние классы не будут сбалансированы. - person Ben Reiniger; 11.01.2021
comment
Вы правы, но поскольку мы не знаем, являются ли данные, сгенерированные / удаленные из выборки, полезными или шумными, иногда небольшая дополнительная передискретизация / недостаточная выборка сверх требуемой может привести к переобучению / недостаточной подгонке модели. Может случиться так, что идеально сбалансированный набор данных содержит больше шума, чем набор данных с небольшим дисбалансом. Итак, я думаю, что небольшой дисбаланс - это нормально. - person Priyam Mehta; 12.01.2021