时间序列预测方法ARIMA、Prophet、LSTM的比较

您所在的位置:网站首页 prophet预测出负值 时间序列预测方法ARIMA、Prophet、LSTM的比较

时间序列预测方法ARIMA、Prophet、LSTM的比较

2024-02-18 00:07| 来源: 网络整理| 查看: 265

假设我们赞同对时间和因果关系的线性理解,就像Sheldon Cooper博士所说的那样,那么将历史事件表示为一系列随时间观察到的数值和特征,就为从过去学习奠定了基础。然而,时间序列与其他数据集有些不同,包括文本或DNA序列等顺序数据。

时间部分提供了额外的信息,在预测未来时可能会很有用。因此,有许多专门为处理时间序列而设计的不同技术。这些技术包括从显示趋势随时间演变或重复的简单可视化工具到利用时间序列的特定结构的高级机器学习模型。

在这篇文章中,我们将讨论从时间序列数据中学习的三种流行方法。

用于时间序列预测的经典ARIMA框架 Facebook的内部模型Prophet,它是专门为从商业时间序列中学习而设计的 LSTM模型,一种强大的递归神经网络方法,已被用于在连续数据的许多问题上取得最知名的结果。

然后我们将展示如何使用Neptune及其强大的功能来比较这三种模型的结果。

让我们先简单介绍一下这三种方法。

三种方法的概述。ARIMA, Prophet 和 LSTM 自回归移动平均模型

ARIMA是一类时间序列预测模型,这个名字是自回归整合移动平均的缩写。ARIMA的骨干是一个数学模型,它利用时间序列的过去值来表示时间序列的值。这个模型基于两个主要特征。

过去的价值。很明显,过去的行为是对未来的良好预测。唯一的问题是我们应该使用多少个过去的值。该模型使用最后的p个时间序列值作为特征。这里p是一个超参数,需要在我们设计模型时确定。 **过去的错误。**该模型可以使用它在过去的表现如何的信息。因此,我们把模型最近发生的q个错误作为特征。同样,q是一个超参数。

这里的一个重要方面是,时间序列需要被标准化,从而使模型独立于季节性或临时趋势。这方面的正式术语是,我们希望模型在静止的时间序列上被训练。在最直观的意义上,静止性意味着产生时间序列的过程的统计属性不随时间变化。它并不意味着该序列不随时间变化,只是它的变化方式本身不随时间变化。

有几种使时间序列静止的方法,最流行的是差分法。通过用n-1个差值替换序列中的n个值,我们迫使模型学习更高级的模式。当模型预测一个新的数值时,我们只需将最后的观察值加入其中,以获得最终的预测结果。如果你第一次遇到这个概念,静止性可能有些令人困惑,你可以参考本教程以了解更多细节。

参数

从形式上看,ARIMA是由三个参数p、d和q定义的,它们描述了模型的三个主要组成部分。

综合 (ARIMA中的I)。 实现静止性所需的差异数由参数d给出。让原始特征为Yt,其中t是序列中的索引。我们使用以下对d的不同值的变换来创建一个静止的时间序列。 对于d=0

在这种情况下,序列已经是静止的,我们没有什么可做的。

对于d=1

ARIMA parameters

这是最典型的转换。

对于d=2

ARIMA parameters

请注意,微分可以被看作是微分的离散版本。对于d=1,新的特征代表了数值的变化。而对于d=2,新的特征代表变化的速度,就像微积分中的二阶导数。 上述方法也可以推广到d>2,但在实践中很少使用。

自动回归(AR)。 参数p告诉我们在表达当前值时要考虑多少个过去的值。本质上,我们学习一个模型,预测时间t的价值。

AutoRegressive (AR)

移动平均(MA): 应该考虑过去多少个预测误差。一个新的值被计算为:。

AutoRegressive (AR)

过去的预测误差。

AutoRegressive (AR)

三个部分的组合给出了ARIMA(p,d,q)模型。更确切地说,我们首先对时间序列进行整合,然后加入AR和MA模型并学习相应的系数。

预言家

Prophet FB是由Facebook开发的一种算法,用于内部预测不同商业应用的时间序列值。因此,它是专门为商业时间序列的预测而设计的。

它是一个由四个部分组成的加法模型。

Prophet

让我们来讨论每个组成部分的含义。

