这个问题与我之前的问题相似但不同。我有一个与银行客户流失相关的二元分类任务。该数据集包含 10,000 个实例和 11 个特征。目标变量不平衡(80% 仍然是客户(0),20% 流失(1))。
最初,我采用了这种方法:我首先将数据集拆分为训练集和测试集,同时在两组中保留目标变量的 80-20 比率。我在训练集中保留了 8,000 个实例,在测试集中保留了 2,000 个。预处理后,我用 SMOTEENN 解决了训练集中的类不平衡问题:
from imblearn.combine import SMOTEENN
smt = SMOTEENN(random_state=random_state)
X_train, y_train = smt.fit_sample(X_train, y_train)
现在,我的训练集有 4774 个 1 和 4182 个 0。我知道继续构建 ML 模型。我使用 scikit-learn 的 GridSearchCV 和 cv = KFold(n_splits=5, shuffle=True, random_state=random_state) 并根据召回分数进行优化。例如,对于随机森林分类器:
cv = KFold(n_splits=5, shuffle=True, random_state=random_state)
scoring_metric='recall'
rf = RandomForestClassifier(random_state=random_state)
param_grid = {
'n_estimators': [100],
'criterion': ['entropy', 'gini'],
'bootstrap': [True, False],
'max_depth': [6],
'max_features': ['auto', 'sqrt'],
'min_samples_leaf': [2, 3, 5],
'min_samples_split': [2, 3, 5]
}
rf_clf = GridSearchCV(estimator=rf,
param_grid=param_grid,
scoring=scoring_metric,
cv=cv,
verbose=False,
n_jobs=-1)
best_rf_clf = rf_clf.fit(X_train, y_train)
y_pred = cross_val_predict(best_rf_clf.best_estimator_,X_train, y_train,cv=cv)
print('Train: ', np.round(recall_score(y_train, y_pred), 3))
y_pred = best_rf_clf.best_estimator_.fit(X_train, y_train).predict(X_test)
print(' Test: ', np.round(recall_score(y_test, y_pred), 3))
我在训练集上的召回 CV 分数是0.902,而在测试中的分数是0.794。
但是,当在完整数据集上应用 SMOTEENN 然后拆分为训练集和测试集时,我在训练集上得到的召回 CV 分数等于0.913,而对于测试集则为0.898。
我们如何解释这两种方法之间的差异?与第二种方法(SMOTEENN 然后拆分)相比,是什么导致第一种方法(拆分然后 SMOTEENN)中的两组之间存在这种差距?我的猜测是,与第一种方法(1607 1s、393 0s)相比,第二种方法会导致更平衡的测试集(1220 1s、1036 0s)。谢谢!