时间融合变压器:利用深度学习进行时间序列预测 — 完整教程

创建准确且可解释的预测

由 DALLE 创建 [1]

根据[2], 时间融合变压器 优于所有著名的时间序列预测深度学习模型。

包括一个特色 梯度提升树 表格时间序列数据的模型。

但是是什么 时间融合变压器(TFT)[3] 为什么这么有趣?

在这篇文章中,我们简要介绍了 时间融合变压器 并构建一个端到端项目 能源需求预测。具体来说,我们将涵盖:

  • 如何准备 TFT 格式的数据。
  • 如何构建、训练和评估 TFT 模型。
  • 如何获得对验证数据和样本外预测的预测。
  • 怎么算 特征重要性, 季节性模式,极端事件鲁棒性 使用内置模型的 可解释的注意力 机制。

我们潜入吧!

要深入分析 Temporal Fusion Transformer 架构,请查看我之前的文章 刊文.

T恩波拉尔 F激子 T变压器(液晶)是一个基于 Transformer 的模型,它利用自注意力来捕获多个时间序列的复杂时间动态。

TFT支持:

  • 多个时间序列: 我们可以在数千个单变量或多变量时间序列上训练 TFT 模型。
  • 多层面预测: 该模型输出一个或多个目标变量的多步预测——包括预测区间。
  • 异构特征: TFT 支持多种类型的特征,包括时变和静态外生变量。
  • 可解释的预测: 预测可以根据变量重要性和季节性来解释。

这些特征之一是独一无二的 时间融合变压器。我们将在下一节中介绍这一点。

在著名的深度学习时间序列模型中(例如, 深度AR[4]),TFT 之所以脱颖而出,是因为它支持各种类型的功能。这些都是:

  • 随时间变化 已知
  • 随时间变化 不明
  • 时不变的 真实
  • 时不变的 明确的

例如,假设我们有一个 销售预测案例:

假设我们必须预测 3 种产品的销量。这 num sales 是目标变量。这 CPI index 或者 number of visitors ,那恭喜你, 时变未知 特征,因为它们仅在预测时间之前是已知的。然而, holidaysspecial days ,那恭喜你, 时变已知 事件。

product id is 时不变(静态)分类 特征。其他数值特征且不依赖于时间,例如 yearly_revenue 可以归类为 时不变实数.

在开始我们的项目之前,我们将首先展示一个关于如何将数据转换为 扩展时间序列格式.

请注意: 本文中的所有图像和图表均由作者创作。

对于本教程,我们使用 TemporalFusionTransformer 来自的模型 PyTorch 预测 库和 PyTorch Lightning:

pip 安装 torch pytorch-lightning pytorch_forecasting

整个过程涉及3件事:

  1. 使用我们的时间序列数据创建一个 pandas 数据框。
  2. 将我们的数据框包装成 时间序列数据集 实例。
  3. 通过我们的 时间序列数据集 实例到 TemporalFusionTransformer.

时间序列数据集 非常有用,因为它可以帮助我们指定特征是随时间变化的还是静态的。另外,这是唯一的格式 TemporalFusionTransformer 接受。

让我们创建一个最小的训练数据集来展示如何 时间序列数据集 工作原理:

我们应该按以下方式格式化数据:每个彩色框代表不同的时间序列,由其表示 group 计算值。

图1: Sample_data pandas 数据框

我们的数据框最重要的列是 time_idx ——它决定了样本的顺序。如果没有缺失观测值,则值应增加 +1 对于每个时间序列。

接下来,我们将数据框包装成 时间序列数据集 实例:

所有论点都是不言自明的: max_encoder_length 定义回顾期和 max_prediction_length 指定将预测多少个数据点。在我们的例子中,我们回顾过去的 3 个时间步来输出 2 个预测。

时间序列数据集 实例现在充当数据加载器。让我们打印一个批次并检查我们的数据将如何传递到 TFT:

