用时间序列基础模型 Chronos-Bolt 轻松尝试时间序列预测

近年来,以 LLM(大语言模型)、VLM(视觉语言模型)为代表的基础模型被大量公开。与图像、自然语言处理等领域不同,基础模型也正逐步应用于时间序列建模领域。

本文将为大家介绍时间序列基础模型之一 ——“Chronos-Bolt”。

关于 Chronos-Bolt

简单来说,Chronos 是一款通过预先学习各类时间序列数据,无需对目标应用数据进行额外学习,即可实现时间序列预测的时间序列基础模型。而 Chronos-Bolt 是 Chronos 的后续迭代模型,与初代 Chronos 相比,其预测精度和运行性能均有大幅提升。

参考资料 ,Chronos 相关论文链接:arxiv.org

本文中,我们将借助 AutoGluon 框架,实现基于 Chronos-Bolt 的时间序列预测流程。AutoGluon 是由 AWS 主导开发的开源 AutoML(自动化机器学习)框架,该框架已集成多款时间序列预测模型,Chronos-Bolt 便是其中之一。

1. 无需训练即可实现高精度推理

为实现 “无需训练即可预测” 的能力,Chronos/Chronos-Bolt 不仅学习了各类真实时间序列数据,还采用了 TS-Mixup、KernelSynth 等合成数据生成技术,通过大量时间序列数据的训练,确保即使在缺乏目标领域训练数据的情况下,也能保证一定的预测精度。

通常而言,提升预测精度需要针对目标数据进行训练,但 Chronos-Bolt 在无训练数据的场景下,仍可实现符合预期的预测精度。

2. 相比 Chronos 模型速度更快(最高达 260 倍)

初代 Chronos 模型每次仅能预测未来 1 个时间步的结果;而 Chronos-Bolt 通过 “同时对多个时间步(t、t+1、t+2……)进行推理” 的设计,实现了速度优化。根据 AWS 官方博客的基准测试数据,在模型规模与 Chronos 相同的情况下,Chronos-Bolt 的运行性能最高可达到 Chronos 的 260 倍。

Chronos-Bolt 的推理速度

3. 相比 Chronos 模型精度更高

根据官方基准测试结果,Chronos-Bolt 的预测精度优于初代 Chronos 模型。仅从这一点来看,选择 Chronos-Bolt 也具备显著优势。

Chronos-Bolt 与其他模型的精度对比

基于 Chronos-Bolt 的时间序列预测

本文将介绍三种基于 Chronos-Bolt 的预测实现方案,具体如下:

方案说明
零样本推理不进行额外训练,直接基于预训练模型进行预测
执行微调基于目标数据进行训练后,再开展预测
利用回归模型进行特征外推除预测目标时间序列外,额外引入辅助特征用于预测

前期准备

1. 安装所需库

要使用 Chronos-Bolt,需提前安装 autogluon 库,执行以下命令即可:

pip install autogluon

2. 数据准备

本文使用的数据集为 Kaggle 平台公开的 “Store Sales – Time Series Forecasting”数据集,该数据集包含厄瓜多尔零售商 “Corporación Favorita” 的商品销量数据。

数据集链接:www.kaggle.com

由于原始数据格式难以直接适用,我们将在后续实现中对数据进行处理。

import polars as pl

transaction = pl.read_csv("./data/store-sales-time-series-forecasting/transactions.csv")
holiday = pl.read_csv("./data/store-sales-time-series-forecasting/holidays_events.csv")

transaction = transaction.join(holiday, how="left", on="date")
transaction = transaction.fill_null("null")
transaction = transaction.with_columns(
    pl.col("date").str.to_date()
)
transaction = transaction.with_columns(
    pl.col("date").dt.month().alias("month"),
    pl.col("date").dt.day().alias("day"),
    pl.col("date").dt.weekday().alias("weekday")
)

df = transaction
train_df = df.filter(
    pl.col("date").dt.year() < 2017
)
train_df.write_csv("./data/train.csv")
valid_df = df.filter(
    (pl.col("date").dt.year() >= 2017) & (pl.col("date").dt.month() == 1)
)
valid_df = pl.concat([train_df, valid_df], how="diagonal_relaxed")
valid_df.write_csv("./data/valid.csv")

以下是本分析中使用的主要参数说明:

项目(列名)说明
date日期
store_nbr店铺编号
transactions交易量(★本次预测目标值)
type节假日或事件类型
locale适用区域范围
locale_name具体区域名称(如城市、省份等)
month从 date 列中提取的月份
day从 date 列中提取的日期
weekday从 date 列中提取的星期几

零样本推理

零样本推理的实现非常简单,通过以下代码即可完成:

其中,id_column指定用于分组的类别列,timestamp_column指定时间列,target指定预测目标列。在TimeSeriesPredictor.fit方法中,通过指定presets="bolt_base",即可调用 Chronos-Bolt 模型。此外,将bolt_base替换为bolt_smallbolt_tiny,还可使用不同规模的 Chronos-Bolt 模型。

import polars as pl
from autogluon.timeseries import TimeSeriesDataFrame, TimeSeriesPredictor

