组织成不同聚合级别结构的大量时间序列通常要求其预测遵循聚合约束,这带来了创建能够实现一致预测的新算法的挑战。

HierarchicalForecast 包提供了广泛的 Python 实现的分层预测算法集合,这些算法遵循经典的分层协调。

在本笔记本中,我们将展示如何使用 StatsForecast 库生成基础预测,以及如何使用 HierarchicalForecast 包执行分层协调。

您可以使用 CPU 或 GPU 在 Google Colab 上运行这些实验。

1. 库

!pip install hierarchicalforecast statsforecast datasetsforecast

2. 加载数据

在本示例中,我们将使用 TourismSmall 数据集。以下单元格获取层次结构中不同级别的时间序列,用于从底层层次结构恢复完整数据集的求和矩阵 S,以及用 tags 表示的每个层次结构的索引。

import pandas as pd

from datasetsforecast.hierarchical import HierarchicalData, HierarchicalInfo
group_name = 'TourismSmall'
group = HierarchicalInfo.get_group(group_name)
Y_df, S_df, tags = HierarchicalData.load('./data', group_name)
S_df = S_df.reset_index(names="unique_id")
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
S_df.iloc[:6, :6]
unique_idnsw-hol-citynsw-hol-noncityvic-hol-cityvic-hol-noncityqld-hol-city
0总计1.01.01.01.01.0
1hol1.01.01.01.01.0
2vfr0.00.00.00.00.0
3bus0.00.00.00.00.0
4oth0.00.00.00.00.0
5nsw-hol1.01.00.00.00.0
tags
{'Country': array(['total'], dtype=object),
 'Country/Purpose': array(['hol', 'vfr', 'bus', 'oth'], dtype=object),
 'Country/Purpose/State': array(['nsw-hol', 'vic-hol', 'qld-hol', 'sa-hol', 'wa-hol', 'tas-hol',
        'nt-hol', 'nsw-vfr', 'vic-vfr', 'qld-vfr', 'sa-vfr', 'wa-vfr',
        'tas-vfr', 'nt-vfr', 'nsw-bus', 'vic-bus', 'qld-bus', 'sa-bus',
        'wa-bus', 'tas-bus', 'nt-bus', 'nsw-oth', 'vic-oth', 'qld-oth',
        'sa-oth', 'wa-oth', 'tas-oth', 'nt-oth'], dtype=object),
 'Country/Purpose/State/CityNonCity': array(['nsw-hol-city', 'nsw-hol-noncity', 'vic-hol-city',
        'vic-hol-noncity', 'qld-hol-city', 'qld-hol-noncity',
        'sa-hol-city', 'sa-hol-noncity', 'wa-hol-city', 'wa-hol-noncity',
        'tas-hol-city', 'tas-hol-noncity', 'nt-hol-city', 'nt-hol-noncity',
        'nsw-vfr-city', 'nsw-vfr-noncity', 'vic-vfr-city',
        'vic-vfr-noncity', 'qld-vfr-city', 'qld-vfr-noncity',
        'sa-vfr-city', 'sa-vfr-noncity', 'wa-vfr-city', 'wa-vfr-noncity',
        'tas-vfr-city', 'tas-vfr-noncity', 'nt-vfr-city', 'nt-vfr-noncity',
        'nsw-bus-city', 'nsw-bus-noncity', 'vic-bus-city',
        'vic-bus-noncity', 'qld-bus-city', 'qld-bus-noncity',
        'sa-bus-city', 'sa-bus-noncity', 'wa-bus-city', 'wa-bus-noncity',
        'tas-bus-city', 'tas-bus-noncity', 'nt-bus-city', 'nt-bus-noncity',
        'nsw-oth-city', 'nsw-oth-noncity', 'vic-oth-city',
        'vic-oth-noncity', 'qld-oth-city', 'qld-oth-noncity',
        'sa-oth-city', 'sa-oth-noncity', 'wa-oth-city', 'wa-oth-noncity',
        'tas-oth-city', 'tas-oth-noncity', 'nt-oth-city', 'nt-oth-noncity'],
       dtype=object)}

我们将数据框分为训练/测试集。

Y_test_df = Y_df.groupby('unique_id').tail(group.horizon)
Y_train_df = Y_df.drop(Y_test_df.index)

3. 基础预测

以下单元格使用 auto_arimanaive 模型计算每个时间序列的基础预测。请注意,Y_hat_df 包含预测结果,但它们并不一致。

from statsforecast.core import StatsForecast
from statsforecast.models import AutoARIMA, Naive
fcst = StatsForecast(
    models=[AutoARIMA(season_length=group.seasonality), Naive()], 
    freq="QE", 
    n_jobs=-1
)
Y_hat_df = fcst.forecast(df=Y_train_df, h=group.horizon)

4. 分层协调

以下单元格使用 HierarchicalReconciliation 类使之前的预测结果一致。用于使预测一致的方法包括

from hierarchicalforecast.core import HierarchicalReconciliation
from hierarchicalforecast.methods import BottomUp, TopDown, MiddleOut
reconcilers = [
    BottomUp(),
    TopDown(method='forecast_proportions'),
    TopDown(method='proportion_averages'),
    MiddleOut(middle_level="Country/Purpose/State", top_down_method="proportion_averages"),
]
hrec = HierarchicalReconciliation(reconcilers=reconcilers)
Y_rec_df = hrec.reconcile(Y_hat_df=Y_hat_df, Y_df=Y_train_df, S=S_df, tags=tags)

5. 评估

HierarchicalForecast 包包含 evaluate 函数用于评估不同的层次结构,我们可以使用 utilsforecast 计算相对于基线模型的平均绝对误差。

from hierarchicalforecast.evaluation import evaluate
from utilsforecast.losses import mse
df = Y_rec_df.merge(Y_test_df, on=['unique_id', 'ds'])
evaluation = evaluate(df = df,
                      tags = tags,
                      train_df = Y_train_df,
                      metrics = [mse],
                      benchmark="Naive")

evaluation.set_index(["level", "metric"]).filter(like="ARIMA", axis=1)
AutoARIMAAutoARIMA/自底向上AutoARIMA/自顶向下_方法-预测比例AutoARIMA/自顶向下_方法-平均比例AutoARIMA/中间向下_中间级别-国家/目的/州_自顶向下方法-平均比例
级别指标
国家mse-scaled0.3178970.3670780.3178970.3178970.305053
国家/目的mse-scaled0.3189500.2336060.2622160.3202250.196062
国家/目的/州mse-scaled0.2680570.2811890.3203490.5113560.268057
国家/目的/州/城市非城市mse-scaled0.2921360.2921360.3232610.5097840.280599
总体mse-scaled0.3089420.2956900.2970720.3647750.255038

参考文献