Press "Enter" to skip to content

PatchTST:时间序列预测的重大突破

从理论到实践,理解PatchTST算法并与N-BEATS和N-HiTS一起在Python中应用

Photo by Ray Hennessy on Unsplash

Transformer-based模型已经成功应用于许多领域,例如自然语言处理(想想BERT或GPT模型)和计算机视觉等。

然而,当涉及到时间序列时,最先进的结果大多是由MLP模型(多层感知器)如N-BEATS和N-HiTS等实现的。最近的一篇论文甚至表明,简单的线性模型在许多基准数据集上优于复杂的基于Transformer的预测模型(请参阅Zheng等人,2022)。

尽管如此,一个新的基于Transformer的模型被提出,它在长期预测任务方面实现了最先进的结果:PatchTST

PatchTST代表patch time series transformer,它最初是由Nie、Nguyen等人在2023年3月的论文“A Time Series is Worth 64 Words: Long-Term Forecasting with Transformers”中首次提出的。他们提出的方法在与其他基于Transformer的模型相比时实现了最先进的结果。

在本文中,我们首先探讨PatchTST的内部工作原理,使用直觉和没有方程式。然后,我们在一个预测项目中应用该模型,并将其性能与MLP模型(如N-BEATS和N-HiTS)进行比较和评估其性能。

当然,要了解有关PatchTST的更多详细信息,请确保参考原始论文。

使用我的免费Python时间序列速查表学习最新的时间序列分析技术!获取统计和深度学习技术的实现,全部都在Python和TensorFlow中!

让我们开始吧!

探索PatchTST

如上所述,PatchTST代表patch time series transformer。

如其名称所示,它利用了patching和transformer架构。它还包括通道独立性以处理多变量时间序列。一般的架构如下所示。

The PatchTST model architecture. We see that the model makes use of channel-independence to treat multivariate time series. In the transformer backbone, we also see the use of patching (illustrated by the rectangles). Plus, there are two versions to the model: supervised and self-supervised. Image by Nie Y., Nguyen N., Sinthong P., Kalagnanam J. from A Time Series is Worth 64 Words: Long-Term Forecasting with Transformers .

从上图中可以获得大量信息。这里的关键元素是PatchTST使用通道独立性来预测多变量时间序列。然后,在其transformer骨干中,该模型使用patching,这些patch由小垂直矩形表示。此外,该模型有两个版本:监督和自监督。

让我们更详细地探讨PatchTST的架构和内部工作原理。

通道独立性

在这里,多变量时间序列被视为多通道信号。每个时间序列基本上是一个包含信号的通道。

<img alt="PatchTST模型的概述。在这里,我们着重介绍通道独立性的实现,即Transformer骨干的每个输入令牌仅包含来自一个通道或一个时间序列的信息。图像由Nie Y.,Nguyen N.,Sinthong P.,Kalagnanam J.从“时间序列值得64个词:使用Transformer进行长期预测”中获取。

在上面的图中,我们可以看到如何将多元时间序列分离成单独的序列,并将每个序列作为输入令牌馈送到Transformer骨干中。然后,对每个序列进行预测,并将结果连接起来进行最终预测。

修补

大多数基于Transformer的预测模型的工作都集中在构建新机制以简化原始的注意力机制。然而,它们仍然依赖于点对点的注意力,在时间序列中并不理想。

在时间序列预测中,我们希望提取过去时间步和未来时间步之间的关系以进行预测。使用点对点的注意力时,我们试图从单个时间步中检索信息,而不考虑周围的时间点。换句话说,我们隔离了一个时间步,并且不查看之前或之后的点。

这就像在不查看句子中周围单词的情况下理解单词的含义。

因此,PatchTST利用修补来提取时间序列中的本地语义信息。

修补的工作原理

每个输入序列都被分成补丁,这只是来自原始序列的较短序列。

PatchTST的Transformer骨干。在这里,我们可以看到输入时间序列(在图像底部)经过修补,产生多个补丁(垂直矩形),然后发送到Transformer编码器。由Nie Y.,Nguyen N.,Sinthong P.,Kalagnanam J.的图像来自A Time Series is Worth 64 Words:Long-Term Forecasting with Transformers .

这里,补丁可以重叠或不重叠。补丁的数量取决于补丁P的长度和步幅S。这里,步幅就像卷积一样,简单地表示连续补丁的开始之间有多少个时间步长。

可视化修补。在这里,我们有一个由15个时间步组成的序列,补丁长度为5,步幅也为5,因此得到三个补丁。由作者提供的图像。

在上面的图中,我们可以看到修补的结果。这里,序列长度(L)为15个时间步,补丁长度(P)为5,步幅(S)为5。结果是将序列分成3个补丁。

修补的优点

通过修补,模型可以通过查看一组时间步骤来提取本地语义含义,而不是查看单个时间步骤。

它还有一个额外的好处,可以大大减少馈送到Transformer编码器的令牌数量。在这里,每个补丁都成为输入到Transformer的一个输入令牌。这样,我们可以将令牌的数量从L减少到大约L/S。