train_data = TimeSeriesDataFrame.from_path( 
     "data/train.csv", 
     id_column="store_nbr", 
     timestamp_column="date", 
)
predictor = TimeSeriesPredictor(prediction_length=30, freq="D", target="transactions").fit(train_data, presets="bolt_base")
predictions = predictor.predict(train_data)

推理结果可视化

AutoGluon 提供了用于可视化的工具函数,我们将使用该函数展示结果。尽管数据中存在部分临时缺失,但可以看出:即使不进行额外训练,模型也基本能贴合实际数据趋势。

test_data = TimeSeriesDataFrame.from_path( 
     "data/valid.csv", 
     id_column="store_nbr", 
     timestamp_column="date", 
)
predictor.plot(test_data,predictions,max_history_length=365,item_ids=[25])

本图表中,蓝色线条代表实际交易量数据,橙色线条代表 Chronos-Bolt 的预测结果。此外,橙色线条前后的阴影部分表示80% 置信区间

微调

接下来,我们通过微调训练模型,并用其尝试时间序列预测。微调可通过以下代码实现:此代码会生成两种模型:零样本模型与微调模型。在hyperparametersChronos键下,通过列表定义了两种模型配置,核心要点是将fine_tune参数设为True

predictor = TimeSeriesPredictor(prediction_length=31, eval_metric="MASE", freq="D", target="transactions").fit( 
     train_data, 
     hyperparameters={ 
         "Chronos": [ 
             {"model_path": "bolt_base", "ag_args": {"name_suffix": "ZeroShot"}}, 
             {"model_path": "bolt_base", "fine_tune": True, "ag_args": {"name_suffix": "FineTuned"}}, 
         ] 
     }, 
     enable_ensemble=False, 
     time_limit=600, 
)

训练结束后,可通过以下实现代码获取零样本模型与微调后模型的评估结果。

predictor.leaderboard(test_data)



此外,利用上述实现的预测器,还可按以下方式进行预测并可视化结果:

predictions = predictor.predict(train_data, model=”ChronosZeroShot[bolt_base]”)
predictor.plot(test_data,predictions,max_history_length=365,item_ids=symbols, max_num_item_ids=len(symbols))

对比零样本推理结果可见,微调后的模型预测结果更贴合实际数据趋势。

特征外推的使用

在部分场景中,除了预测目标时间序列数据外,还可能存在可辅助预测的其他时间序列数据。例如,店铺销量可能与影响到店人数的 “降水量” 相关,这类数据即可作为辅助特征使用。但需注意:外推需使用 “预测当日” 的辅助特征数据,因此在实际验证中,若无法获取当日辅助数据,则难以进行当日预测(例如:若需在预测前日使用次日的准确降水量数据,实际场景中通常无法实现)。

外推场景下的预测公式

回归预测值 = Chronos-Bolt 的预测值 + CatBoost(外推回归模型)的预测值

代码实现

核心修改点在于:在TimeSeriesPredictor中通过known_covariates_names指定用于外推的辅助特征列。本次模型中,我们输入了日期特征(month、day、weekday)与节假日信息(type、locale、locale_name),具体实现如下:

predictor = TimeSeriesPredictor(
    prediction_length=31,
    eval_metric="MASE",
    target="transactions",
    known_covariates_names=["type", "locale", "locale_name", "month", "day", "weekday"],
    freq="D"
).fit(
    train_data,
    hyperparameters={
        "Chronos": [
            {"model_path": "bolt_base", "ag_args": {"name_suffix": "ZeroShot"}},
            {
                "model_path": "bolt_base",
                "covariate_regressor": "CAT",
                "target_scaler": "standard",
                "ag_args": {"name_suffix": "WithRegressor"},
            },
        ],
    },
    time_limit=600,
    enable_ensemble=False,
)

与微调场景类似,可通过以下代码对比模型效果:

predictor.leaderboard(test_data)

在本次预测中,需要提供用于外推的特征量。由于此类推理需要 31 天的完整数据才能进行(若数据不完整则难以实现),因此我们筛选出店铺编号为 25 的完整数据集,并用其对推理结果进行可视化。具体实现代码如下。

filtered_id_df = train_data.to_data_frame().loc[25]
filtered_id_df['item_id'] = 25
filtered_id_df['timestamp'] = filtered_id_df.index
train_data = TimeSeriesDataFrame.from_data_frame(filtered_id_df)

filtered_id_df = test_data.to_data_frame().loc[25]
filtered_id_df['item_id'] = 25
filtered_id_df['timestamp'] = filtered_id_df.index
test_data = TimeSeriesDataFrame.from_data_frame(filtered_id_df)

predictions = predictor.predict(train_data, model="ChronosWithRegressor[bolt_base]", 
                                known_covariates =test_data
                               )
predictor.plot(test_data,predictions,max_history_length=365,
               item_ids=[25], max_num_item_ids=1)

对比微调模型可见,加入外推特征后的预测结果更接近实际数据趋势。

总结

我们通过 AutoGluon 轻松调用了 Chronos-Bolt 模型,并尝试完成了时间序列预测。将 LLM 等基础模型的思路应用到时间序列模型中,这一方向非常有趣,其未来发展值得期待。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注