g(t)。它代表了趋势,目的是为了捕捉系列的一般趋势。例如,随着越来越多的人加入网络,Facebook上的广告浏览量可能会随着时间而增加。但是,增加的确切函数会是什么? s(t): 它是 季节性 成分。广告浏览量也可能取决于季节。例如,在北半球的夏季,人们可能会花更多的时间在户外,而减少在电脑前的时间。这种季节性的波动对于不同的商业时间序列来说可能是非常不同的。因此,第二部分是一个模拟季节性趋势的函数。 h(t)。 假期部分。我们使用对大多数商业时间序列有明显影响的假期信息。需要注意的是,不同年份、不同国家的假期都不一样,因此需要明确提供给模型的信息。 误差项εt代表模型无法解释的随机波动。像往常一样,假设εt遵循正态分布N (0,σ2),均值为零,未知方差为σ,必须从数据中得出。 LSTM 递归神经网络

LSTM是长短期记忆的缩写。LSTM细胞被用于递归神经网络中,该网络学习从可变长度的序列中预测未来。请注意,递归神经网络适用于任何类型的序列数据,与ARIMA和Prophet不同,它不限于时间序列。

LSTM单元背后的主要想法是学习到目前为止所看到的序列的重要部分,并忘记那些不太重要的部分。这是通过所谓的门来实现的,即具有不同学习目标的函数,如。

到目前为止看到的时间序列的紧凑表示 如何将新的输入与过去的序列表示相结合 对该系列忘记什么 输出什么作为下一个时间步骤的预测。

设计一个基于LSTM的最佳模型可能是一项艰巨的任务,需要仔细调整超参数。以下是一个基于LSTM的模型需要考虑的最重要的参数列表。

要用多少个LSTM单元来表示序列?请注意,每个LSTM单元将专注于到目前为止所处理的时间序列的特定方面。少量的LSTM单元不太可能捕捉到序列的结构,而过多的LSTM单元可能会导致过度拟合。 典型的做法是,首先,我们把输入序列转换成另一个序列,即数值ht。这就产生了一个新的表示,因为 ht状态捕捉到了到目前为止所处理的序列的结构。但在某些时候,我们不需要所有的ht值,而只需要最后的ht值。这将使我们能够将不同的ht送入全连接层,因为每个ht都对应于单个LSTM单元的最终输出。设计确切的结构可能需要仔细的微调和多次试验。

The structure of an LSTM cell

图1:LSTM单元的结构 |来源

最后,我们想重申,递归神经网络是一类用于从序列数据中学习的通用方法,它们可以与任意的序列(如自然文本或音频)一起工作。

实验评估。ARIMA vs Prophet vs LSTM 数据集

我们将使用印度金融服务公司Bajaj Finserv Ltd的股票交易数据来比较这三种模型。该数据集的时间跨度从2008年到2021年底。它包含了每天的股票价格(平均值、最低值和最高值),以及交易股票的总成交量和成交额。该数据集的一个子样本显示在图2中。

The data used for evaluation

图2:用于评估的数据|来源:《中国证券报》。作者

我们感兴趣的是预测每天结束时的成交量加权平均价格(VWAP)变量。 图3是时间序列VWAP值的图表。

The daily values of the VWAP variable

图3:VWAP变量的每日数值|来源:作者。作者

为了评估,我们将时间序列分为训练和测试时间序列,其中训练序列包括直到2018年底的数据(见图4)。

观察值的总数:3201

训练观测值:2624

测试观测值:577

The train and test subsets of the VWAP time series

图4:VWAP时间序列的训练子集和测试子集 | 来源。作者

实施

为了正常工作,机器学习模型需要良好的数据,为此,我们将做一点特征工程。特征工程背后的目标是设计更强大的模型,利用数据中的不同模式。由于三个模型学习了过去观察到的模式,我们创建了额外的特征,彻底描述股票运动的近期趋势。

特别是,我们在3天、7天和30天内跟踪不同交易特征的移动平均线。此外,我们还考虑了诸如月份、周数和工作日等特征。因此,我们模型的输入是多维的。 一个使用的特征工程的小例子看起来如下。

lag_features = ["High", "Low", "Volume", "Turnover", "Trades"] df_rolled_7d = df[lag_features].rolling(window=7, min_periods=0) df_mean_7d = df_rolled_7d.mean().shift(1).reset_index().astype(np.float32)

上面的代码摘录显示了如何添加描述股票销售的几个特征在过去一周的运行平均值。总的来说,我们创建了一个外生特征集。

Implementation

现在,让我们开始使用我们的主要模型。

ARIMA模型

我们从公开提供的软件包pmdarima中实现了ARIMA版本。函数auto_arima接受一个额外的参数,即外生特征列表,我们提供在特征工程步骤中创建的特征。auto_arima的主要优点是它首先进行了几个测试,以决定时间序列是否是静止的。此外,它还采用了智能网格搜索策略,确定上一节中讨论的p、d和q的最佳参数。

from pmdarima import auto_arima model = auto_arima( df_train["VWAP"], exogenous=df_train[exogenous_features], trace=True, error_action="ignore", suppress_warnings=True)

