TATECHATLAS
◎ 简体中文
数学与模型 / 建议

使用 TimeSeriesSplit 和每步预测时界误差分析验证预测

通过 TimeSeriesSplit 实现时间有序的预测评估以防止数据泄漏,计算每个预测时界(Horizon)的独立误差,并选择与决策成本相匹配的严格一致性指标,从而量化预测质量随时间增加而下降的程度。

本文内容

使用 TimeSeriesSplit 生成时间有序的训练/测试折叠,确保每次评估仅使用过去的数据,随后为每个预测时界(forecast horizon)分别计算回归指标并对比这些每步时界的误差。最终指标不应是一个全局平均值,而应是关于误差如何随时界增长而变化的、与决策相关的汇总分析。选择一个严格一致的评分函数,例如针对中位数目标的 mean_absolute_error 或针对均值目标的 mean_squared_error,并将其同时用于训练损失和评估。这种对齐确保了指标能真实反映所选点预测的成本。例如,对于 12 个月度样本,TimeSeriesSplit(n_splits=3, test_size=2) 会创建三个折叠,每个测试集覆盖两个月,且训练集仅包含更早的月份。如果每步时界的 MAE 从时界 1 的 1.2 增加到时界 3 的 2.8,则意味着提前三个月的决策业务成本明显高于提前一个月。据此,您可以决定是否接受这种性能下降、增加特征或限制预测时界。该方法假设样本等距分布且采用点预测,而非完整的概率分布。

使用 TimeSeriesSplit 验证预测

TimeSeriesSplit 是一种专为时间有序数据设计的交叉验证器。它通过确保模型仅在过去观测值上训练并在随后的时间有序折叠上进行评估,从而防止数据泄漏。标准交叉验证方法不适用于时间序列,因为它们可能会使用未来数据训练并评估过去数据。TimeSeriesSplit 返回的训练和测试索引确保每个测试集的时间窗口都晚于其对应的训练集。训练集会累积之前拆分的数据,因此后续的训练集是之前训练集的超集。这种结构符合预测的时间顺序,即绝不能使用未来值来预测过去。

为了确保各折叠之间的指标具有可比性,样本必须等距分布。在满足此条件后,每个测试集覆盖相同的时间跨度,而训练集则逐渐增长。该类接受 n_splits、max_train_size、test_size 和 gap 等参数。默认测试大小为 n_samples // (n_splits + 1),而 gap 参数用于在训练集末尾和测试集之间排除部分样本。split 方法生成的训练和测试索引数组可用于切片数据,从而方便地循环遍历折叠、拟合模型并在每个测试窗口上进行评估。

对于固定的 test_size,各折叠产生的测试集长度相等。每个折叠在不同的时界上评估模型,且每折误差可单独记录。这是分析跨时界误差的基础。同样的评估循环可以扩展为存储每个时界的预测结果,从而计算每步时界的指标而非仅计算每折指标。核心要求是数据保持时间有序,且没有任何未来信息泄露到训练步骤中。

import numpy as np
from sklearn.model_selection import TimeSeriesSplit
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error

X = np.arange(12).reshape(-1, 1)
y = np.array([1.0, 1.8, 3.2, 4.1, 5.0, 5.9, 6.8, 7.7, 8.6, 9.5, 10.4, 11.3])

tscv = TimeSeriesSplit(n_splits=3, test_size=2)
for fold, (train_idx, test_idx) in enumerate(tscv.split(X), start=1):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    model = LinearRegression()
    model.fit(X_train, y_train)
    pred = model.predict(X_test)
    print(f"Fold {fold}: test indices {test_idx}, MAE {mean_absolute_error(y_test, pred):.3f}")

分析跨预测时界的误差

在获得每个折叠的预测结果后,下一步是对比每个预测时界的指标。单一的全局指标会掩盖预测质量如何随训练集与预测点之间时间间隔的增加而下降。通过按时界对误差进行分组,您可以观察短时界预测是否准确以及长时界预测是否恶化,或者误差模式是否不规则。这种对比对于决定特定业务操作可以信任预测到多远的时间点至关重要。

每步时界误差的计算方法是:选择所有时界值匹配给定值的预测结果,并对相应的真实值应用所选的回归指标。这要求为每个预测结果存储时界索引,在从单个模型进行多步预测或在特定时界评估每个折叠时,这种操作非常自然。最终生成的表格或图表展示了跨时界的误差轨迹,直接回答了预测窗口延长后预测效果恶化程度的问题。

这种分析还有助于将结构性误差与噪声区分开。如果误差随时界稳步增加,则模型可能缺乏长期预测所需的信息。如果误差在某个特定时界出现峰值,则可能表明存在结构性断裂、季节性或该范围内的训练数据不足。每步时界视图比单一聚合分数更具信息量,因为它揭示了预测在何处失去价值。它还支持将指标与决策成本挂钩,因为每个时界都可以映射到特定的行动或风险。

