数据采样和算法管道python

时间:2018-11-05 17:12:15

标签: python scikit-learn pipeline

如何将数据采样和分类器管道链接在一起?

我想对所有分类器执行所有采样技术,然后选择效果最好的分类器。我正在执行随机网格搜索以选择最佳超参数。

在每个未调整的分类器(Logistic回归l1,Logistic回归l2,随机森林)上仅执行6种采样技术,然后仅对每种采样技术执行得最好的一个分类器进行调整,是否合理?

在我以前的实现中,我发现adasyn在逻辑回归方面表现最佳,所以这是我目前的赢家。我已经使用每种采样技术实现了随机森林并对其进行了评分,但是我想弄清楚如何对其进行很好的打包和简化。

我主要使用imblearn和sklearn。

我的问题是:如何构造用于超参数,分类和采样的管道?

尝试1

oss= OneSidedSelection(random_state=RANDOM_STATE)
enn= SMOTEENN(random_state=RANDOM_STATE)
smtk= SMOTETomek(random_state=RANDOM_STATE)
ada= ADASYN(random_state=RANDOM_STATE)
ros= RandomOverSampler(random_state=RANDOM_STATE)
smote= SMOTE(random_state=RANDOM_STATE)

l1= make_pipeline(StandardScaler(),
                    LogisticRegression(random_state=RANDOM_STATE,penalty='l1'))
l2= make_pipeline(StandardScaler(),
                    LogisticRegression(random_state=RANDOM_STATE, penalty='l2'))
rf= make_pipeline(StandardScaler(),
                    RandomForestClassifier(random_state=RANDOM_STATE))

l1_pipeline = make_pipeline(oss, enn, smtk, ada, ros, smote, l1)
l2_pipeline = make_pipeline(oss, enn, smtk, ada, ros, smote, l2)
rf_pipeline = make_pipeline(oss, enn, smtk, ada, ros, smote, rf)

l1_pipeline.fit(X_train, y_train)
y_hat = l1_pipeline.predict(X_test)
print(classification_report_imbalanced(y_test, y_hat))

ATTEMPT 2

fitted_models = {}
fitted_methods = {}
for name, classification_algorithms in classification_algorithms.items():

oss= OneSidedSelection(random_state=RANDOM_STATE)
enn= SMOTEENN(random_state=RANDOM_STATE)
smtk= SMOTETomek(random_state=RANDOM_STATE)
ada= ADASYN(random_state=RANDOM_STATE)
ros= RandomOverSampler(random_state=RANDOM_STATE)
smote= SMOTE(random_state=RANDOM_STATE)

X_oss, y_oss= oss.fit_sample(X_train,y_train)
X_enn, y_enn= enn.fit_sample(X_train,y_train)
X_smtk, y_smtk= smtk.fit_sample(X_train,y_train)
X_ada, y_ada= ada.fit_sample(X_train,y_train)
X_ros, y_ros= ros.fit_sample(X_train,y_train)
X_smote, y_smote= smote.fit_sample(X_train,y_train)

print('named X, y')


model = RandomizedSearchCV(classification_algorithms, 
hyperparameters[name], \
                           cv=10, n_jobs=-1)

model_oss = model.fit(X_oss, y_oss)
print('One Sided Selection has been fitted.')
model_enn = model.fit(X_enn, y_enn)
print('SMOTE ENN has been fitted.')
model_smtk = model.fit(X_smtk, y_smtk)
print('SMOTE Tomek has been fitted.')
model_ada = model.fit(X_ada, y_ada)
print('ADASYN has been fitted.')
model_ros = model.fit(X_ros, y_ros)
print('Random Over Sampling has been fitted.')
model_smote = model.fit(X_smote, y_smote)
print('SMOTE has been fitted.')

fitted_models[name + model_oss] = model_oss
fitted_models[name + model_enn] = model_enn
fitted_models[name + model_smtk] = model_smtk
fitted_models[name + model_ada] = model_ada
fitted_models[name + model_ros] = model_ros
fitted_models[name + model_smote] = model_smote


print(name, 'has been fitted.')

超参数和分类管道

l1_hyperparameters = {
'logisticregression__C' : np.linspace(1e-3, 1e3, 10),
}

l2_hyperparameters = {
'logisticregression__C' : np.linspace(1e-3, 1e3, 10),
}
rf_hyperparameters = {
'randomforestclassifier__n_estimators': [100, 200],
'randomforestclassifier__max_features': ['auto', 'sqrt', 0.33]
}
hyperparameters = {
'l1' : l1_hyperparameters,
'l2' : l2_hyperparameters,
'rf' : rf_hyperparameters
}

classification_algorithms = {
'l1': make_pipeline(StandardScaler(),
                    LogisticRegression(random_state=RANDOM_STATE, 
penalty='l1')),
'l2': make_pipeline(StandardScaler(),
                    LogisticRegression(random_state=RANDOM_STATE, 
penalty='l2')),
'rf': make_pipeline(StandardScaler(),
                    RandomForestClassifier(random_state=RANDOM_STATE))
}

训练和测试集

X = df.drop('Class', axis=1)
y = df.Class
X_train, X_test, y_train, y_test = train_test_split(X, y, 
random_state=99)

1 个答案:

答案 0 :(得分:-1)

我个人不会尝试将采样技术应用到管道中,管道对象旨在作为一种健壮的端到端方法,用于将特征推到另一端并从另一端获取预测,主要是针对将模型概括为新数据

由于您不会过采样或欠采样或对新的看不见的数据点进行交叉验证,因此应在之前进行过采样/欠采样,交叉验证等操作,以便确定您希望管道的外观如何。

在您的情况下,您似乎已经做好了良好的腿部锻炼,您说您发现ADASYN和LogistRegression给了您最佳的结果,因此您的(伪)管道将成为

Out-of-pipe:
oversampled_X,y = Adasyn(X, y)

Pipeline:
{scaling/normalization if necessary,
 logisticregression with selected hyperparams}

pipeline.fit(oversampled_X,y) (or fit_transform(oversampled_X,y))

pipeline.predict(new_X)