pip install statsforecast
交叉验证
在这个例子中,我们将实现时间序列交叉验证来评估模型的性能。
本教程假设您对StatsForecast有基本的了解。要查看一个最简单的例子,请访问快速入门
介绍
时间序列交叉验证是一种评估模型在过去表现的方法。它通过在历史数据上定义一个滑动窗口,并预测其后的时间段来实现。
Statsforecast 提供了一种快速且易于使用的时间序列交叉验证实现。这个实现将交叉验证转变为分布式操作,从而减少了时间消耗。在这个笔记本中,我们将其应用于 M4 Competition 每小时数据集的一个子集。
大纲:
- 安装库
- 加载和探索数据
- 训练模型
- 执行时间序列交叉验证
- 评估结果
安装库
我们假设您已经安装了StatsForecast。如果没有,请查看本指南了解如何安装StatsForecast。
使用 pip install statsforecast
安装所需的包。
from statsforecast import StatsForecast # 需要实例化StastForecast对象并使用交叉验证方法
加载和探索数据
正如在介绍中所述,我们将使用M4竞赛的小时数据集。我们将首先使用pandas
从一个URL导入数据。
import pandas as pd
= pd.read_parquet('https://datasets-nixtla.s3.amazonaws.com/m4-hourly.parquet') # 加载数据
Y_df Y_df.head()
unique_id | ds | y | |
---|---|---|---|
0 | H1 | 1 | 605.0 |
1 | H1 | 2 | 586.0 |
2 | H1 | 3 | 586.0 |
3 | H1 | 4 | 559.0 |
4 | H1 | 5 | 511.0 |
StatsForecast
的输入是一个 长格式 的数据框,包含三列:unique_id
、ds
和 y
:
unique_id
(字符串、整数或类别)表示序列的标识符。ds
(日期戳或整数)列应为整数索引时间或格式为 YYYY-MM-DD 或 YYYY-MM-DD HH:MM:SS 的日期戳。y
(数值型)表示我们希望预测的测量值。
该示例中的数据已经具备这种格式,因此不需要进行更改。
为了将执行此笔记本所需的时间保持在最小,我们将仅使用数据中的一个时间序列,即 unique_id == 'H1'
的那个。然而,您可以使用任意多个时间序列,不需要对代码进行其他更改。
= Y_df[Y_df['unique_id'] == 'H1'] # 选择时间序列 df
我们可以使用 StatsForecast.plot
方法绘制我们将要使用的时间序列。
StatsForecast.plot(df)
训练模型
在这个例子中,我们将使用 StastForecast AutoETS。首先,我们需要从 statsforecast.models
导入它,然后我们需要实例化一个新的 StatsForecast
对象。
StatsForecast
对象具有以下参数:
- models: 模型列表。从 模型 中选择您想要的模型并导入。
- freq: 一个字符串,指示数据的频率。请参见 pandas 可用的频率。
- n_jobs: n_jobs: int,进行并行处理时使用的作业数量,使用 -1 表示使用所有核心。
任何设置都将传递给构造函数。然后您调用其 fit 方法并传入历史数据框 df
。
from statsforecast.models import AutoETS
= [AutoETS(season_length = 24)]
models
= StatsForecast(
sf = df,
df = models,
models = 'H',
freq = -1
n_jobs )
执行时间序列交叉验证
一旦实例化了StatsForecast
对象,我们可以使用cross_validation
方法,该方法接受以下参数:
df
:采用StatsForecast
格式的训练数据框h
(整数):表示将要预测的未来h个步骤step_size
(整数):每个窗口之间的步长,意味着您希望多频繁地运行预测过程。n_windows
(整数):用于交叉验证的窗口数量,意味着您希望评估过去的预测过程的数量。
对于这个特定的例子,我们将使用3个24小时的窗口。
= sf.cross_validation(
crossvalidation_df = df,
df = 24,
h = 24,
step_size = 3
n_windows )
crossvaldation_df对象是一个新的数据框,包含以下列:
unique_id
: 索引。如果您不喜欢使用索引,可以运行crossvalidation_df.resetindex()
ds
: 日期戳或时间索引cutoff
: n_windows的最后一个日期戳或时间索引。y
: 真实值"model"
: 包含模型名称和拟合值的列。
crossvalidation_df.head()
ds | cutoff | y | AutoETS | |
---|---|---|---|---|
unique_id | ||||
H1 | 677 | 676 | 691.0 | 677.761047 |
H1 | 678 | 676 | 618.0 | 607.817871 |
H1 | 679 | 676 | 563.0 | 569.437744 |
H1 | 680 | 676 | 529.0 | 537.340027 |
H1 | 681 | 676 | 504.0 | 515.571106 |
我们现在将绘制每个截止期的预测。为了使图形更清晰,我们将重新命名每个时期的实际值。
= {'y' : 'actual'}, inplace = True) # 重命名实际值
crossvalidation_df.rename(columns
= crossvalidation_df['cutoff'].unique()
cutoff
for k in range(len(cutoff)):
= crossvalidation_df[crossvalidation_df['cutoff'] == cutoff[k]]
cv != 'cutoff']) StatsForecast.plot(df, cv.loc[:, cv.columns
请注意,在每个截止期,我们仅使用该期间之前的数据 y
来生成未来 24 小时的预测。
评估结果
我们现在可以使用适当的准确性指标计算预测的准确性。在这里,我们将使用均方根误差 (RMSE)。 为此,我们首先需要安装.datasetsforecast,这是Nixtla开发的一个Python库,其中包含计算RMSE的函数。
pip install datasetsforecast
from datasetsforecast.losses import rmse
计算RMSE的函数需要两个参数:
- 实际值。
- 预测值,在本例中为
AutoETS
。
= rmse(crossvalidation_df['actual'], crossvalidation_df['AutoETS'])
rmse print("RMSE using cross-validation: ", rmse)
RMSE using cross-validation: 33.90342
这个测量应该更好地反映我们模型的预测能力,因为它使用不同的时间段来测试其准确性。
交叉验证在比较多个模型时特别有用。这里有一个示例,展示了多个模型和时间序列的应用。
参考文献
Rob J. Hyndman 和 George Athanasopoulos (2018). “预测原则与实践,时间序列交叉验证”。
Give us a ⭐ on Github