-U pip install statsforecast
间歇性或稀疏数据
在这个笔记本中,我们将为间歇性或稀疏数据实现模型。
间歇性或稀疏数据的非零观察值非常少。这类数据很难进行预测,因为零值增加了对数据中潜在模式的的不确定性。此外,一旦出现非零观察值,其规模会有相当大的变化。间歇性时间序列在许多行业中很常见,包括金融、零售、运输和能源。鉴于这种系列的普遍性,已经开发了特殊的方法来进行预测。第一个方法来自于 Croston (1972),随后出现了几种变体和不同的聚合框架。
StatsForecast 实现了几种模型来预测间歇性时间序列。在本教程结束时,您将对这些模型及其使用方法有一个良好的理解。
大纲:
- 安装库
- 加载并探索数据
- 训练间歇性数据模型
- 绘制预测并计算准确性
对于大规模预测,我们建议你查看这个笔记本在Databricks上完成的。
安装库
我们假设您已经安装了StatsForecast。如果没有,请查看本指南了解如何安装StatsForecast的说明。
使用 pip install statsforecast
安装必要的包。
加载和探索数据
在这个例子中,我们将使用M5 Competition数据集的一个子集。每个时间序列代表某个产品在特定Walmart商店的单位销售量。在这个层面上(产品-商店),大部分数据都是间歇性的。 我们首先需要导入数据,为此,我们需要datasetsforecast。
-U pip install datasetsforecast
from datasetsforecast.m5 import M5
加载数据的函数是 M5.load()
。它需要以下参数: - directory
: (str) 数据将被下载的目录。
该函数返回多个输出,但只需要第一个包含单位销售的数据。
*_ = M5.load('./data') df_total,
df_total.head()
unique_id | ds | y | |
---|---|---|---|
0 | FOODS_1_001_CA_1 | 2011-01-29 | 3.0 |
1 | FOODS_1_001_CA_1 | 2011-01-30 | 0.0 |
2 | FOODS_1_001_CA_1 | 2011-01-31 | 0.0 |
3 | FOODS_1_001_CA_1 | 2011-02-01 | 1.0 |
4 | FOODS_1_001_CA_1 | 2011-02-02 | 4.0 |
从这个数据集中,我们将选择前8个时间序列。您可以通过更改n_series
的值来选择任何数量的序列。
= 8
n_series = df_total['unique_id'].unique()[:n_series]
uids = df_total.query('unique_id in @uids') df
我们可以使用 StatsForecast 类的 plot
方法来绘制这些序列。该方法有多个参数,生成此笔记本图形所需的参数如下所示。
df
:一个包含 [unique_id
,ds
,y
] 列的pandas
数据框。forecasts_df
:一个包含 [unique_id
,ds
] 和模型的pandas
数据框。plot_random
:(bool =True
)随机绘制时间序列。max_insample_length
:(int)要绘制的训练/样本观察的最大数量。engine
:(str =plotly
)。用于生成图形的库。它也可以是matplotlib
用于静态图。
from statsforecast import StatsForecast
= False, max_insample_length = 100) StatsForecast.plot(df, plot_random
在这里,我们只绘制了最后100个观测值,但通过移除max_insample_length
,我们可以可视化完整的历史数据。通过这些图表,我们可以确认数据确实是间歇性的,因为有多个周期的销售额为零。事实上,除了一个例外,在所有情况下,中位数值都是零。
'unique_id')[['y']].median().query('unique_id in @uids') df.groupby(
y | |
---|---|
unique_id | |
FOODS_1_001_CA_1 | 0.0 |
FOODS_1_001_CA_2 | 1.0 |
FOODS_1_001_CA_3 | 0.0 |
FOODS_1_001_CA_4 | 0.0 |
FOODS_1_001_TX_1 | 0.0 |
FOODS_1_001_TX_2 | 0.0 |
FOODS_1_001_TX_3 | 0.0 |
FOODS_1_001_WI_1 | 0.0 |
为间歇性数据训练模型
在训练任何模型之前,我们需要将数据分为训练集和测试集。M5 竞赛使用最后 28 天作为测试集,所以我们也将这样做。
= df['ds'].unique()[-28:] # 过去28天
dates
= df.query('ds not in @dates')
train = df.query('ds in @dates') test
StatsForecast 提供了多个间歇性数据模型的高效实现。可用模型的完整列表请参见 这里。在本笔记中,我们将使用:
要使用这些模型,我们首先需要从 statsforecast.models
导入它们,然后实例化它们。
from statsforecast.models import (
ADIDA,
CrostonClassic,
IMAPA,
TSB
)
# 创建一个模型及其实例化参数的列表
= [
models
ADIDA(),
CrostonClassic(),
IMAPA(), = 0.2, alpha_p = 0.2)
TSB(alpha_d ]
要实例化一个新的 StatsForecast 对象,我们需要以下参数:
df
:包含训练数据的数据框。models
:在前一步中定义的模型列表。freq
:一个字符串,指示数据的频率。请参见 pandas 可用的频率。n_jobs
:一个整数,指示并行处理使用的作业数量。使用 -1 选择所有核心。
= StatsForecast(
sf = train,
df = models,
models = 'D',
freq = -1
n_jobs )
现在我们准备生成预测。为此,我们将使用forecast
方法,该方法需要预测范围(在本例中为28天)作为参数。
目前在StatsForecast中可用的间歇性系列模型只能生成点预测。如果需要预测区间,则应使用概率模型。
= 28
horizon = sf.forecast(h=horizon)
forecasts = forecasts.reset_index()
forecasts forecasts.head()
unique_id | ds | ADIDA | CrostonClassic | IMAPA | TSB | |
---|---|---|---|---|---|---|
0 | FOODS_1_001_CA_1 | 2016-05-23 | 0.791852 | 0.898247 | 0.705835 | 0.434313 |
1 | FOODS_1_001_CA_1 | 2016-05-24 | 0.791852 | 0.898247 | 0.705835 | 0.434313 |
2 | FOODS_1_001_CA_1 | 2016-05-25 | 0.791852 | 0.898247 | 0.705835 | 0.434313 |
3 | FOODS_1_001_CA_1 | 2016-05-26 | 0.791852 | 0.898247 | 0.705835 | 0.434313 |
4 | FOODS_1_001_CA_1 | 2016-05-27 | 0.791852 | 0.898247 | 0.705835 | 0.434313 |
最后,我们将把预测值与实际值合并。
= test.merge(forecasts, how='left', on=['unique_id', 'ds']) test
绘制预测并计算准确性
我们可以使用上述描述的 plot
生成绘图。
= False, max_insample_length = 100) StatsForecast.plot(train, test, plot_random
要计算预测的准确性,我们将使用平均绝对误差(MAE),即绝对误差的总和除以预测的数量。我们将创建一个函数来计算MAE,为此,我们需要导入numpy
。
import numpy as np
def mae(y_hat, y_true):
return np.mean(np.abs(y_hat-y_true))
= test['y'].values
y_true = test['ADIDA'].values
adida_preds = test['CrostonClassic'].values
croston_preds = test['IMAPA'].values
imapa_preds = test['TSB'].values
tsb_preds
print('ADIDA MAE: \t %0.3f' % mae(adida_preds, y_true))
print('Croston Classic MAE: \t %0.3f' % mae(croston_preds, y_true))
print('IMAPA MAE: \t %0.3f' % mae(imapa_preds, y_true))
print('TSB MAE: \t %0.3f' % mae(tsb_preds, y_true))
ADIDA MAE: 0.949
Croston Classic MAE: 0.944
IMAPA MAE: 0.957
TSB MAE: 1.023
因此,平均而言,预测误差为一个单位。
参考文献
Croston, J. D. (1972). 间歇性需求的预测与库存控制. 运筹学研究学会杂志, 23(3), 289-303.
Give us a ⭐ on Github