RepeatedStratifiedKFold 更稳定的原因是通过反复打乱和分层,稀释单次随机划分的方差,从而更准确地估计模型泛化能力,而不是提高性能;适用于中小规模平衡数据,但计算成本大,样本小,容易报错,不适用时间数据。RepeatedStratifiedKFold 为什么比普通人好? StratifiedKFold 更稳?
由于单层交叉验证容易受到随机种子的影响,评价结果波动较大;RepeatedStratifiedKFold 通过多次重复(例如 5 次)+ 每次重新打乱 + 保持每次分层比例一致,稀释单次方差,最终取平均值和标准差,更可靠地反映模型的真实泛化能力。
注:它不是“提高模型性能”,而是“更准确地估计模型性能”。假如你只跑一次 StratifiedKFold(n_splits=5),结果可能偏高或偏低; RepeatedStratifiedKFold(n_splits=5, n_repeats=10) 跑 50 折叠,稳定性显著提高。
直接传给 cross_val_score 或 cross_val_predict 可以,但要注意参数含义的变化:
-
n_splits每次重复都要打几折(比如) 5),不是总折数 -
n_repeats是重复次数(如 3),总 CV 折数 =n_splits × n_repeats -
random_state控制每次重复的中断模式,不设定不同的操作结果
示例:
立即学习“Python免费学习笔记(深入);
Python 3.14.2
Python 3.14.2是Python编程语言于2025年12月5日发布的稳定版本,属于3.14系列的第二次维护更新。该版本包含18个修复项目,重点解决多过程、数据和正则表达模块的回归问题,修复CVE-2025-12084等安全漏洞。这个版本标志着Python发展的一个重要里程碑,即自由线程模式(删除GIL)正式得到官方支持。
下载from sklearn.model_selection import RepeatedStratifiedKFold, cross_val_score from sklearn.ensemble import RandomForestClassifier <p>cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=3, random_state=42) scores = cross_val_score(RandomForestClassifier(), X, y, cv=cv, scoring='f1_macro')</p><h1>scores.shape == (15,) —— 5×3=15 个分数</h1><p>在什么情况下不应该用? RepeatedStratifiedKFold?
适用于中小型数据集(n_samples 几百到几万)、当类别相对平衡,您关心评估指标的信心范围时。但要注意几个现实约束:
- 计算费用翻倍:10 次重复 × 5 折 = 50 第二次模型训练比单次模型训练好 5 折慢 10 倍
- 小样本下的分层可能会失效:如果只有一个类别 3 个样本,
n_splits=5会导致一些折中,这种类型会导致一些折中 0,触发ValueError: The least populated class in y has only 1 member - 时间序列或有结构的数据(如患者多次就诊记录)不能直接使用,会破坏时间序列/依赖关系
cross_val_score 只回到一维数组,想看每次重复的折叠性能,或者调试一次 split 手动迭代训练/验证集:
cv = RepeatedStratifiedKFold(n_splits=3, n_repeats=2, random_state=42)
for i, (train_idx, val_idx) in enumerate(cv.split(X, y)):
print(f"Split {i}: train size={len(train_idx)}, val size={len(val_idx)}")
# i 从 0 到 5(3×2)每次预测、特征重要性等都可以相应保存
注意:i 编号线性增加,不区分“重复多少次”;如需重复分组,建议使用 enumerate(cv.split(...), 1) 配合整除运算,或改用 list(cv.split(...)) 先缓存再切片。
真正容易被忽视的是:RepeatedStratifiedKFold 分层逻辑作用于 每次重复前 y,不是全局重采样—这意味着即使是某一类 split 中间分布略有偏差,只要整体比例稳定,就被认为是“分层成功”。所以不要指望它解决极端不平衡的问题,那就是 imblearn 或自定义 cv 的事。