对参数p、d和q的不同值的网格搜索如下所示。最后,返回具有最小的AIC值的模型。(AIC值是一个衡量模型复杂性的标准,它同时优化了预测模型的准确性和复杂性)。

ARIMA

然后通过以下方法获得对测试集的预测结果

forecast = model.predict(n_periods=len(df_valid), exogenous=df_valid[exogenous_features]) 预言家

我们使用公开可用的Prophet的Python实现。输入的数据必须包含两个特定的字段。

日期:应该是一个有效的日历日期,可以从中计算出假期 Y:我们想要预测的目标变量。

我们将模型实例化为。

from prophet import Prophet model = Prophet()

在特征工程中创建的特征必须明确地添加到模型中,如下所示。

for feature in exogenous_features: model.add_regressor(feature)

最后,我们拟合该模型。

model.fit(df_train[["Date", "VWAP"] + exogenous_features].rename(columns={"Date": "ds", "VWAP": "y"}))

对测试集的预测结果为:。

forecast = model.predict(df_test[["Date", "VWAP"] + exogenous_features].rename(columns={"Date": "ds"})) LSTM

我们使用了LSTM的Keras实现。

import tensorflow as tf from keras.layers import Dropout from tensorflow.keras.layers import Dense from tensorflow.keras.layers import LSTM from tensorflow.keras.metrics import RootMeanSquaredError, MeanAbsoluteError from tensorflow.keras.models import Sequential

该模型是由以下函数定义的。

def get_model(params, input_shape): model = Sequential() model.add(LSTM(units=params["lstm_units"], return_sequences=True, input_shape=(input_shape, 1))) model.add(Dropout(rate=params["dropout"])) model.add(LSTM(units=params["lstm_units"], return_sequences=True)) model.add(Dropout(rate=params["dropout"])) model.add(LSTM(units=params["lstm_units"], return_sequences=True)) model.add(Dropout(rate=params["dropout"])) model.add(LSTM(units=params["lstm_units"], return_sequences=False)) model.add(Dropout(rate=params["dropout"])) model.add(Dense(1)) model.compile(loss=params["loss"], optimizer=params["optimizer"], metrics=[RootMeanSquaredError(), MeanAbsoluteError()]) return model

然后我们用给定的参数集实例化一个模型。我们使用时间序列中过去的90个观察值作为序列,作为模型的输入。其他超参数描述了结构和训练模型的具体选择。

params = { "loss": "mean_squared_error", "optimizer": "adam", "dropout": 0.2, "lstm_units": 90, "epochs": 30, "batch_size": 128, "es_patience" : 10 } model = get_model(params=params, input_shape=x_train.shape[1])

以上的结果是以下的Keras模型(见图5)。

A summary of the Keras LSTM model

图5:Keras LSTM模型的摘要|来源:中国新闻网。作者

然后,我们创建一个回调来实现早期停止,即如果模型在给定的历时数(在我们的例子中是10)内对验证数据集没有产生改善,就停止训练。

es_callback = tf.keras.callbacks.EarlyStopping(monitor='val_root_mean_squared_error', mode='min', patience=params["es_patience"])

参数es_patience指的是早期停止的历时数。

最后,我们使用预定义的参数来拟合模型。

model.fit( x_train, y_train, validation_data=(x_test, y_test), epochs=params["epochs"], batch_size=params["batch_size"], verbose=1, callbacks=[neptune_callback, es_callback] ) 实验跟踪和模型比较

由于在这篇博文中,我们想回答一个简单的问题:哪个模型对测试数据集产生最准确的预测,我们将需要看看这三个模型之间的对比情况。

有许多不同的方法来进行模型比较,如创建记录不同指标评估的表格和图表,创建绘制预测值与测试集上的真实值的图表,等等。然而,对于这个练习,我们将使用Neptune。

什么是Neptune?

Neptune是一个MLOps的元数据存储,为运行大量实验的团队而建。

它为你提供了一个单一的地方来记录、存储、显示、组织、比较和查询你所有的模型构建元数据。

Neptune用于。

实验跟踪。在一个地方记录、显示、组织和比较ML实验。 模型注册表。版本、存储、管理和查询训练好的模型和模型构建元数据。 实时监控ML运行。记录和监控模型的训练、评估或生产的实时运行。

如本教程所述,我们首先创建一个Neptune项目并记录我们账户的API。

run = neptune.init(project='', api_token='')

变量运行可以被看作是一个文件夹,我们可以在其中创建包含不同信息的子文件夹。例如,我们可以创建一个名为模型的子文件夹,并在其中记录模型的名称。

run["model/name"] = "Arima"

我们将根据两个不同的指标来比较这些模型的准确性。

均方根误差(RMSE)

The root mean square error (RMSE)

平均绝对误差(MAE)