这样,我们大大减少了模型的空间和时间复杂度。这反过来意味着我们可以馈送模型更长的输入序列以提取有意义的时间关系。

因此,通过修补,模型更快,更轻,可以处理更长的输入序列,这意味着它可能能够更好地学习序列并进行更好的预测。

Transformer编码器

一旦序列被修补,它就被馈送到Transformer编码器。这是经典的Transformer架构。没有进行任何修改。

然后,输出被馈送到线性层,进行预测。

使用表征学习改进 PatchTST

文献的作者建议使用表征学习来进一步改进该模型。

在 PatchTST 中可视化自监督表征学习。在这里,模型将随机屏蔽补丁并学习重构它们。图片来自 Nie Y.、Nguyen N.、Sinthong P.、Kalagnanam J. 的“一系列时间相当于 64 个单词:使用 Transformer 进行长期预测”。

从上图可以看出,PatchTST 可以使用自监督表征学习来捕获数据的抽象表征。这可以导致潜在的预测性能改进。

这里,过程非常简单,随机补丁将被屏蔽,这意味着它们将被设置为 0。这在上图中用空白的垂直矩形表示。然后,模型被训练以重新创建原始补丁,这是在图的顶部输出的,作为灰色垂直矩形。

现在我们已经了解了 PatchTST 的工作原理,让我们将其与其他模型进行比较并查看其表现如何。

使用 PatchTST 进行预测

在文献中,PatchTST 与其他基于 Transformer 的模型进行了比较。然而,最近已经发布了基于 MLP 的模型,例如 N-BEATS 和 N-HiTS,并且在长期预测任务上也展示了最新的性能。

本节的完整源代码可在 GitHub 上获得。

在这里,让我们应用 PatchTST、N-BEATS 和 N-HiTS,并将其与这两个基于 MLP 的模型进行比较。

对于此练习,我们使用 Exchange 数据集,这是研究中常用的长期预测基准数据集。该数据集包含八个国家相对于美元的每日汇率,从 1990 年到 2016 年。该数据集通过 MIT 许可证提供。

初始设置

让我们首先导入所需的库。在这里,我们将使用 neuralforecast,因为他们具有 PatchTST 的开箱即用实现。对于数据集,我们使用包括评估预测算法的所有流行数据集的 datasetsforecast 库。

import torchimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom neuralforecast.core import NeuralForecastfrom neuralforecast.models import NHITS, NBEATS, PatchTSTfrom neuralforecast.losses.pytorch import MAEfrom neuralforecast.losses.numpy import mae, msefrom datasetsforecast.long_horizon import LongHorizon

如果已安装 CUDA,则 neuralforecast 将自动利用 GPU 训练模型。在我的环境中,我没有安装它,这就是为什么我没有进行广泛的超参数调整或在非常大的数据集上进行训练。

完成后,让我们下载 Exchange 数据集。

Y_df, X_df, S_df = LongHorizon.load(directory="./data", group="Exchange")

在这里,我们看到我们得到了三个数据框。第一个包含每个国家的日汇率。第二个包含外生时间序列。第三个包含静态外生变量(如天、月、年、小时或我们知道的任何未来信息)。

对于此练习,我们仅使用 Y_df

然后,让我们确保日期具有正确的类型。

Y_df['ds'] = pd.to_datetime(Y_df['ds'])Y_df.head()
Exchange 数据集的前五行。图片由作者提供。

在上面的图中,我们可以看到我们有三列。第一列是一个唯一标识符,当使用 neuralforecast 时必须有一个id列。然后,ds 列有日期,y 列有汇率。

Y_df['unique_id'].value_counts()
Showing the number of observations per unique id. Image by the author.

从上图中,我们可以看到每个唯一标识符对应一个国家,并且我们每个国家有7588个观察值。

现在,我们定义验证集和测试集的大小。在这里,我选择760个时间步长作为验证集,1517个时间步长作为测试集,如 datasets 库所指定的。

val_size = 760test_size = 1517print(n_time, val_size, test_size)

然后,让我们绘制其中一个序列,以查看我们正在处理的内容。在这里,我决定绘制第一个国家(unique_id = 0)的系列,但请随意绘制另一个系列。

u_id = '0'x_plot = pd.to_datetime(Y_df[Y_df.unique_id==u_id].ds)y_plot = Y_df[Y_df.unique_id==u_id].y.valuesx_plotx_val = x_plot[n_time - val_size - test_size]x_test = x_plot[n_time - test_size]fig, ax = plt.subplots(figsize=(12,8))ax.plot(x_plot, y_plot)ax.set_xlabel('Date')ax.set_ylabel('Exhange rate')ax.axvline(x_val, color='black', linestyle='--')ax.axvline(x_test, color='black', linestyle='--')plt.text(x_val, -2, 'Validation', fontsize=12)plt.text(x_test,-2, 'Test', fontsize=12)plt.tight_layout()
Daily exchange rate for the first country, from 1990 to 2016. Image by the author.

