地理和时间聚合(旅游)
在澳大利亚旅游数据上进行地理和时间分层预测
在许多应用中,一组时间序列被组织成层级结构。例子包括地理层级、产品或类别,它们定义了不同类型的聚合。在这种情况下,预测者通常需要为所有分解和聚合的序列提供预测。一个自然的期望是这些预测是“一致的”,也就是说,底层序列的预测值精确地加总等于聚合序列的预测值。
在本笔记本中,我们展示一个如何使用 HierarchicalForecast
来生成地理层级和时间层级之间一致预测的示例。我们将使用经典的澳大利亚国内旅游 (Tourism
) 数据集,它包含澳大利亚每个州的月度游客数量时间序列。
我们将首先加载 Tourism
数据,并使用 StatsForecast
中的 AutoETS
模型生成基础预测。然后,我们根据跨部门地理层级,使用 HierarchicalForecast
中的几种协调算法来协调这些预测。最后,我们根据时间层级在时间维度上协调预测。
您可以使用 CPU 或 GPU 在 Google Colab 上运行这些实验。
1. 加载和处理数据
在本例中,我们将使用《预测:原理与实践》书中的 Tourism 数据集。
数据集仅包含最低层级的时间序列,因此我们需要为所有层级创建时间序列。
国家 | 区域 | 州 | 目的 | ds | y | |
---|---|---|---|---|---|---|
0 | 澳大利亚 | 阿德莱德 | 南澳大利亚 | 商务 | 1998-01-01 | 135.077690 |
1 | 澳大利亚 | 阿德莱德 | 南澳大利亚 | 商务 | 1998-04-01 | 109.987316 |
2 | 澳大利亚 | 阿德莱德 | 南澳大利亚 | 商务 | 1998-07-01 | 166.034687 |
3 | 澳大利亚 | 阿德莱德 | 南澳大利亚 | 商务 | 1998-10-01 | 127.160464 |
4 | 澳大利亚 | 阿德莱德 | 南澳大利亚 | 商务 | 1999-01-01 | 137.448533 |
2. 跨部门协调
2a. 根据跨部门层级聚合数据集
数据集可以按以下非严格的层级结构进行分组。
使用 HierarchicalForecast
中的 aggregate
函数,我们可以获得完整的时间序列集。
unique_id | ds | y | |
---|---|---|---|
0 | 澳大利亚 | 1998-01-01 | 23182.197269 |
1 | 澳大利亚 | 1998-04-01 | 20323.380067 |
2 | 澳大利亚 | 1998-07-01 | 19826.640511 |
3 | 澳大利亚 | 1998-10-01 | 20830.129891 |
4 | 澳大利亚 | 1999-01-01 | 22087.353380 |
... | ... | ... | ... |
33995 | 澳大利亚/西澳大利亚/珀斯体验/V... | 2016-10-01 | 439.699451 |
33996 | 澳大利亚/西澳大利亚/珀斯体验/V... | 2017-01-01 | 356.867038 |
33997 | 澳大利亚/西澳大利亚/珀斯体验/V... | 2017-04-01 | 302.296119 |
33998 | 澳大利亚/西澳大利亚/珀斯体验/V... | 2017-07-01 | 373.442070 |
33999 | 澳大利亚/西澳大利亚/珀斯体验/V... | 2017-10-01 | 455.316702 |
unique_id | 澳大利亚/ACT/堪培拉/商务 | 澳大利亚/ACT/堪培拉/度假 | 澳大利亚/ACT/堪培拉/其他 | 澳大利亚/ACT/堪培拉/探亲访友 | |
---|---|---|---|---|---|
0 | 澳大利亚 | 1.0 | 1.0 | 1.0 | 1.0 |
1 | 澳大利亚/ACT | 1.0 | 1.0 | 1.0 | 1.0 |
2 | 澳大利亚/新南威尔士 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | 澳大利亚/北领地 | 0.0 | 0.0 | 0.0 | 0.0 |
4 | 澳大利亚/昆士兰 | 0.0 | 0.0 | 0.0 | 0.0 |
2b. 拆分训练/测试集
我们使用最后两年(8个季度)作为测试集。因此,我们的预测 horizon=8。
2c. 计算基础预测
以下单元格使用 AutoETS
模型为 Y_df
中的每个时间序列计算基础预测。请注意,Y_hat_df
包含预测值,但它们并不一致。
2d. 协调预测
以下单元格使用 HierarchicalReconciliation
类使先前的预测保持一致。由于层级结构不是严格的,我们无法使用 TopDown
或 MiddleOut
等方法。在本例中,我们使用 BottomUp
和 MinTrace
。
数据框 Y_rec_df
包含协调后的预测值。
unique_id | ds | AutoETS | AutoETS/BottomUp | AutoETS/MinTrace_method-mint_shrink | AutoETS/MinTrace_method-ols | |
---|---|---|---|---|---|---|
0 | 澳大利亚 | 2016-01-01 | 25990.068004 | 24381.911737 | 25428.089783 | 25894.399067 |
1 | 澳大利亚 | 2016-04-01 | 24458.490282 | 22903.895964 | 23914.271400 | 24357.301898 |
2 | 澳大利亚 | 2016-07-01 | 23974.055984 | 22412.265739 | 23428.462394 | 23865.910647 |
3 | 澳大利亚 | 2016-10-01 | 24563.454495 | 23127.349578 | 24089.845955 | 24470.782393 |
4 | 澳大利亚 | 2017-01-01 | 25990.068004 | 24518.118006 | 25545.358678 | 25901.362283 |
3. 时间协调
接下来,我们旨在在时间域上也协调我们的预测。
3a. 根据时间层级聚合数据集
我们首先定义时间聚合规范。规范是一个字典,其中键是聚合的名称,值是该聚合中应聚合的底层时间步长的数量。例如,year
包含 12
个月,因此我们定义一个键值对 "yearly":12
。我们可以对我们感兴趣的其他聚合进行类似操作。
在此示例中,我们选择 year
、semiannual
和 quarter
的时间聚合。底层时间步长是季度频率的。
接下来,我们使用 aggregate_temporal
函数计算时间聚合的训练集和测试集。请注意,由于测试集包含训练集中未包含的时间层级,因此训练集和测试集的聚合矩阵 S
不同。
temporal_id | quarter-1 | quarter-2 | quarter-3 | quarter-4 | |
---|---|---|---|---|---|
0 | year-1 | 1.0 | 1.0 | 1.0 | 1.0 |
1 | year-2 | 0.0 | 0.0 | 0.0 | 0.0 |
2 | year-3 | 0.0 | 0.0 | 0.0 | 0.0 |
3 | year-4 | 0.0 | 0.0 | 0.0 | 0.0 |
4 | year-5 | 0.0 | 0.0 | 0.0 | 0.0 |
temporal_id | quarter-1 | quarter-2 | quarter-3 | quarter-4 | |
---|---|---|---|---|---|
0 | year-1 | 1.0 | 1.0 | 1.0 | 1.0 |
1 | year-2 | 0.0 | 0.0 | 0.0 | 0.0 |
2 | semiannual-1 | 1.0 | 1.0 | 0.0 | 0.0 |
3 | semiannual-2 | 0.0 | 0.0 | 1.0 | 1.0 |
4 | semiannual-3 | 0.0 | 0.0 | 0.0 | 0.0 |
如果您没有可用的测试集,通常是进行预测时的情况,则需要创建一个未来数据框,其中包含正确的底层 unique_ids 和时间戳,以便可以进行时间聚合。我们可以使用 make_future_dataframe
辅助函数来完成此操作。
Y_test_df_te_new
然后可以在 aggregate_temporal
中使用,以构建时间聚合结构。
我们可以验证我们是否拥有相同的时间聚合测试集,只是 Y_test_df_te_new
不包含真实值 y
。
temporal_id | unique_id | ds | y | |
---|---|---|---|---|
0 | year-1 | 澳大利亚 | 2016-10-01 | 101484.586551 |
1 | year-2 | 澳大利亚 | 2017-10-01 | 107709.864650 |
2 | year-1 | 澳大利亚/ACT | 2016-10-01 | 2457.401367 |
3 | year-2 | 澳大利亚/ACT | 2017-10-01 | 2734.748452 |
4 | year-1 | 澳大利亚/ACT/商务 | 2016-10-01 | 754.139245 |
... | ... | ... | ... | ... |
5945 | quarter-4 | 澳大利亚/西澳大利亚/探亲访友 | 2016-10-01 | 787.030391 |
5946 | quarter-5 | 澳大利亚/西澳大利亚/探亲访友 | 2017-01-01 | 702.777251 |
5947 | quarter-6 | 澳大利亚/西澳大利亚/探亲访友 | 2017-04-01 | 642.516090 |
5948 | quarter-7 | 澳大利亚/西澳大利亚/探亲访友 | 2017-07-01 | 646.521395 |
5949 | quarter-8 | 澳大利亚/西澳大利亚/探亲访友 | 2017-10-01 | 813.184778 |
temporal_id | unique_id | ds | |
---|---|---|---|
0 | year-1 | 澳大利亚 | 2016-10-01 |
1 | year-2 | 澳大利亚 | 2017-10-01 |
2 | year-1 | 澳大利亚/ACT | 2016-10-01 |
3 | year-2 | 澳大利亚/ACT | 2017-10-01 |
4 | year-1 | 澳大利亚/ACT/商务 | 2016-10-01 |
... | ... | ... | ... |
5945 | quarter-4 | 澳大利亚/西澳大利亚/探亲访友 | 2016-10-01 |
5946 | quarter-5 | 澳大利亚/西澳大利亚/探亲访友 | 2017-01-01 |
5947 | quarter-6 | 澳大利亚/西澳大利亚/探亲访友 | 2017-04-01 |
5948 | quarter-7 | 澳大利亚/西澳大利亚/探亲访友 | 2017-07-01 |
5949 | quarter-8 | 澳大利亚/西澳大利亚/探亲访友 | 2017-10-01 |
3b. 计算基础预测
现在,我们需要为每个时间聚合计算基础预测。以下单元格使用 AutoETS
模型为 Y_train_df_te
中的每个时间聚合计算基础预测。请注意,Y_hat_df_te
包含预测值,但它们并不一致。
另请注意,每个时间聚合的频率和 horizon 都不同。在此示例中,最低层级具有季度频率,horizon 为 8
(构成 2
年)。因此,year
聚合具有年度频率,horizon 为 2
。
当然,可以为时间聚合中的每个层级选择不同的模型 - 您可以随心所欲地创新!
3c. 协调预测
我们可以再次使用 HierarchicalReconciliation
类来协调预测。在此示例中,我们使用 BottomUp
和 MinTrace
。请注意,我们必须在 reconcile
函数中设置 temporal=True
。
请注意,时间协调目前不支持样本内(insample)协调方法,例如 MinTrace(method='mint_shrink')
。
4. 评估
HierarchicalForecast
包包括用于评估不同层级的 evaluate
函数。
4a. 跨部门评估
我们首先评估所有跨部门聚合的预测。
level | metric | Base | BottomUp | MinTrace(ols) | |
---|---|---|---|---|---|
0 | Total | rmse | 4249.25 | 4461.95 | 4234.55 |
1 | 目的 | rmse | 1222.57 | 1273.48 | 1137.57 |
2 | 州 | rmse | 635.78 | 546.02 | 611.32 |
3 | Regions | rmse | 103.67 | 107.00 | 99.23 |
4 | Bottom | rmse | 33.15 | 33.98 | 32.30 |
5 | Overall | rmse | 81.89 | 82.41 | 78.97 |
可以看出,MinTrace(ols)
似乎是每个跨部门聚合的最佳预测方法。
4b. 时间评估
然后,我们评估所有时间聚合的时间聚合预测。
level | metric | Base | BottomUp | MinTrace(ols) | |
---|---|---|---|---|---|
0 | year | rmse | 480.85 | 581.18 | 515.32 |
1 | semiannual | rmse | 312.33 | 304.98 | 275.30 |
2 | quarter | rmse | 168.02 | 168.02 | 155.61 |
3 | Overall | rmse | 253.94 | 266.17 | 241.19 |
同样,MinTrace(ols)
是总体最佳方法,在 quarter
聚合预测上得分最低的 rmse
,而在 year
聚合预测上略差于 Base
预测。
4c. 跨时间评估
最后,我们进行跨时间评估。为此,我们首先需要获取跨部门层级和时间层级的组合,我们可以使用 get_cross_temporal_tags
辅助函数来完成。
正如我们所见,我们现在有一个标签 Country//year
,其中包含 Australia//year-1
和 Australia//year-2
,表示跨部门层级 Australia
在时间层级 2016
和 2017
下的聚合。
我们现在的数据集和跨时间标签已准备好进行评估。
我们定义一组 eval_tags,现在我们将每个跨部门聚合也按每个时间聚合进行拆分。请注意,我们在下面的概述中跳过了 semiannual 时间聚合。
level | metric | Base | BottomUp | MinTrace(ols) | |
---|---|---|---|---|---|
0 | TotalByYear | rmse | 7148.99 | 8243.06 | 7748.40 |
1 | RegionsByYear | rmse | 151.96 | 175.69 | 158.48 |
2 | BottomByYear | rmse | 46.98 | 50.78 | 46.72 |
3 | TotalByQuarter | rmse | 2060.77 | 2060.77 | 1942.32 |
4 | RegionsByQuarter | rmse | 57.07 | 57.07 | 54.12 |
5 | BottomByQuarter | rmse | 19.42 | 19.42 | 18.69 |
6 | Overall | rmse | 43.14 | 45.27 | 42.49 |
我们发现最佳方法是跨时间协调方法 AutoETS/MinTrace_method-ols
,它实现了总体最低的 RMSE。
参考文献
- Hyndman, R.J., & Athanasopoulos, G. (2021). “Forecasting: principles and practice, 3rd edition: Chapter 11: Forecasting hierarchical and grouped series.”. OTexts: Melbourne, Australia. OTexts.com/fpp3 Accessed on July 2022.
- Rob Hyndman, Alan Lee, Earo Wang, Shanika Wickramasuriya, and Maintainer Earo Wang (2021). “hts: Hierarchical and Grouped Time Series”. URL https://CRAN.R-project.org/package=hts. R package version 0.3.1.
- Mitchell O’Hara-Wild, Rob Hyndman, Earo Wang, Gabriel Caceres, Tim-Gunnar Hensel, and Timothy Hyndman (2021). “fable: Forecasting Models for Tidy Time Series”. URL https://CRAN.R-project.org/package=fable. R package version 6.0.2.
- Athanasopoulos, G, Hyndman, Rob J., Kourentzes, N., Petropoulos, Fotios (2017). Forecasting with temporal hierarchies. European Journal of Operational Research, 262, 60-74