StratifiedKFold比KFold更适合类别不平衡的分类任务,因其强制每折保持原始类别比例,避免某折缺失少数类;而KFold仅按索引均匀切分,不保障类别分布,易导致训练或评估失效。

分层K折交叉验证用 StratifiedKFold 而不是 KFold
如果你的数据类别分布不均衡(比如二分类中正样本只占5%),直接用 KFold 会导致某些折里完全没有正样本,模型根本训不了。这时候必须用 StratifiedKFold,它能保证每折中各类别比例和原始数据一致。
关键区别在于: KFold 只按索引切分,StratifiedKFold 会看 y 的标签分布再切分。所以调用时必须传入 y 参数,否则会报错 ValueError: The least populated class in y has only 1 member(常见于某类样本太少)。
- 初始化时设
n_splits=5就是5折,和KFold一样 - 加
shuffle=True和random_state=42才能复现实验结果 - 不能直接用
split(X),必须写成split(X, y),漏掉y就会失败
配合 cross_val_score 时要显式传 cv= 参数
很多人以为 cross_val_score 默认就是分层的,其实不是——它的默认 cv=5 等价于 KFold(n_splits=5),完全不分层。
正确做法是自己构造 StratifiedKFold 实例,再传给 cv:
from sklearn.model_selection import StratifiedKFold, cross_val_score from sklearn.ensemble import RandomForestClassifier <p>skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) scores = cross_val_score(RandomForestClassifier(), X, y, cv=skf, scoring='f1') </p>
注意:scoring 别用 'accuracy' 评估极度不平衡数据,容易虚高;优先选 'f1' 或 'average_precision'。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
手动遍历折数时,split() 返回的是索引元组
如果你想在每折上做额外操作(比如保存预测概率、分析各折特征重要性),就得手动循环。但 split() 不返回数据子集,只返回训练/测试索引:
for train_idx, test_idx in skf.split(X, y):
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
# 训练、预测、记录指标...
-
train_idx和test_idx是numpy.ndarray,可直接用于数组索引 - 如果
X是pandas.DataFrame,记得用.iloc[train_idx],不能直接用[train_idx] - 别在循环里重复创建模型实例——每次都要新建,否则权重会污染下一折
当某类样本数 时会报错
这是最常被忽略的硬限制:StratifiedKFold 要求每个类别的样本数 ≥ 折数。例如你有3个正样本、97个负样本,设 n_splits=5 就会崩,因为正样本没法平均分到5折里。
解决办法只有两个:
- 降低
n_splits(比如改用3折) - 换用
StratifiedShuffleSplit(它不保证“每折都含所有类”,但允许小样本类出现在部分折中)
后者适合探索性分析,但严格评估时仍推荐前者——毕竟交叉验证的核心前提是每折都能代表整体分布。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










