DeepAR(Deep Autoregressive)是一种用于时间序列预测的深度学习模型,由亚马逊的研究团队提出。
在时间序列预测领域,基于历史数据预测未来值的能力至关重要,先进的机器学习算法已变得不可或缺。DeepAR 就是这样一种强大的算法,它因其在处理复杂时间模式和生成准确预测方面的有效性而闻名。DeepAR 特别适合需要同时预测多个相关时间序列的场景,使其成为金融、电子商务和供应链管理等各个领域的宝贵工具。在本文中,我们将讨论 DeepAR 预测算法并将其实现用于时间序列预测。
DeepAR 预测算法适合处理各种时间序列预测问题,特别是在以下情境中表现良好:
- 不规则和非周期性的时间序列: DeepAR 不需要时间序列具有固定的周期性,因此适用于不规则和非周期性的数据。它能够捕捉复杂的模式和趋势,适用于各种业务和应用领域。
- 多变量时间序列: DeepAR 能够有效处理多变量时间序列,其中每个时间步可以包含多个相关联的变量。这使其适用于需要考虑多个因素的预测问题,如销售预测、交通流量预测等。
- 长期预测: DeepAR 在长期预测任务中表现良好。由于其递归结构和对历史信息的有效利用,它能够在未来时间步骤上做出准确的预测。
- 可处理的不确定性: DeepAR 不仅提供点预测,还能输出对预测不确定性的估计。这对于业务决策和风险管理非常有用。
- 需求较高的时间序列预测任务: 如果你需要一个更复杂、更强大的模型来处理特定领域或应用中的时间序列数据,DeepAR 可能是一个不错的选择。
例子包括零售销售预测、交通流量预测、服务器负载预测等。需要注意的是,DeepAR 的性能可能取决于数据的特征和任务的要求,因此在应用之前最好进行模型调整和验证。
什么是 DeepAR?
对于高级时间序列预测,亚马逊公司开发了一种最先进的概率预测算法,称为深度自回归或 DeepAR 预测算法。这是一种深度学习模型,专门用于捕获与未来预测相关的固有不确定性。与依赖确定性点估计的传统预测方法不同,DeepAR 提供未来值的概率分布,使决策者能够评估可能结果的范围并做出更明智的决策。
DeepAR的工作原理
DeepAR的一些关键工作原理如下:
- 自回归架构: DeepAR 采用自回归神经网络架构,其中每个时间步长的预测取决于历史观察结果和模型自身过去预测的组合。这使得算法能够捕获时间序列数据中更复杂的依赖关系,使其擅长处理具有复杂模式和趋势的序列。
- 分类特征的嵌入: DeepAR 可以无缝合并来自与时间序列数据相关的分类特征的信息。这是通过使用嵌入来实现的,它将分类变量转换为连续向量。包含这些特征可以增强模型识别数据中的模式和关系的能力,特别是在外部因素影响时间序列的情况下。
- 时间注意力机制:为了有效权衡历史数据中不同时间点的重要性,DeepAR采用了时间注意力机制。这种机制使模型能够专注于时间序列的相关部分,根据数据中存在的模式动态调整其注意力。
- 使用分位数损失进行训练: DeepAR 使用概率方法进行训练,可最大限度地减少分位数损失。这意味着模型经过优化以生成预测区间,表示未来可能值的范围以及相关的置信水平。这种概率框架在决策过程中特别有价值,可以让决策者对与预测相关的不确定性有细致入微的了解。
DeepAR预测分步实施
1、安装所需的模块
首先,我们将所有必需的 Python 模块安装到运行时。
!pip install gluonts !pip install --upgrade mxnet==1.6.0 !pip install "gluonts[torch]"
|
2、导入所需的库
现在我们将导入所有必需的Python库,如NumPy、Pandas、Matplotlib和OS等。
Python3
import numpy as np import pandas as pd import os import matplotlib as mpl import matplotlib.pyplot as plt from gluonts.torch.model.deepar import DeepAREstimator from gluonts.dataset.common import ListDataset from gluonts.dataset.field_names import FieldName from gluonts.evaluation.backtest import make_evaluation_predictions from tqdm.autonotebook import tqdm from gluonts.evaluation import Evaluator from typing import Dict
|
3、数据集加载和预处理
现在我们将加载两个简单的数据集,因为 DeepAR 主要用于多个时间序列预测。这两个数据集都可以从这里下载:dataset1和dataset2。之后,我们将对数据集进行切片,使它们均匀分布并合并它们。然后合并的数据集将被分为训练集和测试集。
<strong>https://www.kaggle.com/datasets/robikscube/hourly-energy-consumption/data?select=COMED_hourly.csv</strong> df_comed = pd.read_csv("/content/COMED_hourly.csv", parse_dates=True) <strong>https://www.kaggle.com/datasets/robikscube/hourly-energy-consumption/data?select=DOM_hourly.csv</strong> df_dom = pd.read_csv("/content/DOM_hourly.csv", parse_dates=True) <strong>Slicing the datasets to make equal lengh data</strong> df_comed = df_comed.loc[df_comed["Datetime"] > '2011-12-31'].reset_index(drop=True) df_dom = df_dom.loc[df_dom["Datetime"] > '2011-12-31'].reset_index(drop=True) df_comed = df_comed.T df_comed.columns = df_comed.iloc[0] df_comed = df_comed.drop(df_comed.index[0]) df_comed['Station_Name'] = "COMED" df_comed = df_comed.reset_index(drop=True) df_dom = df_dom.T df_dom.columns = df_dom.iloc[0] df_dom = df_dom.drop(df_dom.index[0]) df_dom['Station_Name'] = "DOM" df_dom = df_dom.reset_index(drop=True) df_all = pd.concat([df_comed, df_dom], axis=0) df_all = df_all.set_index("Station_Name") df_all = df_all.reset_index()
ts_code = df_all['Station_Name'].astype('category').cat.codes.values freq = "1H" <strong>rate at which dataset is sampled</strong> start_train = pd.Timestamp("2011-12-31 01:00:00", freq=freq) start_test = pd.Timestamp("2016-06-10 18:00:00", freq=freq) prediction_lentgh = 24 * 1 <strong>Our prediction Length is 1 Day</strong> <strong>training and testing sets split</strong> df_train = df_all.iloc[:, 1:40000].values df_test = df_all.iloc[:, 40000:].values
|
4、定义模型
现在,我们将通过定义 DeepAR 估计模型的各种超参数来初始化该模型,具体参数如下->
- freq:该参数定义时间序列数据的频率。它表示时间序列在一个周期内的时间步数。我们的数据每天都有观测结果,因此频率由 freq 变量决定。
- 上下文长度(context_length):该参数设置了模型用于学习历史数据中的模式和依赖关系的时间步数。这里设置为 (24 * 5),表示模型回顾的时间段相当于 5 天(假设每个时间步长对应一个小时)。
- 预测长度(prediction_length):该参数指定模型应生成多远的预测。它决定了预测范围的长度。
- cardinality(类别数量):该参数是一个列表,表示数据集中每个分类特征的类别数。
- num_layer(层数):它决定了神经网络架构的层数。在我们的例子中,模型配置为 2 层。
- dropout_rate:这是一种正则化技术,有助于防止过度拟合。它表示在训练过程中丢弃的输入单元的比例。0.25 表示每次更新时,25% 的输入单元将被随机设置为零。
- trainer_kwargs:这是一个字典,包含训练过程中的附加参数。在我们的例子中,它包括 "max_epochs":16,用于设置最大训练历元数。一个历元是对整个训练数据集的一次完整遍历。
estimator = DeepAREstimator(freq=freq, <strong>context length is number of time steps will look back(5 days in a week)</strong> context_length=24 * 5, prediction_length=prediction_lentgh, cardinality=[1], num_layers=2, dropout_rate=0.25, trainer_kwargs={'max_epochs': 16} )
|
5、模型训练
现在我们准备通过传递刚刚准备好的训练数据集来训练 DeepAR 估计器。这里我们将利用四个CPU代码作为工作者来进行快速处理。
predictor = estimator.train(training_data=train_ds, num_workers=4)
6、预测
这样,训练就完成了。现在我们的任务只是绘制预测值与实际值。DeepAR 支持置信区间值,因此我们将采用预测的中值来做出最接近的预测。在图中,实际线和预测线之间的差距是置信区(例如预测的 75% 或 90% 置信度等)。
forecast_it, ts_it = make_evaluation_predictions( dataset=test_ds, predictor=predictor, num_samples=100, )
print("Gathering time series conditioning values ...") tss = list(tqdm(ts_it, total=len(df_test))) print("Gathering time series predictions ...") forecasts = list(tqdm(forecast_it, total=len(df_test)))
def plot_prob_forecasts(ts_entry, forecast_entry): plot_length = prediction_lentgh prediction_intervals = (0.5, 0.8) legend = ["observations", "median prediction"] + \ [f"{k*100}% prediction interval" for k in prediction_intervals][::-1]
fig, ax = plt.subplots(1, 1, figsize=(10, 7)) ts_entry[-plot_length:].plot(ax=ax, color='blue', label='observations')
<strong>Extract the median prediction</strong> median = np.median(forecast_entry, axis=0) ax.plot(ts_entry.index[-plot_length:], median[-plot_length:], color='orange', label='median prediction')
<strong>Extract the prediction intervals if available</strong> if len(forecast_entry) > 1: lower, upper = np.percentile(forecast_entry, q=[(1 - k) * 100 / 2 for k in prediction_intervals], axis=0), np.percentile( forecast_entry, q=[(1 + k) * 100 / 2 for k in prediction_intervals], axis=0)
<strong>Ensure lower and upper are 1-D arrays</strong> lower, upper = lower[-plot_length:], upper[-plot_length:]
plt.grid(which="both") plt.legend(legend, loc="upper left") plt.show()
for i in tqdm(range(2)): ts_entry = tss<i> forecast_entry = np.array(forecasts<i>.samples) plot_prob_forecasts(ts_entry, forecast_entry)
|
评价
DeepAR 本身提供了广泛的性能指标,例如分位数损失、MAPE 等。
evaluator = Evaluator(quantiles=[0.1, 0.5, 0.9]) agg_metrics, item_metrics = evaluator(iter(tss), iter(forecasts), num_series=len(df_test)) item_metrics
|
Output:
item_id forecast_start MSE abs_error abs_target_sum abs_target_mean seasonal_error MASE MAPE sMAPE num_masked_target_values ND MSIS QuantileLoss[0.1] Coverage[0.1] QuantileLoss[0.5] Coverage[0.5] QuantileLoss[0.9] Coverage[0.9] 0 None 2018-06-19 23:00 318517.437500 11284.473633 297067.0 12377.791667 777.236948 0.604946 0.038610 0.037733 0.0 0.037986 3.896573 3385.887109 0.041667 11284.473633 0.583333 6079.214258 1.000000 1 None 2018-06-19 23:00 835246.333333 16977.113281 414494.0 17270.583333 909.647006 0.777642 0.040786 0.042074 0.0 0.040959 4.620998 9115.450977 0.000000 16977.114258 0.166667 6252.767773 0.708333
|
因此,我们可以看到每种情况下的错误都非常低。
结论
我们可以得出结论,DeepAR 是一种用于预测问题的有效深度学习模型。然而,为了更准确的预测,需要在更多的时期内训练模型。