交叉验证策略
k 折、分层 k 折、留一法和时间序列拆分——了解分别何时使用
交叉验证策略 是 CoddyKit 上的免费 Learn AI with Python 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Learn AI with Python 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Learn AI with Python 课程共包含 4 节课。
为什么要交叉验证
单次训练集/测试集划分可能恰好有利,也可能恰好不利。交叉验证会在不同划分上重复评估并对得分取平均,从而更可靠地估计模型性能。
K 折交叉验证
KFold 会将数据划分为 K 个相等的部分。每一折都会恰好一次作为测试集,其余部分用于训练模型。这样可以得到 K 个得分并计算平均值。
from sklearn.model_selection import KFold
kf = KFold(n_splits=5, shuffle=True, random_state=0)
for train_idx, test_idx in kf.split(X):
Xtr, Xte = X[train_idx], X[test_idx]
ytr, yte = y[train_idx], y[test_idx]
# train and evaluate here用于分类的分层 K 折交叉验证
在分类任务中,普通 K 折可能产生类别比例不平衡的各折数据。StratifiedKFold 会保留每一折中的类别比例。
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
for train_idx, test_idx in skf.split(X, y):
# each fold keeps the same class balance as the full set
passcross_val_score 快捷方式
cross_val_score 会为您执行整个循环,并返回包含各折得分的数组。对于分类器,它会自动使用 StratifiedKFold。
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(random_state=0)
scores = cross_val_score(clf, X, y, cv=5, scoring="accuracy")
print(scores)
print("Mean:", scores.mean(), "Std:", scores.std())选择折数
更多的折数(例如 10 折)可以得到偏差更小的估计,但需要更多计算资源。5 折是常见的折中方案。对于非常小的数据集,留一法会使用 N 折,其中每个测试集都只包含一个样本。
from sklearn.model_selection import LeaveOneOut, cross_val_score
loo = LeaveOneOut()
scores = cross_val_score(clf, X, y, cv=loo)
print("Mean:", scores.mean())用于时间数据的 TimeSeriesSplit
对于时间序列,绝不能使用未来数据进行训练。TimeSeriesSplit 始终使用过去的数据进行训练,并使用下一个数据块进行测试,同时在各折之间逐步扩大训练窗口。
from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)
for train_idx, test_idx in tscv.split(X):
# train_idx always precedes test_idx in time
print(len(train_idx), len(test_idx))为什么时间序列中的顺序很重要
将按时间排序的数据打乱,会把未来信息泄漏到训练过程中,并使得分虚高。TimeSeriesSplit 遵循时间顺序,因此评估结果更接近真实的预测场景。
使用 cross_validate 评估多个指标
cross_validate 类似于 cross_val_score,但可以一次返回多个指标,还可以包含训练得分和拟合时间。
from sklearn.model_selection import cross_validate
results = cross_validate(
clf, X, y, cv=5,
scoring=["accuracy", "f1_macro", "roc_auc_ovr"],
return_train_score=True,
)
print(results["test_accuracy"])
print(results["test_f1_macro"])解读 cross_validate 输出
结果是一个字典,其中包含 test_<metric>、train_<metric>、fit_time 和 score_time 等键。比较训练得分与测试得分有助于诊断过拟合。
import numpy as np
gap = results["train_accuracy"].mean() - results["test_accuracy"].mean()
print("Overfit gap:", gap)
print("Avg fit time:", np.mean(results["fit_time"]))交叉验证与数据泄漏
始终要将预处理(缩放、编码)放在交叉验证循环内部进行,而不是提前处理。请使用 Pipeline,这样每一折都会只使用该折的训练数据进行缩放,从而避免数据泄漏。
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
pipe = make_pipeline(StandardScaler(), SVC())
scores = cross_val_score(pipe, X, y, cv=5)选择正确的策略
分类使用 StratifiedKFold,回归使用普通的 KFold,时间数据使用 TimeSeriesSplit。请将预处理封装在流水线中,并报告各折的平均值和标准差。
快速检查
测试您对交叉验证的掌握情况。
回顾
回顾:交叉验证会对多次划分的性能取平均。回归使用 KFold,类别均衡的分类任务使用 StratifiedKFold,时间数据使用 TimeSeriesSplit。cross_val_score 返回一个指标;cross_validate 返回多个指标以及计时信息。始终在 Pipeline 内部进行预处理,以防止数据泄漏。
常见问题解答
「交叉验证策略」课时是免费的吗?
是的 — 「交叉验证策略」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Learn AI with Python 课程的其余内容,请升级到 CoddyKit PRO。 Learn AI with Python 课程共包含 4 节课。
「交叉验证策略」这节课中我会学到什么?
k 折、分层 k 折、留一法和时间序列拆分——了解分别何时使用 你通过在浏览器中直接运行的动手代码来练习 Learn AI with Python,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Learn AI with Python 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Learn AI with Python 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「交叉验证策略」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Learn AI with Python 课中编写并运行代码吗?
能。每节 Learn AI with Python 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。