0
# Hierarchical Forecast
1
2
A comprehensive Python library for hierarchical time series forecasting that provides cross-sectional and temporal reconciliation methods including BottomUp, TopDown, MiddleOut, MinTrace, and ERM, as well as probabilistic coherent prediction methods such as Normality, Bootstrap, and PERMBU. The library addresses the challenge of maintaining coherent forecasts across different levels of hierarchical data structures (like geographical, categorical, or temporal aggregations) which is essential for consistent decision-making and planning in business and research contexts.
3
4
## Package Information
5
6
- **Package Name**: hierarchicalforecast
7
- **Language**: Python
8
- **Installation**: `pip install hierarchicalforecast`
9
10
## Core Imports
11
12
```python
13
from hierarchicalforecast.core import HierarchicalReconciliation
14
```
15
16
Common imports for reconciliation methods:
17
18
```python
19
from hierarchicalforecast.methods import (
20
BottomUp, BottomUpSparse, TopDown, TopDownSparse,
21
MiddleOut, MiddleOutSparse, MinTrace, MinTraceSparse,
22
OptimalCombination, ERM
23
)
24
```
25
26
For evaluation:
27
28
```python
29
from hierarchicalforecast.evaluation import evaluate
30
```
31
32
For probabilistic methods:
33
34
```python
35
from hierarchicalforecast.probabilistic_methods import Normality, Bootstrap, PERMBU
36
```
37
38
For utilities:
39
40
```python
41
from hierarchicalforecast.utils import aggregate, aggregate_temporal, HierarchicalPlot
42
```
43
44
## Basic Usage
45
46
```python
47
import pandas as pd
48
import numpy as np
49
from hierarchicalforecast.core import HierarchicalReconciliation
50
from hierarchicalforecast.methods import BottomUp, TopDown, MinTrace
51
from hierarchicalforecast.utils import aggregate
52
53
# Sample hierarchical data preparation
54
df = pd.DataFrame({
55
'unique_id': ['A', 'A', 'B', 'B', 'C', 'C'],
56
'ds': pd.date_range('2020-01-01', periods=2, freq='D').tolist() * 3,
57
'y': [100, 110, 200, 220, 150, 160]
58
})
59
60
# Create hierarchical structure
61
spec = [['A', 'B', 'C']] # Group bottom level series
62
Y_df, S_df, tags = aggregate(df, spec)
63
64
# Generate base forecasts (example)
65
forecasts = pd.DataFrame({
66
'unique_id': ['A', 'A', 'B', 'B', 'C', 'C', 'A/B/C', 'A/B/C'],
67
'ds': pd.date_range('2020-01-03', periods=2, freq='D').tolist() * 4,
68
'AutoARIMA': [115, 120, 230, 240, 170, 180, 515, 540]
69
})
70
71
# Initialize reconciliation methods
72
reconcilers = [
73
BottomUp(),
74
TopDown(method='forecast_proportions'),
75
MinTrace(method='ols')
76
]
77
78
# Create reconciliation object
79
hrec = HierarchicalReconciliation(reconcilers=reconcilers)
80
81
# Perform reconciliation
82
reconciled_forecasts = hrec.reconcile(
83
Y_hat_df=forecasts,
84
S=S_df,
85
tags=tags,
86
Y_df=Y_df
87
)
88
89
print(reconciled_forecasts)
90
```
91
92
## Architecture
93
94
HierarchicalForecast is built around a modular architecture:
95
96
- **HierarchicalReconciliation**: Main orchestrator that coordinates multiple reconciliation methods
97
- **Reconciliation Methods**: Specialized classes implementing different reconciliation approaches (BottomUp, TopDown, MiddleOut, MinTrace, ERM, OptimalCombination)
98
- **Evaluation Framework**: Tools for measuring forecast accuracy across hierarchy levels
99
- **Data Utilities**: Functions for creating hierarchical structures and data preparation
100
- **Visualization Tools**: Classes for plotting hierarchical data and reconciliation results
101
- **Probabilistic Methods**: Classes for generating prediction intervals and samples with coherent reconciliation
102
103
## Capabilities
104
105
### Core Reconciliation
106
107
Main orchestration functionality for applying multiple hierarchical reconciliation methods to base forecasts, ensuring coherence across hierarchy levels.
108
109
```python { .api }
110
class HierarchicalReconciliation:
111
def __init__(self, reconcilers: list[HReconciler]): ...
112
def reconcile(
113
self,
114
Y_hat_df: Frame,
115
S: Frame,
116
tags: dict[str, np.ndarray],
117
Y_df: Optional[Frame] = None,
118
level: Optional[list[int]] = None,
119
intervals_method: str = "normality",
120
num_samples: int = -1,
121
seed: int = 0,
122
is_balanced: bool = False,
123
id_col: str = "unique_id",
124
time_col: str = "ds",
125
target_col: str = "y",
126
id_time_col: str = "temporal_id",
127
temporal: bool = False,
128
) -> FrameT: ...
129
def bootstrap_reconcile(
130
self,
131
Y_hat_df: Frame,
132
S_df: Frame,
133
tags: dict[str, np.ndarray],
134
Y_df: Optional[Frame] = None,
135
level: Optional[list[int]] = None,
136
intervals_method: str = "normality",
137
num_samples: int = -1,
138
num_seeds: int = 1,
139
id_col: str = "unique_id",
140
time_col: str = "ds",
141
target_col: str = "y",
142
) -> FrameT: ...
143
```
144
145
[Core Reconciliation](./core-reconciliation.md)
146
147
### Reconciliation Methods
148
149
Various reconciliation algorithms including bottom-up, top-down, middle-out, minimum trace, optimal combination, and empirical risk minimization approaches, each with sparse variants for scalability.
150
151
```python { .api }
152
class BottomUp:
153
def fit_predict(self, S, y_hat, idx_bottom, **kwargs): ...
154
155
class TopDown:
156
def __init__(self, method='forecast_proportions'): ...
157
def fit_predict(self, S, y_hat, tags, y_insample=None, **kwargs): ...
158
159
class MinTrace:
160
def __init__(self, method='ols', nonnegative=False, mint_shr_ridge=2e-8, num_threads=1): ...
161
def fit_predict(self, S, y_hat, y_insample=None, **kwargs): ...
162
```
163
164
[Reconciliation Methods](./reconciliation-methods.md)
165
166
### Evaluation
167
168
Comprehensive evaluation framework for measuring forecast accuracy across different hierarchy levels using standard metrics from utilsforecast.losses.
169
170
```python { .api }
171
def evaluate(df, metrics, tags, models=None, train_df=None, level=None, id_col='unique_id', time_col='ds', target_col='y', agg_fn='mean', benchmark=None): ...
172
```
173
174
[Evaluation](./evaluation.md)
175
176
### Probabilistic Methods
177
178
Probabilistic reconciliation methods for generating prediction intervals and samples from hierarchically coherent distributions, supporting normality assumptions, bootstrap sampling, and empirical copula approaches.
179
180
```python { .api }
181
class Normality:
182
def __init__(self, S: np.ndarray, P: np.ndarray, y_hat: np.ndarray, sigmah: np.ndarray, W: np.ndarray, seed: int = 0): ...
183
def get_samples(self, num_samples: int) -> np.ndarray: ...
184
def get_prediction_quantiles(self, results: dict, quantiles: np.ndarray) -> dict: ...
185
186
class Bootstrap:
187
def __init__(self, S: np.ndarray, P: np.ndarray, y_hat: np.ndarray, y_insample: np.ndarray, y_hat_insample: np.ndarray, num_samples: int, seed: int = 0): ...
188
def get_samples(self, num_samples: int) -> np.ndarray: ...
189
def get_prediction_quantiles(self, results: dict, quantiles: np.ndarray) -> dict: ...
190
191
class PERMBU:
192
def __init__(self, S: np.ndarray, P: np.ndarray, y_hat: np.ndarray, tags: dict, y_insample: np.ndarray, y_hat_insample: np.ndarray, sigmah: np.ndarray, num_samples: int, seed: int = 0): ...
193
def get_samples(self, num_samples: int) -> np.ndarray: ...
194
def get_prediction_quantiles(self, results: dict, quantiles: np.ndarray) -> dict: ...
195
```
196
197
[Probabilistic Methods](./probabilistic-methods.md)
198
199
### Data Utilities
200
201
Utilities for creating hierarchical data structures from bottom-level time series, including cross-sectional and temporal aggregation capabilities.
202
203
```python { .api }
204
def aggregate(df, spec, exog_vars=None, sparse_s=False, id_col='unique_id', time_col='ds', id_time_col=None, target_cols=('y',)): ...
205
def aggregate_temporal(df, spec, exog_vars=None, sparse_s=False, id_col='unique_id', time_col='ds', id_time_col='temporal_id', target_cols=('y',), aggregation_type='local'): ...
206
def make_future_dataframe(df, freq, h, id_col='unique_id', time_col='ds'): ...
207
```
208
209
[Data Utilities](./data-utilities.md)
210
211
### Visualization
212
213
Plotting utilities for visualizing hierarchical time series data, reconciliation results, and hierarchy structures.
214
215
```python { .api }
216
class HierarchicalPlot:
217
def __init__(self, S, tags, S_id_col='unique_id'): ...
218
def plot_summing_matrix(self): ...
219
def plot_series(self, series, Y_df, models=None, level=None, **kwargs): ...
220
def plot_hierarchically_linked_series(self, bottom_series, Y_df, models=None, level=None, **kwargs): ...
221
def plot_hierarchical_predictions_gap(self, Y_df, models=None, **kwargs): ...
222
```
223
224
[Visualization](./visualization.md)
225
226
## Types
227
228
```python { .api }
229
# Import necessary types
230
from typing import Optional
231
from narwhals.typing import Frame, FrameT
232
import numpy as np
233
import scipy.sparse
234
235
# DataFrame types expected by the library
236
Frame = Frame # Narwhals Frame for input DataFrames
237
FrameT = FrameT # Narwhals FrameT for output DataFrames
238
239
# Reconciler base class
240
class HReconciler:
241
"""Base class for all reconciliation methods."""
242
fitted: bool
243
is_sparse_method: bool
244
insample: bool
245
246
# Common column specifications
247
id_col: str = 'unique_id' # Series identifier column
248
time_col: str = 'ds' # Timestamp column
249
target_col: str = 'y' # Target variable column
250
id_time_col: str = 'temporal_id' # Temporal hierarchy identifier
251
252
# Aggregation specification
253
spec: list[list[str]] # Cross-sectional hierarchy specification
254
spec: dict[str, int] # Temporal aggregation specification
255
256
# Tags dictionary mapping hierarchy levels to series indices
257
tags: dict[str, np.ndarray]
258
259
# Summing matrix formats
260
S: Frame # Dense summing matrix as Frame
261
S: scipy.sparse.csr_matrix # Sparse summing matrix for large hierarchies
262
```