from sklearn.metrics import mean_absolute_error

# y_true and y_pred are aligned per horizon
horizon_errors = {}
for horizon in range(1, max_horizon + 1):
    mask = (horizon_index == horizon)
    horizon_errors[horizon] = mean_absolute_error(y_true[mask], y_pred[mask])

将指标与决策成本挂钩

评分函数的选择应始于预测的最终目标和应用场景,而非出于方便。区分预测和决策这两个步骤很有用:预测涉及选择响应分布的属性或泛函(如均值、中位数或分位数);决策则涉及基于该预测采取行动。用于评估的指标应与预测期间选择的目标泛函严格一致。严格一致的评分函数保证了在期望意义下,诚实报告是最佳策略,这意味着指标能准确反映预测值与真实目标之间的距离。

对于回归器,典型目标泛函是均值和中位数。均方误差(MSE)与均值对齐,而平均绝对误差(MAE)与中位数对齐。使用与目标泛函不一致的指标可能会产生误导性的对比。例如,如果模型训练目标是预测中位数,但使用平方误差进行评估,则评估结果可能无法反映所选点预测的实际成本。scikit-learn 文档建议为所选泛函使用严格一致的评分函数,并将其同时作为训练的损失函数和评估及模型对比的指标。

一旦选定指标,就应将其与决策的业务成本联系起来。最终指标不仅是一个数字,它是预测误差成本的代理指标。如果时界 1 的每步 MAE 为 1.2,而时界 3 为 2.8,那么提前三个月的决策成本是提前一个月决策成本的两倍多。这种对比可以为限制预测时界、增加特征或接受性能下降提供依据。指标必须在应用语境下解释,因为相同的误差值在不同领域可能产生不同的后果。

from sklearn.metrics import mean_absolute_error, mean_squared_error

# Strictly consistent scoring functions for point forecasts
mae = mean_absolute_error(y_true, y_pred)  # aligns with median target
mse = mean_squared_error(y_true, y_pred)   # aligns with mean target

选择一致的评分函数

应选择一个严格一致的评分函数,使其与点预测的目标泛函对齐。对于均值目标,均方误差是标准选择;对于中位数目标,平均绝对误差是标准选择。这些函数保证了当预测值等于目标泛函时,期望得分最小,从而使指标成为预测质量的真实衡量标准。scikit-learn 文档强调,一旦选择了严格一致的评分函数,最好将其同时用作模型训练的损失函数以及模型评估和比较的指标。

scikit-learn 模型评估文档中提供的评分器表格包括 mean_absolute_error、mean_squared_error、root_mean_squared_error 和 median_absolute_error 等回归指标。每种指标都与特定的目标泛函对齐。选择应由业务目标和关键的预测统计属性驱动。如果目标是最小化平均绝对偏差,则 MAE 是合适的;如果目标是最小化平均平方偏差,则 MSE 是合适的。指标必须与预测目标一致,以避免产生偏差的评估。

在训练和评估中使用相同的指标可确保模型优化的是将被测量的量。这种对齐防止了模型在不一致指标上表现良好,但在实际决策相关量上表现糟糕的情况。随后,每步时界分析变得有意义,因为指标反映了每个时界预测的真实成本。最终决策可以基于误差轨迹和不同时界误差的业务影响,而非依赖于可能掩盖重要模式的单一聚合分数。

from sklearn.metrics import mean_absolute_error

# Example: 12 monthly samples, 3 folds, test_size=2
# Fold 1 test indices: 6,7; Fold 2 test indices: 8,9; Fold 3 test indices: 10,11
# Per-horizon MAE: horizon 1 = 1.2, horizon 2 = 1.9, horizon 3 = 2.8
# Decision: restrict forecast to horizon 2 or improve long-horizon features

适用条件

  • 样本是否等距分布,以确保每个测试集覆盖相同的时间长度?
  • 每个测试集是否严格位于其训练集之后,且训练中未使用未来数据?
  • 所选指标是否与目标泛函(如均值或中位数)严格一致?
  • 是否分别计算了每步时界的误差,而不是将所有结果合并为一个全局数值?
  • 最终指标是否与决策的实际业务成本相挂钩?
  • 预测是否为点预测而非完整的概率分布?
  • 每个折叠的训练集和测试集在时间上是否不重叠?
  • 同一指标是否一致地用于模型训练和评估?

TimeSeriesSplit 要求样本等距分布以确保各折叠指标可比。该方法假设采用点预测而非完整的概率分布。它不能自动处理非对称的业务成本或误差结构中的非平稳性。当折叠数量较少时,每步时界的误差对比可能会有较大噪声,最终汇总指标必须结合具体的决策语境进行解释。

参考来源

  1. scikit-learn: TimeSeriesSplit ↗
  2. scikit-learn: Model evaluation ↗
返回顶部 ↑