学习目标
完成本课后,你将能够:
- 将泛化能力解释为模型在目标环境新样本上的表现。
- 区分有限样本上的经验风险与未知分布下的期望风险。
- 解读训练误差与测试误差之间的差距,而不把它视为绝对保证。
- 根据类别、分组和时间选择数据划分方案。
- 识别数据泄漏和分布偏移的类型。
- 说明测试集评估的局限,以及部署后的监控必要性。
1. 泛化能力究竟意味着什么
泛化能力是指训练后的模型在未用于拟合参数的新样本上保持可接受性能的能力。“新”非常重要:模型会遇到不同的数据行、图像、文档或事件,但任务和应用条件应当与目标使用场景足够相似。例如,一个模型根据温度、振动和压力估计水泵故障风险。它在训练数据上表现良好,并不能证明它能识别另一台水泵、另一家工厂或下一个季节的故障。泛化关注规律的迁移,而不是对记录的记忆。
2. 从样本误差到期望风险
在 1.4.2 课中,我们学习了损失函数以及训练样本上的平均损失。有限样本上的平均损失称为经验风险。我们还关心另一种量:未来样本未知分布上的期望损失。用 P 表示目标环境的数据分布,用 f 表示模型,用 L 表示损失函数。期望风险按照 P 对可能的输入—目标组合的损失求平均。我们无法枚举所有未来情况,因此只能在有限样本上估计风险,并尽量保证样本独立且具有代表性。
3. 如何理解泛化差距
一个实用起点是比较训练集和独立测试集上的同一指标。如果测试误差明显更高,就出现了泛化差距。它可能提示过拟合,但不能单独说明原因:样本差异、测试集过小、数据泄漏或划分错误也可能造成这种现象。如果两种误差都很高,模型可能表达能力不足、特征较弱、数据噪声较大,或优化尚未完成。如果两种误差都较低,只有在实验设计有效且测试样本符合目标用途时,这才是积极信号。脱离上下文的数字不是证据。
4. 样本应反映未来的使用场景
随机划分并不总是合适。对于少数类分类,可以使用分层抽样,使各子集中的类别比例大致一致。如果多行数据属于同一患者、客户、设备或对象,应按组划分;否则模型可能在训练集和测试集中看到几乎相同的记录。对于时间序列的未来预测,不要随机打乱过去和未来。应使用较早时期训练,再用较晚时期评估。划分方案应模拟真实部署,而不是只为了得到方便的数字。
5. 数据泄漏:测试集何时失去独立性
当预测时不可获得的信息进入训练或数据准备流程时,就会发生数据泄漏。例如,在划分之前用完整数据集计算标准化统计量,会让测试数据影响训练转换。另一个例子是把只有在待预测事件发生之后才产生的字段作为特征。防护方法:先划分数据,再只在训练部分拟合预处理步骤。可以使用 Pipeline 将预处理和模型组合起来。还要检查时间戳、重复记录、相关分组、特征来源以及特征何时可用。隐蔽的数据泄漏也会让评估分数高得不真实。
6. 当应用环境本身发生变化
即使测试评估设计正确,它也只对应某个特定的数据分布。实际运行中,这个分布可能改变。特征偏移改变输入分布;类别先验偏移改变目标类别频率;概念偏移改变特征与结果之间的关系。例如,设备被更换、传感器重新校准,或运行条件发生变化。因此,泛化并不意味着“模型在任何地方、任何时候都有效”。测试分数回答的是相似条件下的问题;迁移到新环境需要单独验证。应监控输入数据、标签到达后的质量、不同分组的错误,并预先定义模型复核条件。
7. 测试集评估能够和不能够证明什么
独立测试集提供有用的估计,但存在统计不确定性。样本较小时,几个困难案例就可能明显改变结果。类别不平衡时,accuracy 可能很高,但重要的少数类却识别得很差。因此,应根据任务和错误成本选择指标;必要时报告样本量、不确定性区间或稳定性分析。不要反复使用测试集来选择特征、架构或阈值,否则测试集会逐渐变成另一个验证集。模型选择应使用验证集或交叉验证,最终测试集则保留用于独立评估。超参数调整将在 1.4.5 课介绍;交叉验证与稳定性会在后续单元展开。
8. 实用评估流程
在相信一个分数之前,先定义目标环境和预测时点;确定独立观测单位;选择能避免相关对象跨集合的划分方式;在查看测试结果前确定指标;把所有转换放在训练流程内部拟合;与简单基线比较;检查重要分组的错误;记录参数设置和实验随机种子。模型部署后仍需持续评估。数据分布和模型质量都可能变化。系统应有明确流程来发现性能退化、获取新标签、重新训练和回滚。泛化能力不是永久属性,而是在特定数据、时间和条件下得到支持的性能。
实践任务:设计一次诚实的模型评估
场景。 你正在建立一个模型,根据传感器测量值预测设备故障。表格中每台设备有多行记录,数据覆盖两年,故障标签在之后才登记。
- 确定独立观测单位:测量行还是设备。
- 如果目标是预测未见过的设备故障,提出一种划分方案;如果目标是预测已知设备下个月的故障,再提出一种方案。
- 指出至少三个可能的数据泄漏来源,并解释为什么不允许。
- 选择一个指标和一个基线模型。说明故障稀少时为什么 accuracy 可能不够。
- 提出部署后需要监控的两个信号。
优秀答案的标准:评估方案模拟真实使用场景,避免相关记录跨集合,并且不使用未来信息。
示例:避免数据泄漏的分类流程
# Python 3.10+;需要 pandas 和 scikit-learn
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import balanced_accuracy_score, classification_report
# target 是类别;特征在预测时已经可用。
df = pd.read_csv("equipment.csv")
X = df[["temperature", "vibration", "pressure"]]
y = df["target"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.25, random_state=42, stratify=y
)
# Pipeline 保证 StandardScaler 只在 X_train 上拟合。
model = make_pipeline(
StandardScaler(),
LogisticRegression(max_iter=1000, class_weight="balanced")
)
model.fit(X_train, y_train)
pred = model.predict(X_test)
print("Balanced accuracy:", balanced_accuracy_score(y_test, pred))
print(classification_report(y_test, pred))
# 不要反复用这个 test 集调整模型或阈值。
# 分组/时间数据需要使用其他划分方案。
参考资料与延伸阅读
课程术语表
自我检测
选择一个答案。检查后将显示解释。
问题 1
哪一项最能描述泛化能力?
问题 2
什么是期望风险?
问题 3
测试误差明显高于训练误差,正确结论是什么?
问题 4
多条记录属于同一位患者,应如何划分?
问题 5
为什么在划分之前进行标准化可能造成泄漏?
问题 6
为了预测时间序列的未来,应如何划分?
问题 7
可以反复根据测试集选择模型吗?
问题 8
环境发生变化后,原来的测试分数还能保证模型表现吗?