无法将组合的 SMOTE 和 RandomUnderSampler 管道送入主管道
Not able to feed the combined SMOTE & RandomUnderSampler pipeline into the main pipeline
我目前正在使用不平衡数据集,为了处理不平衡,我计划将 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送入主pipeline,是这样的:
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:
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(),这是原因吗?
为了强调@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 和过度欠采样。但这对我来说似乎没问题:与无重采样管道进行比较会很好,并且过欠采样类似于合成欠采样组合。
我目前正在使用不平衡数据集,为了处理不平衡,我计划将 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送入主pipeline,是这样的:
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:
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(),这是原因吗?
为了强调@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 和过度欠采样。但这对我来说似乎没问题:与无重采样管道进行比较会很好,并且过欠采样类似于合成欠采样组合。