You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多分类不平衡小样本建模:分层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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:33:25