从上图中,我们可以看到我们有相当嘈杂的数据,没有明显的季节性。

建模

探索了数据之后,让我们开始使用 neuralforecast 进行建模。

首先,我们需要设置时间跨度。在这种情况下,我使用96个时间步长,因为这个时间跨度也用在了PatchTST论文中。

然后,为了公平评估每个模型,我决定将输入大小设置为两倍的时间跨度(因此是192个时间步长),并将最大时期数设置为50。所有其他超参数都保持默认值。

horizon = 96models = [NHITS(h=horizon,               input_size=2*horizon,               max_steps=50),         NBEATS(h=horizon,               input_size=2*horizon,               max_steps=50),         PatchTST(h=horizon,                 input_size=2*horizon,                 max_steps=50)]

然后,我们通过指定我们要使用的模型和预测频率(在这种情况下为每日)来初始化 NeuralForecast 对象。

nf = NeuralForecast(models=models, freq='D')

现在,我们准备预测。

预测

为了生成预测,我们使用 cross_validation 方法利用验证集和测试集。它将返回一个包含所有模型的预测和相关真实值的 DataFrame。

preds_df = nf.cross_validation(df=Y_df, val_size=val_size, test_size=test_size, n_windows=None)
预测DataFrame的前五行。图片来自作者。

可以看到,对于每个id,我们都有每个模型的预测值,以及y列中的真实值。

现在,为了评估模型,我们必须将实际和预测值的数组重塑为形状为(number of series, number of windows, forecast horizon)的形状。

y_true = preds_df['y'].valuesy_pred_nhits = preds_df['NHITS'].valuesy_pred_nbeats = preds_df['NBEATS'].valuesy_pred_patchtst = preds_df['PatchTST'].valuesn_series = len(Y_df['unique_id'].unique())y_true = y_true.reshape(n_series, -1, horizon)y_pred_nhits = y_pred_nhits.reshape(n_series, -1, horizon)y_pred_nbeats = y_pred_nbeats.reshape(n_series, -1, horizon)y_pred_patchtst = y_pred_patchtst.reshape(n_series, -1, horizon)

完成后,我们可以选择绘制模型的预测结果。这里,我们绘制了第一个系列的第一个窗口中的预测结果。

fig, ax = plt.subplots(figsize=(12,8))ax.plot(y_true[0, 0, :], label='True')ax.plot(y_pred_nhits[0, 0, :], label='N-HiTS', ls='--')ax.plot(y_pred_nbeats[0, 0, :], label='N-BEATS', ls=':')ax.plot(y_pred_patchtst[0, 0, :], label='PatchTST', ls='-.')ax.set_ylabel('Exchange rate')ax.set_xlabel('Forecast horizon')ax.legend(loc='best')plt.tight_layout()
第一个系列的每日汇率预测结果,在第一个窗口中。图片来自作者。

这张图片有点令人失望,因为N-BEATS和N-HiTS的预测结果与实际值相差很大。然而,PatchTST虽然也有误差,但似乎是最接近实际值的。

当然,我们必须对此持保留态度,因为我们只是在可视化一个系列中的预测结果,在一个预测窗口中。

评估

因此,让我们评估每个模型的性能。为了复制论文中的方法,我们使用MAE和MSE作为性能指标。

data = {'N-HiTS': [mae(y_pred_nhits, y_true), mse(y_pred_nhits, y_true)],       'N-BEATS': [mae(y_pred_nbeats, y_true), mse(y_pred_nbeats, y_true)],       'PatchTST': [mae(y_pred_patchtst, y_true), mse(y_pred_patchtst, y_true)]}metrics_df = pd.DataFrame(data=data)metrics_df.index = ['mae', 'mse']metrics_df.style.highlight_min(color='lightgreen', axis=1)
所有模型的表现。在这里,PatchTST实现了最低的MAE和MSE。图片来自作者。

在上面的表格中,我们看到PatchTST是冠军模型,因为它实现了最低的MAE和MSE。

当然,这不是最彻底的实验,因为我们只使用了一个数据集和一个预测范围。然而,有趣的是,一个基于Transformer的模型可以与最先进的MLP模型竞争。

结论

PatchTST 是一种基于 Transformer 模型的方法,通过打补丁的方式提取时间序列数据中的局部语义信息。这使得模型训练更快,并且具有更长的输入窗口。

与其他基于 Transformer 的模型相比,它已经实现了最先进的性能。在我们的实验中,我们看到它的表现比 N-BEATS 和 N-HiTS 更好。

虽然这并不意味着它比 N-HiTS 或 N-BEATS 更好,但在预测长期趋势时,它仍然是一个有趣的选择。

谢谢阅读!我希望你喜欢这篇文章,学到了一些新的知识!

干杯 🍻

参考文献

“A Time Series is Worth 64 Words: Long-Term Forecasting with Transformers” ,Nie Y.,Nguyen N. 等人。

“Neuralforecast”,Olivares K.,Challu C.,Garza F.,Canseco M.,Dubrawski A.。

Leave a Reply

Your email address will not be published. Required fields are marked *