该批次包含训练值 [0,1] 从第一个时间序列(group 0)和测试值[2,3,4]。如果重新运行此代码,您将获得不同的值,因为默认情况下数据会被打乱。

我们的项目将使用 电力负荷图20112014 [5] 来自 UCI 的数据集。此示例的笔记本可以从以下位置下载 点击此处:

该数据集包含 370 个客户端/消费者以 15 分钟为单位的用电量(以千瓦为单位)。数据跨度为 4 年(2011 年至 2014 年)。

有些消费者是在 2011 年之后创建的,因此他们的用电量最初为零。

我们按照以下方式进行数据预处理 [3]:

  • 聚合我们的目标变量 power_usage 按小时。
  • 查找幂非零的每个时间序列的最早日期。
  • 创建新功能: month, day, hourday_of_week.
  • 选择之间的所有日期 2014–01–012014–09–07.

开始吧:

下载数据

wget的 https://archive.ics.uci.edu/ml/machine-learning-databases/00321/LD2011_2014.txt.zip
!解压
LD2011_2014.txt.zip

数据预处理

每列代表一个消费者。最初始的 power_usage 值为 0。

接下来,我们汇总每小时数据。由于模型的大小和复杂性,我们仅在 5 个消费者(对于那些具有非零值的消费者)上训练我们的模型。

现在,我们准备数据集 时间序列数据集 格式。请注意,每列代表不同的时间序列。因此,我们“融化”我们的数据框,以便所有时间序列都垂直堆叠而不是水平堆叠。在此过程中,我们创建了新功能。

最终预处理后的数据帧称为 time_df。让我们打印它的内容:

time_df 现在格式正确 时间序列数据集。正如您现在已经猜到的,由于粒度是每小时, hours_from_start 变量将是 时间索引。

探索性数据分析

5 个消费者/时间序列的选择不是随机的。这 power usage 每个时间序列都有不同的属性,例如平均值:

time_df[['consumer_id','power_usage']].groupby('consumer_id').mean()

让我们绘制每个时间序列的第一个月:

图2: 所有 5 个时间序列/消费者的第一个月。

没有明显的趋势,但每个时间序列的季节性和幅度略有不同。我们可以进一步实验和检查平稳性、信号分解等,但在我们的例子中,我们只关注模型构建方面。

另外,请注意其他时间序列预测方法,例如 有马 必须满足一些要求(例如,时间序列必须首先变得平稳。)使用 TFT,我们可以保持数据不变。

创建数据加载器

在这一步中,我们通过 time_df时间序列数据集 格式非常有用,因为:

  • 它使我们无需编写自己的数据加载器。
  • 我们可以指定 TFT 如何处理数据集的特征。
  • 我们可以轻松标准化我们的数据集。在我们的例子中,归一化是强制性的,因为所有时间序列的大小都不同。因此,我们使用 组标准化器 单独标准化每个时间序列。

我们的模型使用一周(7*24)的回溯窗口来预测未来 24 小时的用电量。

另外,请注意 hours_from_start 既是时间索引又是随时间变化的特征。这 power_usage 是我们的目标变量。为了演示,我们的验证集是最后一天:

基线模型

接下来是几乎每个人都忘记的步骤:基线模型。特别是在时间序列预测中,您会惊讶地发现一个简单的预测器常常胜过更高级的模型!

作为一个简单的基线,我们预测前一天的用电量曲线:

训练 Temporal Fusion Transformer 模型

我们可以使用熟悉的方法来训练我们的 TFT 模型 训练者 PyTorch Lightning 的接口。

请注意以下事项:

  • 我们使用 提前停止 回调来监控验证丢失。
  • 我们使用 张量板 记录我们的训练和验证指标。
  • 我们的模型使用 分位数损失 ——一种特殊类型的损失,可以帮助我们输出预测区间。有关分位数损失函数的更多信息, 检查这篇文章.
  • 我们用 4 注意力头,就像原始论文一样。

我们现在准备构建和训练我们的模型:

就是这样! 6 个 epoch 后,EarlyStopping 启动并停止训练。

