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

不平衡数据集交叉验证洗牌后F1反而更高,原因何在?

不平衡数据集交叉验证:洗牌与不洗牌的F1得分差异问题

我正在处理一个不平衡数据集,奇怪地发现交叉验证时若对数据洗牌,得到的F1 score较高;若不洗牌,F1 score则较低。以下是我使用的交叉验证函数:

def train_cross_v(md,df_train,n_folds=5,shuffl=False):

        X,y=df_train.drop([variable],axis=1),df_train[variable]
    
        cv =StratifiedKFold(n_splits=n_folds,shuffle=shuffl)

        scores = cross_val_score(md,X,y, scoring='f1', cv=cv, n_jobs=-1)

        y_pred=cross_val_predict(md,X,y, cv=cv, n_jobs=-1)
        print(' f1: ',scores,np.mean(scores))
        print(confusion_matrix(y_pred,y))
        return np.mean(scores)

洗牌时,F1约为0.82:

nfolds=5
train_cross_v(XGBClassifier(),df_train,n_folds=nfolds,shuffl=True)
f1:  [0.81469793 0.82076749 0.82726257 0.82379249 0.82484862] 0.8222738195197493
[[23677  2452]
[ 1520  9126]]
0.8222738195197493

不洗牌时的结果:

nfolds=5
train_cross_v(XGBClassifier(),df_train,n_folds=nfolds,shuffl=False) 

f1:  [0.67447073 0.55084022 0.4166443  0.52759421 0.64819164] 0.5635482198057791
[[21621  5624]
[ 3576  5954]]
0.5635482198057791

我原本认为洗牌能消除数据顺序相关依赖,更能评估模型真实性能,且通常洗牌后性能指标会更低,但我的情况恰好相反:洗牌后F1更高,且测试集预测值无变化。这可能是什么问题?


问题分析

  • 原始数据的类别特征分布失衡:虽然用了StratifiedKFold保证每折的类别比例与整体一致,但如果原始数据是按类别或相关特征排序的(比如多数类集中在前半段,少数类集中在后半段),不洗牌时,部分折的训练集里少数类样本的特征分布会过于集中,模型无法充分学习到少数类的判别模式。洗牌后,每折训练集的少数类样本特征分布更均匀,模型能更好捕捉少数类特征,从混淆矩阵能明显看出:不洗牌时少数类召回率仅约51%,洗牌后提升至约78%,直接拉高了对少数类敏感的F1得分。

  • 数据顺序引入伪相关性:如果数据是按采集批次、时间等非分类维度排序的,同一折内的数据可能带有相同的噪声或偏置(比如某批次特征普遍偏高),模型训练时会学到这种批次特征而非真实分类特征,跨折验证时就会失效。洗牌打破了这种顺序依赖,让模型学习到通用的分类特征,性能自然提升。

  • 对“洗牌后性能更低”的认知误区:这种预期只适用于数据本身存在有意义顺序结构的场景(比如时间序列,洗牌会破坏时序依赖)。你的数据显然没有这种有效顺序,反而顺序带来了数据分布偏差,洗牌纠正了偏差,因此性能反而更高。

内容的提问来源于stack exchange,提问作者Sunny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:31:00