TimeSeriesSplit
训练窗口始终早于验证窗口,可设置 gap 模拟标签延迟或隔离边界。
学习前需要掌握
背景与问题
预测未来时,训练数据只能来自当时已经可获得的信息。普通随机 K 折可能用未来记录训练,再回头预测过去,即使没有重复样本,也会得到不符合使用方式的结果。
时间验证需要模拟实际更新频率、训练窗口和预测跨度,尤其要检查标签何时成熟、滞后特征使用了哪些时段。
概念定义
时间序列验证常用扩展窗口,后轮包含更多历史但从不随机打乱未来。
直观理解
每次都用过去预测下一段未来,时间箭头不能反转。
核心原理
TimeSeriesSplit 按输入顺序使用较早行训练、较晚行验证,默认是逐渐扩大的训练窗口。它不会读取时间戳替你排序,调用前必须按真实时间组织数据。
test_size 控制每折验证样本数,max_train_size 可限制训练窗口,gap 在训练与验证间留出若干行。gap 的单位是样本数,并不是自动理解的天数;不规则采样时,等行数也不意味着等时间跨度。
间隔要与标签窗口、延迟和特征构造匹配。例如未来多天的累计结果作为标签时,靠近验证起点的训练标签可能尚未可得,需要相应清除或延迟。只设一个任意 gap 不能保证没有未来信息。
多实体时间序列还要定义同一时间点和同一实体的边界。评价过去到未来、旧实体到新实体是不同目标;对时间漂移明显的任务,旧时期的均值分数也可能掩盖最近窗口的退化。
数学表达
核心表达
数据先排序;窗口长度、测试跨度和 gap 必须模拟真实预测频率。多实体时还需结合群组。
变量含义
变量定义与本页概念定义一致,代码中的同名变量保持相同语义。
计算步骤
- 1按时间排序
- 2确定预测跨度
- 3设置训练窗口/test_size/gap
- 4窗口内 fit 预处理
代码对应位置
示例 1打印并核对前向训练、间隔与验证范围:使用已按时间顺序排列的构造行,直接检查真实索引关系;未训练模型。
案例:12 个等间隔时点的前向划分
构造索引 0 到 11 的时间序列,用 3 折、每折验证 2 行、gap 为 1。第一折训练 0 到 4,跳过 5,验证 6 到 7;第二折训练扩展到 6,验证 8 到 9;第三折训练到 8,验证 10 到 11。
这个例子只说明索引规则。如果一行代表一天,则间隔是一日;若一天有多条记录,就不能继续把 gap=1 称为一天。实际还应按时间戳检查预测时点能够获得哪些输入与标签。
计算与实现步骤
- 按时间排序
- 确定预测跨度
- 设置训练窗口/test_size/gap
- 窗口内 fit 预处理
- 逐窗口评价
- 观察随时间变化
代码实现
示例 1
打印并核对前向训练、间隔与验证范围
example_01.py用途:使用已按时间顺序排列的构造行,直接检查真实索引关系;未训练模型。
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
X = np.arange(12).reshape(-1, 1)
cv = TimeSeriesSplit(n_splits=3, test_size=2, gap=1)
for train, valid in cv.split(X):
gap = int(valid[0] - train[-1] - 1)
assert gap == 1
assert train[-1] < valid[0]
print(f"train={train[0]}..{train[-1]}, valid={valid[0]}..{valid[-1]}, gap={gap}")代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
使用已按时间顺序排列的构造行,直接检查真实索引关系;未训练模型。
X- 完整特征矩阵,每行一个样本、每列一个特征。
Step 1 · 1–2 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import numpy as np
from sklearn.model_selection import TimeSeriesSplitStep 2 · 4–10 行
输出中间参数、形状或最终指标,用于核对代码是否符合预期。
X = np.arange(12).reshape(-1, 1)
cv = TimeSeriesSplit(n_splits=3, test_size=2, gap=1)
for train, valid in cv.split(X):
gap = int(valid[0] - train[-1] - 1)
assert gap == 1
assert train[-1] < valid[0]
print(f"train={train[0]}..{train[-1]}, valid={valid[0]}..{valid[-1]}, gap={gap}")预期输出或运行结果
本地 scikit-learn 1.8.0 的核对输出: train=0..4, valid=6..7, gap=1 train=0..6, valid=8..9, gap=1 train=0..8, valid=10..11, gap=1
常见错误 · 4 条
- 以为 TimeSeriesSplit 会自动根据时间列排序,或先随机打乱再调用。
- 把 gap 的行数当作固定时长,忽略采样不规则与标签观察窗口。
- 在生成滞后、滚动统计或目标编码时先使用全部未来信息,再期望划分器修复。
- 确认样本轴、特征轴以及 X 与 y 的第一维完全对应。
实际应用
- 需求预测
- 流失与设备预测
常见错误
- 以为 TimeSeriesSplit 会自动根据时间列排序,或先随机打乱再调用。
- 把 gap 的行数当作固定时长,忽略采样不规则与标签观察窗口。
- 在生成滞后、滚动统计或目标编码时先使用全部未来信息,再期望划分器修复。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。