用 Python 轻松实现时间序列预测:Darts 时间序列 TimeSeries

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。

Darts

Darts 是一个 Python 库,用于对时间序列进行用户友好型预测和异常检测。它包含多种模型,从 ARIMA 等经典模型到深度神经网络。所有预测模型都能以类似 scikit-learn 的方式使用 fit()predict() 函数。该库还可以轻松地对模型进行回溯测试,将多个模型的预测结果结合起来,并将外部数据考虑在内。Darts 支持单变量和多变量时间序列和模型。基于 ML 的模型可以在包含多个时间序列的潜在大型数据集上进行训练,其中一些模型还为概率预测提供了丰富的支持。

时间序列

TimeSeries 是 Darts 中的主要数据类。TimeSeries 表示一个单变量或多变量时间序列,并带有适当的时间索引。时间索引可以是 pandas.DatetimeIndex 类型(包含日期时间),也可以是 pandas.RangeIndex 类型(包含整数;适用于无具体时间戳的序列数据)。在某些情况下,TimeSeries 甚至可表示 概率 序列,例如用于获得置信区间。

在 Darts 中,TimeSeries 用于提供一致的时间序列 API:

  • TimeSeries 保证具有适当的时间索引(基于整数或日期时间):完整且按时间排序。

  • Darts 中的所有模型均接收 TimeSeries 并输出 TimeSeries

  • TimeSeries 支持各种时间序列操作(如按时间戳拆分、拼接等)。

  • TimeSeries 提供友好的方式来表示多维和概率序列(例如获取边际分位数)。

使用专用类型来表示时间序列(而非 Pandas DataFrame、NumPy 数组等)可消除对不同模型和函数所期望格式的依赖。

多变量时间序列 vs 多个时间序列

我们区分单变量与多变量序列:

  • 多变量 序列包含多个维度(即每个时间步有多个数值)。

  • 单变量 序列仅包含一个维度(即每个时间步只有一个标量值)。

有时这些维度称为 分量。单个 TimeSeries 对象可以是单变量(若仅有一个分量),也可以是多变量(若有多个分量)。在多变量序列中,所有分量共享同一时间轴,即它们共享相同的时间戳。

Darts 中的某些模型(以及所有机器学习模型)支持多变量序列。这意味着它们可将多变量序列作为输入(作为目标或协变量),且其输出的预测维度与目标维度匹配。

此外,某些模型可处理 多个时间序列,即它们可在多个 TimeSeries 对象上训练,并一次性预测多个 TimeSeries 对象。这有时称为面板数据。在这种情况下,不同的 TimeSeries 不必共享相同的时间索引——例如,某些序列可能在 1990 年,而其他序列在 2000 年。实际上,这些序列甚至可以具有不同的频率。处理多个序列的模型期望输入为 Python SequenceTimeSeries(例如简单的 TimeSeries 列表)。

img

图 1: 单个多变量序列。在 Darts 中,这由单个 TimeSeries 对象表示。

img

图 2: 多个时间序列。在 Darts 中,这由多个 TimeSeries 对象表示。这些序列可能共享或不共享同一时间轴,也可能为单变量或多变量。

  • 多变量序列示例: 单个患者随时间变化的血压和心率(一个包含 2 个分量的多变量序列)。

  • 多个序列示例: 多个患者的血压和心率;不同患者可能在不同时间测量(每个患者一个包含 2 个分量的多变量序列)。

我应使用多变量序列还是多个序列来解决我的问题?

使用多变量序列为模型提供了联合捕获维度的机会,而使用多个序列则让模型接触到多个观测值。因此,哪种表示方式合适取决于具体的问题,有时甚至在事前并不明确,需要通过实验确定。然而,若你试图建模多个“相关”分量随时间共同变化(例如移动物体的坐标,或与单个实体相关的多个测量值),通常自然地将这些分量捕获为单个序列中的多个分量。另一方面,如果你有这些测量的多个实例(例如,在不同实验或观测中获得),这可能意味着你有多个时间序列。此外,如果你的值不共享相同的时间跨度,它们可能应表示为不同的序列。

