使用 🤗 Transformers 的时间序列 Transformer 概率预测
TL;DR
Hugging Face 推出了 Time Series Transformer,这是一种原始的编码器‑解码器 Transformer,能够学习单变量序列的全局概率预测,并在 Tourism Monthly 数据集上超越传统基线。
为什么使用全局概率模型?
在许多相关序列上训练单一模型(全局模型)使网络能够捕获共享的模式和潜在表示,这不同于对每个序列独立拟合的传统“局部”方法。概率预测——预测完整的分布而非点估计——提供了不确定性量化,对下游决策至关重要。
架构概览
Time Series Transformer 在编码器‑解码器配置中复用了标准 Transformer(Vaswani 等,2017)。
- Encoder 消耗固定大小的过去观测上下文窗口。
- Decoder 使用因果掩码自回归生成未来值,类似于文本生成。
- Distribution head(默认:Student‑t)为每个预测步输出概率分布的参数。
关键优势:
- 通过类似
attention_mask的机制处理缺失值。 - 通过窗口训练支持任意上下文和预测长度。
- 利用与 NLP 模型相同的 API,支持推理时使用
generate()。
模型配置细节
from transformers import TimeSeriesTransformerConfig, TimeSeriesTransformerForPrediction
config = TimeSeriesTransformerConfig(
prediction_length=24, # forecast horizon (months)
context_length=48, # encoder window (2× horizon)
lags_sequence=[1,2,3,4,5,6,7,11,12,13,23,24,25,35,36,37],
num_time_features=2, # month‑of‑year + age feature
num_static_categorical_features=1, # series ID
cardinality=[366], # 366 regions in the dataset
embedding_dimension=[2],
encoder_layers=4,
decoder_layers=4,
d_model=32,
)
model = TimeSeriesTransformerForPrediction(config)
- 模型学习 Student‑t 分布(
model.config.distribution_output == "student_t")。 - 静态分类嵌入编码每个序列的身份,使单一模型能够服务全部 366 条序列。
数据管道(GluonTS + 🤗 Datasets)
- 加载 Monash
tourism_monthly数据集(训练/验证/测试划分,366 条序列)。 - 将
start时间戳转换为pandas.Period,以便轻松生成时间特征。 - 定义 GluonTS 转换链,包括:
- 移除未使用的静态/动态字段。
- 将字段转换为 NumPy 数组。
- 为缺失值添加 observed‑mask。
- 生成时间特征(
month_of_year)和年龄特征。 - 堆叠时间特征并重命名字段以匹配 Transformer API。
- 创建
InstanceSplitter,为编码器采样大小为context_length + max(lags)的窗口,为解码器采样prediction_length的窗口。支持三种模式:train(随机窗口)、validation(最后一个窗口)和test(仅最后上下文)。 - 构建 DataLoaders,将转换后的实例批处理为张量(
past_values、past_time_features、future_time_features等)。
训练循环(Accelerate)
from accelerate import Accelerator
from torch.optim import AdamW
accelerator = Accelerator()
model.to(accelerator.device)
optimizer = AdamW(model.parameters(), lr=6e-4, betas=(0.9, 0.95), weight_decay=1e-1)
model, optimizer, train_loader = accelerator.prepare(model, optimizer, train_loader)
model.train()
for epoch in range(40):
for batch in train_loader:
optimizer.zero_grad()
outputs = model(**batch)
accelerator.backward(outputs.loss)
optimizer.step()
- 解码器会自动平移
future_values以计算似然损失。 - 未进行超参数搜索;40 个 epoch 已足以获得强劲结果。
使用自回归生成进行推理
model.eval()
forecasts = []
for batch in test_loader:
out = model.generate(**batch)
forecasts.append(out.sequences.cpu().numpy())
forecasts = np.vstack(forecasts) # shape: (366, 100, 24)
generate()从学习到的分布中采样,为每条序列生成 100 条 Monte‑Carlo 轨迹。- 使用样本的中位数进行点预测评估。
评估指标
使用 evaluate 库:
- MASE(平均绝对比例误差)= 1.256(在 366 条序列上的平均)。
- sMAPE(对称平均绝对百分比误差)= 0.161。 这些数值在相同基准上优于大量经典和深度基线。
基准比较
| 模型 | MASE |
|---|---|
| SES | 3.306 |
| Theta | 1.649 |
| TBATS | 1.751 |
| ETS | 1.526 |
| (DHR‑)ARIMA | 1.589 |
| PR | 1.678 |
| CatBoost | 1.699 |
| FFNN | 1.582 |
| DeepAR | 1.409 |
| N‑BEATS | 1.574 |
| WaveNet | 1.482 |
| Transformer(本工作) | 1.256 |
Transformer 在未进行任何数据集特定调优的情况下实现了最低的 MASE,表明全局注意力机制能够有效捕获季节性和趋势模式。
实际要点
- 全局概率预测 可以使用 🤗 Transformers 库仅几行代码实现。
- 用于语言模型的相同 API(
generate、forward、loss)同样适用于时间序列数据,降低了实践者的使用门槛。 - 缺失数据处理通过注意力掩码原生支持,免去了插补的需求。
- 二次方的注意力成本限制了上下文长度;未来工作可采用高效注意力变体。
社区的后续工作
- 多变量扩展——支持对角独立和全协方差分布头。
- 时间序列分类——为异常检测等任务添加分类头。
- 预训练检查点——探索在异构时间序列语料上进行大规模预训练,类似于 NLP/视觉。
- 可选日期时间输入——为缺少显式时间戳的数据集(如神经科学记录)调整管道。
- 高效注意力——集成稀疏或线性复杂度的注意力,以扩大可行的上下文窗口。
此发布表明,原始 Transformer 结合合适的概率头和数据管道后,在单变量预测方面具有竞争力。鼓励研究者和工程师尝试 Hugging Face Hub 上的其他数据集,调整频率特定参数,并向库中贡献更多模型。