1

我目前正在使用不平衡数据集,为了处理不平衡,我计划将 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)), 
])

我的计划是将这两个管道输入主管道,如下所示:

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_pipelineAdasyn_Under_pipeline。那么,它可以在Main_Pipeline中调用,那为什么会抛出错误呢?两个采样管道都暴露了fit()方法以及fit_resample(),这是原因吗?

4

1 回答 1

0

为了强调@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。但这对我来说似乎没问题:与无重采样管道进行比较会很好,并且过度欠采样类似于合成器欠采样组合。

于 2021-01-11T14:42:40.553 回答