K 折交叉验证将数据分成 K 份,进行 K 次训练验证,充分利用数据提高评估稳定性。
基本步骤
- 将数据集随机拆分成 K 份
- 每次选择 1 份作为验证集,其余 K-1 份作为训练集
- 进行 K 次训练和验证
- 计算 K 次评估指标均值作为最终性能
示例(K=5)
第1次:训练集 [3,4,5,6,7,8,9,10],验证集 [1,2]
第2次:训练集 [1,2,5,6,7,8,9,10],验证集 [3,4]
第3次:训练集 [1,2,3,4,7,8,9,10],验证集 [5,6]
第4次:训练集 [1,2,3,4,5,6,9,10],验证集 [7,8]
第5次:训练集 [1,2,3,4,5,6,7,8],验证集 [9,10]代码实现
from sklearn.model_selection import KFold, cross_val_score
from sklearn.ensemble import RandomForestClassifier
kf = KFold(n_splits=5, shuffle=True, random_state=42)
model = RandomForestClassifier()
scores = cross_val_score(model, X, y, cv=kf, scoring='accuracy')
print("平均准确率:", scores.mean())K 值选择
| K 值 | 适用情况 | 特点 |
|---|---|---|
| 5 或 10 | 常用 | 平衡计算成本和稳定性 |
| K=N (LOOCV) | 超小数据集 | 计算量大,评估最稳定 |
| 过大 | 数据量大但不均匀 | 计算成本高 |
| 过小 | 数据少 | 评估不稳定 |
变体
分层 K 折(Stratified K-Fold)
适用于类别不均衡分类任务,确保每折类别分布与整体相似。
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True)时间序列 K 折
适用于时间序列数据,训练集时间点始终早于验证集。
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)方法对比
| 方法 | 适用场景 | 计算开销 |
|---|---|---|
| Hold-Out | 大数据集 | 低 |
| K-Fold | 适中数据量 | 中等 |
| Stratified K-Fold | 类别不均衡 | 中等 |
| Time Series Split | 时间序列 | 高 |
选择建议
- 数据量充足:K=5 或 K=10
- 类别不均衡:Stratified K-Fold
- 时间序列:Time Series Split
- 数据量极小:LOOCV