TimeSeries
¶
TimeSeries
是 Darts 中的主要数据类。TimeSeries
表示单变量或多元时间序列,带有正确的时间索引。时间索引可以是 pandas.DatetimeIndex
类型(包含日期时间),也可以是 pandas.RangeIndex
类型(包含整数;对于表示没有特定时间戳的顺序数据很有用)。在某些情况下,TimeSeries
甚至可以表示概率序列,例如用于获取置信区间。
TimeSeries
在 Darts 中用于提供一致的、专用于时间序列的 API
TimeSeries
保证拥有正确的时间索引(基于整数或日期时间):完整且按时间排序。Darts 中的所有模型都使用
TimeSeries
并产生TimeSeries
。TimeSeries
允许进行各种时间序列操作(例如按时间戳分割、连接等)。TimeSeries
提供了一种用户友好的方式来表示多维和概率序列(例如获取边际分位数)。
使用专用类型来表示时间序列(而不是 Pandas DataFrame、NumPy 数组等)消除了对不同模型和函数期望格式约定的依赖。
多元时间序列 vs 多时间序列¶
我们区分单变量序列和多元序列
一个多元序列包含多个维度(即每个时间步长有多个值)。
一个单变量序列只包含一个维度(即每个时间步长只有一个标量值)。
有时这些维度被称为分量。一个 TimeSeries
对象可以是单变量(如果它只有一个分量),也可以是多元(如果它有多个分量)。在多元序列中,所有分量共享相同的时间轴。也就是说,它们共享相同的时间戳。
Darts 中的一些模型(以及所有机器学习模型)支持多元序列。这意味着它们可以接受多元序列作为输入(作为目标或协变量),并且它们生成的预测将与目标的维度相匹配。
此外,一些模型可以处理多个时间序列,这意味着它们可以同时在多个 TimeSeries
对象上训练,并用于同时预测多个 TimeSeries
对象。这有时被称为面板数据。在这种情况下,不同的 TimeSeries
不需要共享相同的时间索引——例如,有些序列可能在 1990 年,有些在 2000 年。实际上,这些序列甚至不需要具有相同的频率。处理多个序列的模型期望输入为 TimeSeries
的 Python Sequence
(例如,一个简单的 TimeSeries
列表)。

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

图 2:多个时间序列。在 Darts 中,这由多个 TimeSeries
对象表示。这些序列可以共享或不共享相同的时间轴,并且可以是单变量或多元的。
多元序列示例:单个患者随时间变化的血压和心率(一个包含 2 个分量的多元序列)。
多序列示例:多个患者的血压和心率;可能针对不同患者在不同时间测量(每个患者一个包含 2 个分量的多元序列)。
我的问题应该使用多元序列还是多序列?¶
使用多元序列将为模型提供共同捕捉维度(components)的机会,而使用多序列将使模型接触到多个观测值。因此,哪种表示形式是正确的取决于具体问题,在某些情况下甚至可能事先不清楚,需要通过实验确定。然而,如果您的情况是试图对随时间一起变化的几个“相关”分量进行建模(例如移动物体的坐标,或与单个实体相关的多个测量值),通常自然地将它们作为单个序列中的多个分量来捕捉。另一方面,如果您有此类测量值的多个实例(例如,在不同实验或观测中获得),这可能意味着您拥有多个时间序列。此外,如果您的值不共享相同的时间跨度,则应将其表示为不同的序列。
概率序列和确定性序列¶
在 Darts 中,概率预测通过从底层概率模型中抽取 Monte Carlo 样本来表示。这种表示允许 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.DatetimeIndex
或 pandas.RangeIndex
),在 *component*(或“列”)维上还有另一个 pandas.Index
。TimeSeries
旨在是不可变的,并且大多数操作都会返回新的 TimeSeries
对象。
从 TimeSeries
导出数据¶
TimeSeries
对象提供了几种导出数据的方式,例如
TimeSeries.to_dataframe() 导出 Dataframe(用于确定性序列)
TimeSeries.data_array() 导出包含此序列数据(和索引)的
xarray
DataArray
。TimeSeries.values() 导出包含序列中一个样本值的 NumPy 数组。
TimeSeries.all_values() 导出包含随机序列所有样本值的 NumPy 数组。
静态协变量¶
可选地,TimeSeries
对象可以包含静态数据(称为静态协变量),这可以被一些模型利用。静态协变量的示例包括
商店位置 - 例如,对于多元序列中的每个商店(分量)
产品 ID
传感器类型
…
静态协变量必须由一个 pandas DataFrame 指定,其行与 TimeSeries
的分量匹配,列表示静态协变量的维度。在使用大多数工厂方法时,可以使用 static_covariates
参数将它们添加到 TimeSeries
中。它们也可以使用 with_static_covariates()
方法添加到现有 TimeSeries
中。
分层时间序列¶
可选地,TimeSeries
对象可以包含一个层级结构(hierarchy),该结构指定其不同分量如何分组。层级结构本身被指定为一个 Python 字典,将分量的名称映射到其在层级结构中父级名称的列表。
例如,以下层级结构表示两个分量 "a"
和 "b"
相加等于 "total"
hierarchy = {"a": ["total"], "b": ["total"]}
层级结构可用于后验预测协调(posthoc forecast reconciliation)。Darts 提供了几种协调转换器(可与 fit()
/transform()
一起使用)——参见相应的 API 文档。
更多信息和文档¶
TimeSeries
类的完整属性和方法列表列在API 文档中。此外,快速入门包含一些 TimeSeries
操作的示例。