概率序列与确定性序列

在 Darts 中,概率预测通过对底层概率模型进行蒙特卡洛采样来表示。这种表示方式使 TimeSeries 能够表示任意联合分布(跨时间和分量),而无需依赖任何预定义的参数形式。基于此,我们定义两种序列类型:

  • 概率(或 随机)序列包含多个样本。

  • 确定性 序列仅包含一个样本。

创建 TimeSeries

TimeSeries 对象可通过工厂方法创建,例如:

  • TimeSeries.from_dataframe() 可从具有一个或多个列表示数值的 Pandas Dataframe 创建 TimeSeries(列对应分量,多个列对应多变量序列)。

  • TimeSeries.from_values() 可从 1-D、2-D 或 3-D NumPy 数组创建 TimeSeries。它将生成基于整数的时间索引(pandas.RangeIndex 类型)。1-D 对应单变量确定性序列,2-D 对应多变量确定性序列,3-D 对应多变量随机序列。

  • TimeSeries.from_times_and_values()TimeSeries.from_values() 类似,但还接受时间索引。

更多方法记录在 TimeSeries API 文档中。

此外,可使用函数 concatenate() 沿不同轴拼接序列。axis=0 对应时间,axis=1 对应分量,axis=2 对应随机样本维度。例如:

from darts import concatenate

my_multivariate_series = concatenate([series1, series2, ...], axis=1)

从共享相同时间轴的某些序列生成多变量序列。

实现

在幕后,TimeSeries 包裹一个 3 维的 xarray.DataArray 对象。维度为 (time, component, sample),其中 component 维度的大小在多变量序列中大于 1,sample 维度的大小在随机序列中大于 1。DataArray 本身由 3 维 NumPy 数组支持,并在 time 维度上具有时间索引(pandas.DatetimeIndexpandas.RangeIndex),在 component(或“列”)维度上具有另一个 pandas.IndexTimeSeries 旨在不可变,大多数操作返回新的 TimeSeries 对象。

TimeSeries 导出数据

TimeSeries 对象提供几种导出数据的方式,例如:

静态协变量

可选地,TimeSeries 对象可包含静态数据(称为 静态协变量),某些模型可利用这些数据。静态协变量的示例包括:

  • 商店位置——例如多变量序列中每个商店(分量)的位置

  • 产品 ID

  • 传感器类型

静态协变量必须由 pandas DataFrame 指定,其行与 TimeSeries 的分量匹配,列表示静态协变量的维度。它们可在使用大多数工厂方法时通过 static_covariates 参数添加到 TimeSeries。也可使用 with_static_covariates() 方法将静态协变量添加到现有 TimeSeries

层次时间序列

可选地,TimeSeries 对象可包含层次结构,该结构指定其不同分量如何分组。层次结构本身指定为 Python 字典,将分量名称映射到其在层次结构中的父级名称列表。

例如,以下层次结构表示两个分量 "a""b" 累加到 "total"

hierarchy = {"a": ["total"], "b": ["total"]}

层次结构可用于事后预测协调。Darts 提供几种协调转换器(可与 fit() / transform() 一起使用)—— 参见相应的 API 文档

更多信息与文档

TimeSeries 类的完整属性和方法列表在 API 文档中列出。此外,快速入门包含一些 TimeSeries 操作的示例。

风险提示与免责声明
本文内容基于公开信息研究整理,不构成任何形式的投资建议。历史表现不应作为未来收益保证,市场存在不可预见的波动风险。投资者需结合自身财务状况及风险承受能力独立决策,并自行承担交易结果。作者及发布方不对任何依据本文操作导致的损失承担法律责任。市场有风险,投资须谨慎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

船长Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值