The mean absolute error (MAE)

请注意,这些数值可以通过设置相应的数值记录到Neptune中,例如,设置。

run["test/mae"] = mae run["test/rmse"] = mse

在运行表中可以看到三个模型的均方误差和平均平均误差相邻。

The mean square error and the mean average error for the three models can be seen next to each other. (The tags for each project are at the top.)

图6.Neptune UI中三个模型的MSE和MAE (每个项目的标签都在顶部)|来源

然后可以在Neptune中看到三种算法的并列比较,如图7所示。

Side by side comparison ARIMA Prophet LSTM

图7:三种模型的均方误差和平均误差可以在旁边看到 (每个项目的标签在顶部) |来源

我们看到,ARIMA产生了最好的性能,即它在测试集上取得了最小的平均平方误差和平均绝对误差。相比之下,LSTM神经网络在三个模型中表现最差。

在下面的图片中可以看到与真实值相对应的确切预测值。我们观察到,这三个模型都能捕捉到时间序列的整体趋势,但LSTM似乎是在曲线后面运行,即它需要更多的时间来调整自己以适应趋势的变化。在测试期间的最后几个月,先知似乎输给了ARIMA,它低估了真实值。

ARIMA predictions

图8:ARIMA的预测 | 来源:作者作者

Prophet predictions

图9:预言家的预测 |来源:作者作者

LSTM prediction

图10:LSTM预测|来源:作者。作者

深入研究模型的性能 ARIMA网格搜索

当对ARIMA中的p、d和q的不同值进行网格搜索时,我们可以绘制出平均平方误差的单个值。图11中的彩色圆点显示了不同ARIMA参数在验证集中的均方误差值。

Grid-search over the ARIMA parameters

图11:对ARIMA参数的网格搜索 |来源

预言家的趋势

在图12中,我们显示了先知的不同组成部分的变化。我们观察到,趋势是线性增长的,而季节性成分则表现出波动性。

The change of values of the different components in the Prophet over time

图12:预言家中不同成分的数值随时间的变化。作者

为什么LSTM的表现最差?

我们在Neptune中收集了在几个epochs中训练LSTM模型时的平均绝对误差。这是通过一个Neptune回调实现的,该回调捕捉训练元数据并自动记录到Neptune。结果显示在图13中。

请注意,虽然训练数据集上的误差在随后的历时中减少,但验证集上的误差却不是这样,它在第二个历时中达到最小,然后波动。这表明LSTM模型对于一个相当小的数据集来说太先进了,容易出现过拟合。尽管加入了正则化条款,如dropout,我们仍然无法避免过拟合。

The evolution of train and test error over different epochs of training the LSTM model

The evolution of train and test error over different epochs of training the LSTM model

图13:在训练LSTM模型的不同历时中,训练和测试误差的演变。

结论

在这篇博文中,我们介绍并比较了三种不同的时间序列预测的算法。正如预期的那样,没有明显的赢家,每种算法都有自己的优势和局限。下面我们总结一下我们对每种算法的观察。

ARIMA是一个强大的模型,正如我们所看到的,它为股票数据取得了最好的结果。一个挑战是,它可能需要仔细的超参数调整和对数据的良好理解。 Prophet是专门为商业时间序列预测设计的。它在股票数据方面取得了非常好的结果,但从轶事来看,它在其他领域的时间序列数据集上可能会失败得很厉害。特别是对于日历日期的概念不适用的时间序列,我们无法学习任何季节性模式。Prophet的优势在于它需要较少的超参数调整,因为它是专门为检测商业时间序列的模式而设计的。 基于LSTM的递归神经网络可能是最强大的从连续数据中学习的方法,而时间序列只是一个特例。基于LSTM的模型的潜力在从海量数据集学习时充分显现出来,在那里我们可以检测复杂的模式。与ARIMA或Prophet不同,它们不依赖于对数据的特定假设,如时间序列的静止性或Date场的存在。 一个缺点是,基于LSTM的RNNs很难解释,要获得对其行为的直觉是很有挑战性的。另外,为了取得好的结果,需要仔细调整超参数。 未来的方向

所以我希望你喜欢阅读这篇文章,现在你一定对我们在这里讨论的时间序列算法有了更好的理解。如果你想深入挖掘,这里有一些链接,可以找到一些有用的资源。祝你实验愉快!

PMD ARIMA。各个Python包的文档。 Prophet。Facebook Prophet的文档和教程。 Keras LSTM。Keras中LSTM RNNs的文档和示例。 Neptune。Neptune网站的教程和文档。 关于用Neptune跟踪ML实验的博文。 对ARIMA模型的深入概述。 关于用LSTM RNNs进行时间序列预测的教程。 预言家的原始研究论文。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3