如何将数据采样和分类器管道链接在一起?
我想对所有分类器执行所有采样技术,然后选择效果最好的分类器。我正在执行随机网格搜索以选择最佳超参数。
在每个未调整的分类器(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)
答案 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)