cross_validate 与 scoring
cross_validate 可同时返回多指标、训练分数和耗时;scoring 必须匹配任务与错误成本。
学习前需要掌握
背景与问题
交叉验证得到什么分数,取决于 scoring,而不是只由模型决定。估计器默认 score 可能是准确率或 R²;若直接接受默认值,很容易与业务真正关心的误差错位。
多指标输出可以帮助诊断,但用于选择模型的主指标和取舍规则应事先固定,避免事后挑选有利分数。
概念定义
cross_val_score 适合单指标,cross_validate 支持字典指标、return_train_score、fit_time 和 estimator。
直观理解
一场实验同时记录正确率、关键错误、稳定性和成本,而不是只留一项分数。
核心原理
scoring 可以是内置名称、评分器或多指标字典。评分器通常接收估计器、输入和真实标签,负责调用相应预测方法;需要概率的指标不能用硬标签随意替代。
scikit-learn 的评分方向统一为越大越好,因此 MAE、MSE 等损失常返回负值。负误差越接近零越好,报告业务误差时可以取反;不要按绝对值越大越好排序。
cross_validate 会分别返回各折验证分数、拟合时间与评分时间;return_train_score 可添加训练分数辅助观察过拟合。训练分数高不是好方案的充分证据,时间值还依赖硬件与并行设置。
自定义指标要明确参数、正类和零分母处理。return_estimator 适合需要分析折内状态时使用,会保存额外模型;指标平均方式也要与数据结构匹配,按折均值和全部折外预测统一计算可能不同。
数学表达
核心表达
预先指定主指标;附加指标用于诊断。return_estimator 会占内存,仅需要分析每折模型时开启。
变量含义
变量定义与本页概念定义一致,代码中的同名变量保持相同语义。
计算步骤
- 1定义主/次指标
- 2cross_validate
- 3转换负误差
- 4查看训练验证差距
代码对应位置
示例 1用常量回归手算负 MAE 的方向:固定 12 个目标值,用可手算的常量基线说明 scoring 的符号与结果键。
案例:负 MAE 只是评分方向约定
构造目标 0 到 11,按顺序做普通 3 折,每轮用训练均值作常量预测。三折真实 MAE 分别为 6、1、6,scoring 返回 −6、−1、−6,转回正误差后的折均值为 13 / 3。
这里有序 KFold 只为让算术可复核,不代表合适的时间预测协议。若误把最负的一折称为最好,就把优化方向读反了;下面代码同时展示返回键与取反步骤。
计算与实现步骤
- 定义主/次指标
- cross_validate
- 转换负误差
- 查看训练验证差距
- 报告耗时和波动
代码实现
示例 1
用常量回归手算负 MAE 的方向
example_01.py用途:固定 12 个目标值,用可手算的常量基线说明 scoring 的符号与结果键。
import numpy as np
from sklearn.dummy import DummyRegressor
from sklearn.model_selection import KFold, cross_validate
X = np.arange(12).reshape(-1, 1)
y = np.arange(12, dtype=float)
result = cross_validate(DummyRegressor(strategy="mean"), X, y,
cv=KFold(3), scoring={"mae": "neg_mean_absolute_error", "r2": "r2"},
return_train_score=True)
mae = -result["test_mae"]
assert np.allclose(mae, [6.0, 1.0, 6.0])
print("raw_scores:", result["test_mae"].tolist())
print("positive_mae:", mae.tolist())
print(f"fold_mean_mae={mae.mean():.3f}")代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
固定 12 个目标值,用可手算的常量基线说明 scoring 的符号与结果键。
X- 完整特征矩阵,每行一个样本、每列一个特征。
y- 目标标签或连续目标值。
mean- 训练特征逐列均值。
Step 1 · 1–3 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as np
from sklearn.dummy import DummyRegressor
from sklearn.model_selection import KFold, cross_validateStep 2 · 5–14 行
只从训练数据逐列计算均值与标准差,对应标准化公式中的 μ 和 σ。
X = np.arange(12).reshape(-1, 1)
y = np.arange(12, dtype=float)
result = cross_validate(DummyRegressor(strategy="mean"), X, y,
cv=KFold(3), scoring={"mae": "neg_mean_absolute_error", "r2": "r2"},
return_train_score=True)
mae = -result["test_mae"]
assert np.allclose(mae, [6.0, 1.0, 6.0])
print("raw_scores:", result["test_mae"].tolist())
print("positive_mae:", mae.tolist())
print(f"fold_mean_mae={mae.mean():.3f}")代码与数学原理
减去训练均值并除以训练标准差,对应代码中的 mean/std 或 StandardScaler。
预期输出或运行结果
本地 scikit-learn 1.8.0 的核对输出: raw_scores: [-6.0, -1.0, -6.0] positive_mae: [6.0, 1.0, 6.0] fold_mean_mae=4.333
常见错误 · 5 条
- 不要在测试集上调用 fit 或 fit_transform;测试集只能复用训练参数。
- 使用 estimator 默认 score 却没有核对分类或回归中的实际含义。
- 把负损失当成真实负误差,或者按绝对值最大选择最差候选。
- 多指标结果出来后才决定主指标,或把 fit_time 当作跨机器通用性能基准。
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 多指标实验
- 模型成本比较
常见错误
- 使用 estimator 默认 score 却没有核对分类或回归中的实际含义。
- 把负损失当成真实负误差,或者按绝对值最大选择最差候选。
- 多指标结果出来后才决定主指标,或把 fit_time 当作跨机器通用性能基准。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。