I have an imbalanced dataset and I am trying different methods to address the data imbalance. I found this article that explains the correct way to cross-validate when oversampling data using SMOTE technique.
I have created a model using AdaBoost algorithm and set the following parametres to be used in Grid Search:
ada = AdaBoostClassifier(n_estimators=100, random_state=42)
params = {
'n_estimators': [50, 100, 200],
'random_state': [42]
}
According to the article, this is the wrong way to oversample:
X_train_upsample, y_train_upsample = SMOTE(random_state=42).fit_sample(X_train, y_train)
# cross-validate using grid search
grid_naive_up = GridSearchCV(ada, param_grid=params, cv=kf,
scoring='recall').fit(X_train_upsample,
y_train_upsample)
grid_naive_up.best_score_
0.6715940782827282
# test set
recall_score(y_test, grid_naive_up.predict(X_test))
0.2824858757062147
Whereas the correct way to oversample is like so:
from imblearn.pipeline import Pipeline, make_pipeline
imba_pipeline = make_pipeline(SMOTE(random_state=42),
AdaBoostClassifier(n_estimators=100, random_state=42))
cross_val_score(imba_pipeline, X_train, y_train, scoring='recall', cv=kf)
new_params = {'adaboostclassifier__' + key: params[key] for key in params}
grid_imba = GridSearchCV(imba_pipeline, param_grid=new_params, cv=kf, scoring='recall',
return_train_score=True)
grid_imba.fit(X_train, y_train);
# How well do we do on our validation set?
grid_imba.best_score_
0.29015614186873506
# compare this to the test set:
y_test_predict = grid_imba.predict(X_test)
0.2824858757062147
So, according to the article, the first method is wrong because when upsampling before cross validation, the validation recall isn't a good measure of the test recall (28.2%). However, when using the imblearn pipeline for upsampling as part of the cross validation, the validation set recall (29%) was a good estimate of the test set recall (28.3%). According to the article, the reason for this is:
When upsampling before cross validation, you will be picking the most oversampled model, because the oversampling is allowing data to leak from the validation folds into the training folds.
Can anyone explain to me simply how the oversampling allows data to leak into the validation and causes the overfitting? And why does this problem not occur in the imblearn pipeline?