多分类不平衡小样本建模:分层K折与交叉验证使用疑问
3类不平衡小样本多分类模型的交叉验证流程疑问
我正在构建一个针对3类不平衡小样本(共436个样本)的多分类模型,目前的流程如下:
1. 原始数据拆分
数据标准化后,我用StratifiedKFold做5折拆分,保证少数类在训练集和测试集的分布合理:
sss = StratifiedKFold(n_splits=5, random_state=None, shuffle=False)#尝试过5/10/15/20折 for train_index, test_index in sss.split(X, y): #print("Train:", train_index, "Test:", test_index) original_Xtrain, original_Xtest = X.iloc[train_index], X.iloc[test_index] original_ytrain, original_ytest = y.iloc[train_index], y.iloc[test_index]
2. 训练集专属处理
我知道特征选择和过采样仅需应用于训练集,所以对拆分后的训练集做了SMOTE过采样(这一步之前已经完成特征选择):
smote = SMOTE('not majority') X_sm, y_sm = smote.fit_resample(original_Xtrain, original_ytrain) print(X_sm.shape, y_sm.shape)
3. 模型评估的疑问
之后我用SMOTE过采样后的训练集训练模型,但对交叉验证的设置拿不准:应该沿用之前的分层拆分参数,还是重新设置新的5折拆分,或是用ShuffleSplit?
目前我是这么写评估代码的:
for key, classifier in classifiers.items(): classifier.fit(X_sm, y_sm) training_score1 = cross_val_score(classifier, X_sm, y_sm,scoring=make_scorer(f1_score, average='macro'),error_score="raise", cv=5) print("Classifiers: ", classifier.__class__.__name__, "Has a training score of", round(training_score1.mean(), 2) * 100, "% F1 score") training_score2 = cross_val_score(classifier, X_sm, y_sm,scoring=make_scorer(roc_auc_score, average='macro',multi_class='ovo', needs_proba=True),error_score="raise", cv=5) print("Classifiers: ", classifier.__class__.__name__, "Has a training score of", round(training_score2.mean(), 2) * 100, "% Roc_auc score")
我两种方式都试过,发现用新的cv=5参数结果更优。我觉得在不平衡数据场景下StratifiedKFold可以替代train_test_split,不需要在交叉验证里再用,但不确定这个想法对不对。想请教我的流程有没有遗漏或者错误?
内容的提问来源于stack exchange,提问作者Ibtissam
相关产品推荐
相关产品推荐

