统计学、机器学习和神经网络预测方法
在这个笔记本中,您将使用交叉验证为 M5 数据集中的每个时间序列选择最佳模型并进行预测。
统计学、机器学习和神经网络预测方法 在本教程中,我们将探讨如何通过为 M5 数据集中的每个时间序列利用最合适的模型来进行预测。我们将通过一项重要的技术——交叉验证来完成此任务。这种方法有助于我们评估模型的预测性能,并选择在每个时间序列上产生最佳性能的模型。
M5 数据集包含沃尔玛为期五年的分层销售数据。目标是预测未来 28 天的每日销售额。该数据集细分为美国的 50 个州,每个州有 10 家商店。
在时间序列预测和分析领域,一个更复杂的任务是确定最适合特定序列组的模型。通常,这个选择过程很大程度上依赖于直觉,而这可能并不一定与我们数据集的实际情况相符。
在本教程中,我们的目标是为 M5 基准数据集中的不同序列组提供一种更结构化、数据驱动的模型选择方法。该数据集在预测领域广为人知,它使我们能够展示我们方法的通用性和强大之处。
我们将训练来自各种预测范式的多种模型
- 基准模型:这些模型虽然简单,但对于提供预测问题的初步视角通常非常有效。我们将使用
SeasonalNaive
和HistoricAverage
模型作为此类别。 - 间歇性模型:对于需求零星、非连续的序列,我们将使用
CrostonOptimized
、IMAPA
和ADIDA
等模型。这些模型特别适用于处理零膨胀序列。 - 状态空间模型:这些是使用系统数学描述进行预测的统计模型。来自 statsforecast 库的
AutoETS
模型属于此类。
机器学习:利用像 LightGBM
、XGBoost
和 LinearRegression
这样的机器学习模型具有优势,因为它们能够发现数据中的复杂模式。我们将为此使用 MLForecast 库。
深度学习:像 Transformer (AutoTFT
) 和神经网络 (AutoNHITS
) 这样的深度学习模型使我们能够处理时间序列数据中复杂的非线性依赖关系。我们将使用 NeuralForecast 库来处理这些模型。
使用 Nixtla 库套件,我们将能够用数据驱动我们的模型选择过程,确保我们为数据集中的特定序列组利用最合适的模型。
大纲
-
读取数据:在第一步,我们将数据集加载到内存中,以便进行后续的分析和预测。在此阶段,了解数据集的结构和细微之处非常重要。
-
使用统计学和深度学习方法进行预测:我们应用了从基本统计技术到高级深度学习模型的各种预测方法。目标是根据我们的数据集生成未来 28 天的预测。
-
在不同窗口上评估模型性能:我们在不同的窗口上评估模型的性能。
-
为序列组选择最佳模型:利用性能评估,我们确定每个序列组的最佳模型。此步骤确保所选模型适合每个组的独特特征。
-
过滤最佳预测:最后,我们过滤由我们选择的模型生成的预测,以获得最有前景的预测。这是我们的最终输出,代表了根据我们的模型对每个序列的最佳预测。
警告
本教程最初是使用
c5d.24xlarge
EC2 实例执行的。
安装库
下载和准备数据
此示例使用 M5 数据集。它包含 30,490
个底部时间序列。
为简单起见,我们只保留一个类别
基本绘图
使用来自 utilsforecast
库的 plot_series
函数绘制一些序列。此方法会打印数据集中的 8 个随机序列,对于基本探索性数据分析 (EDA) 非常有用。
使用 Stats、ML 和 Neural 方法创建预测。
StatsForecast
StatsForecast
是一个综合性库,提供一套流行的单变量时间序列预测模型,所有模型都专注于高性能和可伸缩性。
以下是使 StatsForecast 成为时间序列预测强大工具的原因
-
局部模型集合:StatsForecast 提供了各种局部模型,这些模型可以单独应用于每个时间序列,使我们能够捕获每个序列中的独特模式。
-
简单性:使用 StatsForecast,训练、预测和回测多个模型变得直截了当,只需几行代码即可完成。这种简单性使其成为初学者和有经验的从业者都方便使用的工具。
-
速度优化:StatsForecast 中模型的实现针对速度进行了优化,确保大规模计算高效执行,从而减少模型训练和预测的总时间。
-
水平可伸缩性:StatsForecast 的显着特点之一是其水平扩展能力。它与 Spark、Dask 和 Ray 等分布式计算框架兼容。此功能使其能够通过在集群中的多个节点上分配计算来高效处理大型数据集,使其成为大型时间序列预测任务的首选解决方案。
StatsForecast
接收一个模型列表以拟合每个时间序列。由于我们处理的是每日数据,将季节性设置为 7 会很有益。
我们通过实例化一个新的 StatsForecast 对象并使用以下参数来拟合模型
models
:模型列表。从模型中选择您想要的模型并导入它们。freq
:一个字符串,指示数据的频率。(请参阅 panda 的可用频率。)n_jobs
:int,并行处理中使用的作业数,使用 -1 表示所有核心。fallback_model
:如果模型失败时使用的模型。任何设置都会传递到构造函数中。然后调用其 fit 方法并传入历史数据框。
预测方法会为接下来的 h
个周期生成预测。
此处的预测对象是一个新的数据框,其中包含一列,其中包含模型名称和 y hat 值。
此代码块测量 StatsForecast 类的预测函数运行所需的时间,该函数预测未来 28 天(h=28)。时间以分钟为单位计算并在最后打印出来。
unique_id | ds | SeasonalNaive | Naive | HistoricAverage | CrostonOptimized | ADIDA | IMAPA | AutoETS | |
---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-05-23 | 1.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.381414 |
1 | FOODS_3_001_CA_1 | 2016-05-24 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.286933 |
2 | FOODS_3_001_CA_1 | 2016-05-25 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.334987 |
3 | FOODS_3_001_CA_1 | 2016-05-26 | 1.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.186851 |
4 | FOODS_3_001_CA_1 | 2016-05-27 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.308112 |
MLForecast
MLForecast
是一个强大的库,为时间序列预测提供自动特征创建,便于使用全局机器学习模型。它旨在实现高性能和可伸缩性。
MLForecast 的主要功能包括
-
支持 sklearn 模型:MLForecast 与遵循 scikit-learn API 的模型兼容。这使得它高度灵活,并允许其与各种机器学习算法无缝集成。
-
简单性:使用 MLForecast,训练、预测和回测模型只需几行代码即可完成。这种简化的简单性使其对各个专业水平的从业者都很友好。
-
速度优化:MLForecast 旨在快速执行任务,这在处理大型数据集和复杂模型时至关重要。
-
水平可伸缩性:MLForecast 能够使用 Spark、Dask 和 Ray 等分布式计算框架进行水平扩展。此功能使其能够通过在集群中的多个节点上分配计算来高效处理大型数据集,使其成为大型时间序列预测任务的理想选择。
要将 MLForecast
用于时间序列预测,我们实例化一个新的 MLForecast
对象,并为其提供各种参数以根据我们的特定需求调整建模过程
-
models
:此参数接受您希望用于预测的机器学习模型列表。您可以从 scikit-learn、lightgbm 和 xgboost 中导入您喜欢的模型。 -
freq
:这是一个字符串,指示数据的频率(每小时、每日、每周等)。此字符串的具体格式应与 pandas 识别的频率字符串对齐。 -
target_transforms
:这些是在模型训练之前和模型预测之后应用于目标变量的转换。这在处理可能受益于转换(例如对高度偏斜数据进行对数转换)的数据时非常有用。 -
lags
:此参数接受要用作回归变量的特定滞后值。滞后表示在为模型创建特征时,您希望回溯多长时间。例如,如果您希望使用前一天的数据作为预测当天值的特征,您将指定滞后为 1。 -
lags_transforms
:这些是每个滞后的特定转换。这允许您对滞后特征应用转换。 -
date_features
:此参数指定要用作回归变量的日期相关特征。例如,您可能希望将星期几或月份包含在模型中作为特征。 -
num_threads
:此参数控制用于并行化特征创建的线程数,有助于在处理大型数据集时加快此过程。
所有这些设置都传递给 MLForecast
构造函数。一旦使用这些设置初始化 MLForecast
对象,我们就会调用其 fit
方法并传递历史数据框作为参数。fit
方法在提供的历史数据上训练模型,为未来的预测任务做好准备。
只需调用 fit
模型即可训练所选模型。在这种情况下,我们正在生成一致性预测区间。
之后,只需调用 predict
即可生成预测。
unique_id | ds | LGBMRegressor | XGBRegressor | LinearRegression | |
---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-05-23 | 0.549520 | 0.560123 | 0.332693 |
1 | FOODS_3_001_CA_1 | 2016-05-24 | 0.553196 | 0.369337 | 0.055071 |
2 | FOODS_3_001_CA_1 | 2016-05-25 | 0.599668 | 0.374338 | 0.127144 |
3 | FOODS_3_001_CA_1 | 2016-05-26 | 0.638097 | 0.327176 | 0.101624 |
4 | FOODS_3_001_CA_1 | 2016-05-27 | 0.763305 | 0.331631 | 0.269863 |
NeuralForecast
NeuralForecast
是一个强大的神经网络预测模型集合,专注于可用性和性能。它包含各种模型架构,从多层感知机 (MLP) 和循环神经网络 (RNN) 等经典网络到 N-BEATS、N-HITS、时间融合 Transformer (TFT) 等新颖贡献,等等。
>NeuralForecast
的主要功能包括
- 广泛的全局模型集合。开箱即用的 MLP、LSTM、RNN、TCN、DilatedRNN、NBEATS、NHITS、ESRNN、TFT、Informer、PatchTST 和 HINT 实现。
- 简单直观的界面,只需几行代码即可训练、预测和回测各种模型。
- 支持 GPU 加速,提高计算速度。
这台机器没有 GPU,但 Google Colabs 提供免费的 GPU。
使用 Colab 的 GPU 训练 NeuralForecast。
unique_id | ds | AutoNHITS | AutoNHITS-lo-90 | AutoNHITS-hi-90 | AutoTFT | AutoTFT-lo-90 | AutoTFT-hi-90 | |
---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-05-23 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 |
1 | FOODS_3_001_CA_1 | 2016-05-24 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 |
2 | FOODS_3_001_CA_1 | 2016-05-25 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 1.0 |
3 | FOODS_3_001_CA_1 | 2016-05-26 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 |
4 | FOODS_3_001_CA_1 | 2016-05-27 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 |
unique_id | ds | SeasonalNaive | Naive | HistoricAverage | CrostonOptimized | ADIDA | IMAPA | AutoETS | AutoNHITS | AutoNHITS-lo-90 | AutoNHITS-hi-90 | AutoTFT | AutoTFT-lo-90 | AutoTFT-hi-90 | LGBMRegressor | XGBRegressor | LinearRegression | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-05-23 | 1.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.381414 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 | 0.549520 | 0.560123 | 0.332693 |
1 | FOODS_3_001_CA_1 | 2016-05-24 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.286933 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 | 0.553196 | 0.369337 | 0.055071 |
2 | FOODS_3_001_CA_1 | 2016-05-25 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.334987 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 1.0 | 0.599668 | 0.374338 | 0.127144 |
3 | FOODS_3_001_CA_1 | 2016-05-26 | 1.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.186851 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 | 0.638097 | 0.327176 | 0.101624 |
4 | FOODS_3_001_CA_1 | 2016-05-27 | 0.0 | 2.0 | 0.448738 | 0.345192 | 0.345477 | 0.347249 | 0.308112 | 0.0 | 0.0 | 2.0 | 0.0 | 0.0 | 2.0 | 0.763305 | 0.331631 | 0.269863 |
预测图
使用 plot 函数探索模型和 ID
验证模型性能
这三个库 - StatsForecast
、MLForecast
和 NeuralForecast
- 提供专门为时间序列设计的开箱即用交叉验证功能。这使我们能够使用历史数据评估模型性能,以获得对每个模型在新数据上可能表现如何的无偏评估。
StatsForecast 中的交叉验证
StatsForecast
类中的 cross_validation
方法接受以下参数
df
:表示训练数据的 DataFrame。h
(int):预测范围,表示我们希望预测未来的步数。例如,如果我们预测每小时数据,h=24
将表示 24 小时的预测。step_size
(int):每个交叉验证窗口之间的步长。此参数确定我们希望运行预测过程的频率。n_windows
(int):用于交叉验证的窗口数。此参数定义了我们希望评估多少个过去的预测过程。
这些参数使我们能够控制交叉验证过程的范围和粒度。通过调整这些设置,我们可以在计算成本和交叉验证的彻底性之间取得平衡。
crossvaldation_df 对象是一个新的数据框,其中包含以下列
unique_id
序列标识符ds
:日期戳或时间索引cutoff
:n_windows 的最后一个日期戳或时间索引。如果 n_windows=1,则有一个唯一的截止值;如果 n_windows=2,则有两个唯一的截止值。y
:真实值"model"
:包含模型名称和拟合值的列。
unique_id | ds | cutoff | y | SeasonalNaive | Naive | HistoricAverage | CrostonOptimized | ADIDA | IMAPA | AutoETS | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-02-29 | 2016-02-28 | 0.0 | 2.0 | 0.0 | 0.449111 | 0.618472 | 0.618375 | 0.617998 | 0.655286 |
1 | FOODS_3_001_CA_1 | 2016-03-01 | 2016-02-28 | 1.0 | 0.0 | 0.0 | 0.449111 | 0.618472 | 0.618375 | 0.617998 | 0.568595 |
2 | FOODS_3_001_CA_1 | 2016-03-02 | 2016-02-28 | 1.0 | 0.0 | 0.0 | 0.449111 | 0.618472 | 0.618375 | 0.617998 | 0.618805 |
3 | FOODS_3_001_CA_1 | 2016-03-03 | 2016-02-28 | 0.0 | 1.0 | 0.0 | 0.449111 | 0.618472 | 0.618375 | 0.617998 | 0.455891 |
4 | FOODS_3_001_CA_1 | 2016-03-04 | 2016-02-28 | 0.0 | 1.0 | 0.0 | 0.449111 | 0.618472 | 0.618375 | 0.617998 | 0.591197 |
MLForecast
MLForecast
类中的 cross_validation
方法接受以下参数。
df
:训练数据框h
(int):表示预测未来的步数。在此示例中,提前 24 小时。step_size
(int):每个窗口之间的步长。换句话说:您希望运行预测过程的频率。n_windows
(int):用于交叉验证的窗口数。换句话说:您希望评估过去多少个预测过程。
crossvaldation_df 对象是一个新的数据框,其中包含以下列
unique_id
序列标识符ds
:日期戳或时间索引cutoff
:n_windows 的最后一个日期戳或时间索引。如果 n_windows=1,则有一个唯一的截止值;如果 n_windows=2,则有两个唯一的截止值。y
:真实值"model"
:包含模型名称和拟合值的列。
unique_id | ds | cutoff | y | LGBMRegressor | XGBRegressor | LinearRegression | |
---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-02-29 | 2016-02-28 | 0.0 | 0.435674 | 0.556261 | -0.353077 |
1 | FOODS_3_001_CA_1 | 2016-03-01 | 2016-02-28 | 1.0 | 0.639676 | 0.625807 | -0.088985 |
2 | FOODS_3_001_CA_1 | 2016-03-02 | 2016-02-28 | 1.0 | 0.792989 | 0.659651 | 0.217697 |
3 | FOODS_3_001_CA_1 | 2016-03-03 | 2016-02-28 | 0.0 | 0.806868 | 0.535121 | 0.438713 |
4 | FOODS_3_001_CA_1 | 2016-03-04 | 2016-02-28 | 0.0 | 0.829106 | 0.313354 | 0.637066 |
NeuralForecast
这台机器没有 GPU,但 Google Colabs 提供免费的 GPU。
使用 Colab 的 GPU 训练 NeuralForecast。
unique_id | ds | cutoff | AutoNHITS | AutoNHITS-lo-90 | AutoNHITS-hi-90 | AutoTFT | AutoTFT-lo-90 | AutoTFT-hi-90 | y | |
---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | 2016-02-29 | 2016-02-28 | 0.0 | 0.0 | 2.0 | 1.0 | 0.0 | 2.0 | 0.0 |
1 | FOODS_3_001_CA_1 | 2016-03-01 | 2016-02-28 | 0.0 | 0.0 | 2.0 | 1.0 | 0.0 | 2.0 | 1.0 |
2 | FOODS_3_001_CA_1 | 2016-03-02 | 2016-02-28 | 0.0 | 0.0 | 2.0 | 1.0 | 0.0 | 2.0 | 1.0 |
3 | FOODS_3_001_CA_1 | 2016-03-03 | 2016-02-28 | 0.0 | 0.0 | 2.0 | 1.0 | 0.0 | 2.0 | 0.0 |
4 | FOODS_3_001_CA_1 | 2016-03-04 | 2016-02-28 | 0.0 | 0.0 | 2.0 | 1.0 | 0.0 | 2.0 | 0.0 |
合并交叉验证预测
绘制交叉验证结果
总需求
每个序列和交叉验证窗口的评估
在本节中,我们将评估每个模型在每个时间序列上的性能。
unique_id | 指标 | SeasonalNaive | Naive | HistoricAverage | CrostonOptimized | ADIDA | IMAPA | AutoETS | AutoNHITS | AutoTFT | LGBMRegressor | XGBRegressor | LinearRegression | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | FOODS_3_001_CA_1 | mse | 1.250000 | 0.892857 | 0.485182 | 0.507957 | 0.509299 | 0.516988 | 0.494235 | 0.630952 | 0.571429 | 0.648962 | 0.584722 | 0.529400 |
1 | FOODS_3_001_CA_2 | mse | 6.273809 | 3.773809 | 3.477309 | 3.412580 | 3.432295 | 3.474050 | 3.426468 | 4.550595 | 3.607143 | 3.423646 | 3.856465 | 3.773264 |
2 | FOODS_3_001_CA_3 | mse | 5.880952 | 4.357143 | 5.016396 | 4.173154 | 4.160645 | 4.176733 | 4.145148 | 4.005952 | 4.372024 | 4.928764 | 6.937792 | 5.317195 |
3 | FOODS_3_001_CA_4 | mse | 1.071429 | 0.476190 | 0.402938 | 0.382559 | 0.380783 | 0.380877 | 0.380872 | 0.476190 | 0.476190 | 0.664270 | 0.424068 | 0.637221 |
4 | FOODS_3_001_TX_1 | mse | 0.047619 | 0.047619 | 0.238824 | 0.261356 | 0.047619 | 0.047619 | 0.077575 | 0.047619 | 0.047619 | 0.718796 | 0.063564 | 0.187810 |
… | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
24685 | FOODS_3_827_TX_2 | smape | 0.083333 | 0.035714 | 0.989540 | 0.996362 | 0.987395 | 0.982847 | 0.981537 | 0.323810 | 0.335714 | 0.976356 | 0.994702 | 0.985058 |
24686 | FOODS_3_827_TX_3 | smape | 0.708532 | 0.681495 | 0.662490 | 0.653057 | 0.655810 | 0.660161 | 0.649180 | 0.683947 | 0.712121 | 0.639518 | 0.856866 | 0.686547 |
24687 | FOODS_3_827_WI_1 | smape | 0.608722 | 0.694328 | 0.470570 | 0.470846 | 0.480032 | 0.480032 | 0.466956 | 0.486852 | 0.475980 | 0.472336 | 0.484906 | 0.492277 |
24688 | FOODS_3_827_WI_2 | smape | 0.531777 | 0.398156 | 0.433577 | 0.387718 | 0.388827 | 0.389371 | 0.389888 | 0.393774 | 0.374640 | 0.413559 | 0.430893 | 0.399131 |
24689 | FOODS_3_827_WI_3 | smape | 0.643689 | 0.680178 | 0.588031 | 0.589143 | 0.599820 | 0.628673 | 0.591437 | 0.558201 | 0.567460 | 0.589870 | 0.698798 | 0.627255 |
SeasonalNaive | Naive | HistoricAverage | CrostonOptimized | ADIDA | IMAPA | AutoETS | AutoNHITS | AutoTFT | LGBMRegressor | XGBRegressor | LinearRegression | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
指标 | ||||||||||||
mae | 1.775415 | 2.045906 | 1.749080 | 1.634791 | 1.542097 | 1.543745 | 1.511545 | 1.438250 | 1.497647 | 1.697947 | 1.552061 | 1.592978 |
mse | 14.265773 | 20.453325 | 12.938136 | 11.484233 | 11.090195 | 11.094446 | 10.351927 | 9.606913 | 10.721251 | 10.502289 | 11.565916 | 10.830894 |
smape | 0.436414 | 0.446430 | 0.616884 | 0.613219 | 0.618910 | 0.619313 | 0.620084 | 0.400770 | 0.411018 | 0.579856 | 0.693615 | 0.641515 |
按指标划分的最佳模型
误差分布
SMAPE
为序列组选择模型
特征
- 包含所有不同模型预测的统一数据框
- 简单集成
- 例如,平均预测
- 或 MinMax(选择即是集成)