加载并保存最佳模型

不要忘记保存您的模型。虽然我们可以pickle它,但最安全的选择是直接保存最好的epoch:

!zip -r model.zip lighting_logs/lightning_logs/version_1/*

要再次加载模型,请解压缩 模型.zip 并执行以下命令 - 只需记住最佳模型路径:

检查张量板

使用 Tensorboard 仔细查看训练和验证曲线:

模型评估

获取验证集的预测并计算平均值 请在50月XNUMX日至XNUMX日来台北台湾参观我们的展位PXNUMX。 (分位数中位数) :

最后 2 个时间序列的损失稍高,因为它们的相对幅度也很高。

绘制验证数据的预测图

如果我们通过 mode=raw 预测() 方法,我们获得更多信息,包括所有七个分位数的预测。我们还可以访问注意力值(稍后会详细介绍)。

仔细看看 raw_predictions 变量:

我们使用 绘图预测() 创建我们的情节。当然,您可以制作自己的自定义绘图 - 绘图预测() 具有添加注意力值的额外好处。

请注意: 我们的模型预测接下来的 24 个数据点 一气呵成。这不是模型预测的滚动预测场景 重视每次并将所有预测“缝合”在一起。

我们为每个消费者创建一个图(总共 5 个)。

图3: 对 MT_002 验证数据的预测
图4: 对 MT_004 验证数据的预测
图5: 对 MT_005 验证数据的预测
图6: 对 MT_006 验证数据的预测
图7: 对 MT_008 验证数据的预测

结果令人印象深刻。

我们的 时间融合变压器 模型能够捕获所有 5 个时间序列的季节性和幅度行为!

另外,请注意:

  • 我们没有执行任何超参数调整。
  • 我们没有实现任何奇特的特征工程技术。

在后续部分中,我们将展示如何通过超参数优化来改进我们的模型。

绘制特定时间序列的预测图

之前,我们使用以下方法对验证数据进行预测 idx 参数,它迭代数据集中的所有时间序列。我们可以更具体地输出特定时间序列的预测:

图7: 日前预测 MT_004 在训练集上

In 图7, 我们计划提前一天 MT_004 消费者时间指数=26512。

请记住,我们的时间索引专栏 hours_from_start 从 26304 开始,我们可以得到从 26388 开始的预测(因为我们之前设置了 min_encoder_length=max_encoder_length // 2 等于 26304 + 168//2=26388

样本外预测

让我们创建超出验证数据的最终数据点的样本外预测 - 即 2014–09–07 23:00:00

我们所要做的就是创建一个新的数据框,其中包含:

  • 的数量 N=max_encoder_length 过去的日期,充当回顾窗口 - 编码器数据 在 TFT 术语中。
  • 未来日期的尺寸 max_prediction_length 我们想要计算我们的预测 - 解码器数据。

我们可以为所有 5 个时间序列或仅一个时间序列创建预测。 图7 显示消费者的样本外预测 MT_002:

图7: MT_002 日前预测

准确的预测是一回事,但如今可解释性也很重要。

对于被视为黑匣子的深度学习模型来说,情况更糟。方法如 LIME夏普 可以提供可解释性(在某种程度上),但对于时间序列来说效果不佳。另外,它们是外部事后方法,不依赖于特定模型。

时间融合变压器 提供三种类型的可解释性:

  • 季节性方面: TFT利用其新颖的 可解释的多头注意力 计算过去时间步的重要性的机制。
  • 从功能上来说: TFT 利用其 变量选择网络 模块来计算每个特征的重要性。
  • 极端事件鲁棒性: 我们可以研究时间序列在罕见事件中的表现

如果你想深入了解其内部运作原理 可解释的多头注意力 变量选择网络, 查看我之前的文章.

季节性的可解释性

TFT 通过探索注意力权重来理解过去时间步长的时间模式。

之前所有图中的灰线代表注意力分数。再看看这些图——你注意到什么了吗? 图8 显示了调查结果 图7 并且还考虑了注意力分数:

图8: 显示季节性的 MT_001 日前预测

注意力分数揭示了模型输出预测时这些时间步长的影响力。小峰值反映了每日季节性,而接近尾声的较高峰值可能意味着每周季节性。

如果我们对所有时间步长和时间序列(不仅仅是我们在本教程中使用的 5 个时间步长和时间序列)的注意力曲线进行平均,我们将得到看起来对称的形状 图9 来自TFT论文:

图9: 电力数据集的时间模式(来源)

问题: 这有什么好处?难道我们不能简单地用ACF图、时间信号分解等方法来估计季节性模式吗?

答: 真的。然而,研究 TFT 的注意力权重还有额外的优势:

  1. 我们可以确认我们的模型捕获了序列的明显季节性动态。
  2. 我们的模型还可能揭示隐藏的模式,因为当前输入窗口的注意力权重考虑了所有过去的输入。
  3. 注意力权重图与自相关图不同:自相关图指的是特定序列,而这里的注意力权重通过查看所有协变量和时间序列来关注每个时间步长的影响。

特征方面的可解释性

变量选择网络 TFT的组成部分可以很容易地估计 特征重要性:

图10: 特征对验证数据的重要性

In 图10,我们注意到以下几点:

  • hourday_of_week 作为过去的观察和未来的协变量都有很高的分数。原始论文中的基准测试也得出相同的结论。
  • power_usage 显然是观察到的最有影响力的协变量。
  • consumer_id 在这里不是很重要,因为我们只使用 5 个消费者。在 TFT 论文中,作者使用了全部 370 名消费者,这个变量更为重要。

请注意: 如果您的分组静态变量并不重要,那么您的数据集很可能也可以通过单个分布模型(如 ARIMA)同样很好地建模。

极端事件检测

时间序列因在罕见事件(也称为 震荡).

更糟糕的是,这些事件非常难以捉摸。想象一下,如果您的目标变量在短时间内变得不稳定,因为协变量默默地改变了行为:

这是一些随机噪声还是逃脱了我们模型的隐藏的持久模式?

借助 TFT,我们可以分析每个单独特征在其值范围内的稳健性。不幸的是,当前的数据集没有表现出波动性或罕见事件——这些更有可能在财务、销售数据等中找到。不过,我们将展示如何计算它们:

有些特征的所有值并未出现在验证数据集中,因此我们只显示 hourconsumer_id:

图11: 每小时预测与实际值(标准化平均值)
图12: Consumer_id 的预测与实际值(标准化平均值)

在这两个数字中,结果都令人鼓舞。在 图12,我们注意到消费者 MT_004 与其他消费者相比,表现稍差。如果我们将每个消费者的 P50 损失与我们之前计算的平均用电量进行标准化,我们就可以验证这一点。

灰色条表示每个变量的分布。我经常做的一件事是找出哪些值的频率较低。然后,我检查模型在这些领域的表现。因此,您可以轻松检测您的模型是否捕获了罕见事件的行为。

一般来说,您可以使用此 TFT 功能来探测模型的弱点并继续进一步调查。

我们可以无缝地使用 时间融合变压器 奥图纳 执行超参数调整:

问题是,由于 TFT 是基于 Transformer 的模型,因此您将需要大量的硬件资源!

时间融合变压器 对于时间序列社区来说无疑是一个里程碑。

该模型不仅实现了 SOTA 结果,还为预测的可解释性提供了框架。该型号也可在 飞镖 python 库,基于 PyTorch Forecasting 库。

最后,如果您有兴趣了解架构 时间融合变压器 详细情况,请检查 配套文章 在原纸上。

时间融合变压器:利用深度学习进行时间序列预测 - 完整教程从来源重新发布 https://towardsdatascience.com/temporal-fusion-transformer-time-series-forecasting-with-deep-learning-complete-tutorial-d32c1e51cd91?source= rss—-7f60cf5620c9—4 通过 https://towardsdatascience.com/feed

–>

时间戳记:

更多来自 区块链顾问