目 录CONTENT

文章目录

改进时间序列模型的五种交叉验证方法

Administrator
2026-02-10 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

📢 转载信息

原文链接:https://machinelearningmastery.com/5-ways-to-use-cross-validation-to-improve-time-series-models/

原文作者:Jason Brownlee


在时间序列预测中,我们经常需要对模型性能进行准确的评估。然而,由于时间序列数据中的观测值之间存在时间依赖性,标准的K折交叉验证(Cross-Validation, CV)方法可能导致评估结果过于乐观。

在处理时间序列数据时,我们不能随机地将数据分成训练集和测试集,因为这会打破数据的内在顺序,使模型在测试集上表现得像是在“作弊”,因为它利用了未来的信息(数据泄漏)。

本文将介绍五种专门用于时间序列预测的交叉验证方法,以确保模型评估的可靠性。

⚠️ 关键概念:时间序列交叉验证的挑战

标准的数据随机划分(如K折CV)假设数据点是独立同分布的(i.i.d.)。在时间序列中,这个假设不成立。对时间序列进行随机分割,模型在训练集中可能会看到未来的数据点,从而在测试集上给出过于乐观的性能估计。

正确的交叉验证策略必须确保:

  • 训练集中的所有观测值都发生在测试集观测值之前。
  • 训练集和测试集之间不存在数据泄漏。

以下是五种有效的方法。

5 ways to use cross-validation to improve time series models

1. 前向验证(Forward Chaining Cross-Validation)

前向验证,也称为“前向链式验证”或“滚动原点交叉验证”,是时间序列交叉验证最常用的方法之一。它通过逐步增加训练集的大小来模拟真实世界中的预测过程。

工作原理:

  1. 选择一个初始的训练集大小(通常是最小的合理大小)。
  2. 创建一个测试集,紧随训练集之后。
  3. 训练模型,评估性能。
  4. 扩展训练集,将前一个测试集也包含进去。
  5. 选择下一个测试集,紧随新的训练集之后。
  6. 重复此过程,直到所有数据都被用于测试。

示例:

假设我们有100个数据点,我们想要进行3次交叉验证(folds)。

  • Fold 1: 训练集 = [1-50],测试集 = [51-60]
  • Fold 2: 训练集 = [1-60],测试集 = [61-70]
  • Fold 3: 训练集 = [1-70],测试集 = [71-80]

这种方法确保了训练集始终是测试集在时间上的先驱。


2. 滑动窗口交叉验证(Sliding Window Cross-Validation)

滑动窗口是前向验证的一种变体,它保持训练集的固定大小,并通过“滑动”这个窗口来迭代数据。

工作原理:

  1. 定义一个固定的训练集大小(W)和一个固定的测试集大小(H)。
  2. 第一个训练集为 $T_1 = [1...W]$,测试集为 $V_1 = [W+1...W+H]$。
  3. 下一个训练集是 $T_2 = [2...W+1]$,测试集是 $V_2 = [W+2...W+H+1]$。
  4. 训练集和测试集一起向前移动一步,保持它们的大小不变。

何时使用:

当您认为最近的数据点比早期的观测值更具代表性时,滑动窗口方法非常有用。它强调了较新的数据,同时保持了固定的历史背景大小。


3. 修正的K折交叉验证(Modified K-Fold Cross-Validation)

标准K折交叉验证将数据分成K个大小相等的块,并轮流将其中一个块用作测试集。对于时间序列,我们不能随机选择块。

修正方法:

为了保持时间顺序,我们需要确保测试集中的所有数据都晚于训练集中的所有数据。我们可以将数据按时间顺序分成K个大小相等的块,并按顺序进行测试。

假设 $K=5$。数据被分割为 $B_1, B_2, B_3, B_4, B_5$。

  • Fold 1: 训练集 = $B_1, B_2, B_3, B_4$,测试集 = $B_5$
  • Fold 2: 训练集 = $B_1, B_2, B_3$,测试集 = $B_4$ (注意:这里通常会使用更大的训练集,但核心思想是测试集必须是时间上最新的)

更标准的修正方法是:

  • Fold 1: 训练集 = $B_1$,测试集 = $B_2$
  • Fold 2: 训练集 = $B_1, B_2$,测试集 = $B_3$
  • Fold 3: 训练集 = $B_1, B_2, B_3$,测试集 = $B_4$
  • Fold 4: 训练集 = $B_1, B_2, B_3, B_4$,测试集 = $B_5$

这实际上与前向验证非常相似,只是划分的粒度不同(按数据块而不是按单个时间步)。


4. 块交叉验证(Blocked Cross-Validation)

块交叉验证旨在解决时间序列数据中存在的“自相关性”问题。

问题:

即使我们保证了训练集在时间上早于测试集,如果测试集内部的数据点是高度相关的(例如,如果测试集 $V$ 中所有点都来自同一个时间段,比如一个特定的季节或一周),模型评估也可能不准确。

解决方案:

将整个数据集划分为几个不重叠的“块”,这些块在时间上是连续的,并且足够大,以包含数据的内在时间结构。

  1. 将数据分成 $K$ 个块 $B_1, B_2, ..., B_K$。
  2. 在第 $k$ 次迭代中,使用 $B_k$ 作为测试集,将所有其他块 $B_1, ..., B_{k-1}, B_{k+1}, ..., B_K$ 合并作为训练集。

关键限制:

这种方法要求我们在训练集中保留测试集之前的所有数据。因此,在实际操作中,我们通常需要一个“验证集”来存储早期数据,或者使用前向验证/滑动窗口方法。

在实践中,如果序列被分成 $K$ 个块,只有在 $B_k$ 是数据序列的最后 $1/K$ 部分时,这种方法才完全符合时间序列的要求。否则,它可能引入数据泄漏。


5. 时间序列保持交叉验证(Time Series Holdout Cross-Validation)

这是最简单、最直接的方法,本质上是将标准数据集拆分扩展到多个时间点的保持集中。

工作原理:

我们定义一个固定的验证时间点验证窗口,将早于该时间点的所有数据用于训练,将晚于该时间点(或在该窗口内)的数据用于验证。

步骤:

  1. 选择一个“截止点”(Cutoff point)或一组截止点。
  2. 训练集: 所有发生在截止点之前的数据。
  3. 测试集: 所有发生在截止点之后的数据。

这更像是标准的训练/测试分割,但强调了时间顺序。如果我们需要多次评估,我们可以使用多个不同的截止点(如在方法1和2中描述那样)。

何时使用:

当您只需要对模型进行一次最终评估,并且拥有足够多的历史数据时,这非常有效。它最能模拟模型在生产环境中(未来)的性能。


总结与建议

对于时间序列预测,随机K折交叉验证是不适用的。您需要采用能够尊重数据时间顺序的方法。

对于大多数时间序列项目,前向验证(Forward Chaining)是最可靠、最常用的方法,因为它能系统地评估模型在不同时间点上的表现,并利用所有可用数据。

如果您对模型的近期表现更感兴趣,可以考虑滑动窗口,它能让模型始终基于一个固定长度的“近期历史”进行训练。




🚀 想要体验更好更全面的AI调用?

欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。

0

评论区