20
20
21
21
22
22
class BayesianETS (PyMCStateSpace ):
23
+ r"""
24
+ Exponential Smoothing State Space Model
25
+
26
+ This class can represent a subset of exponential smoothing state space models, specifically those with additive
27
+ errors. Following .. [1], The general form of the model is:
28
+
29
+ .. math::
30
+
31
+ \begin{align}
32
+ y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
33
+ \epsilon_t &\sim N(0, \sigma)
34
+ \end{align}
35
+
36
+ where :math:`l_t` is the level component, :math:`b_t` is the trend component, and :math:`s_t` is the seasonal
37
+ component. These components can be included or excluded, leading to different model specifications. The following
38
+ models are possible:
39
+
40
+ * `ETS(A,N,N)`: Simple exponential smoothing
41
+
42
+ .. math::
43
+
44
+ \begin{align}
45
+ y_t &= l_{t-1} + \epsilon_t \\
46
+ l_t &= l_{t-1} + \alpha \epsilon_t
47
+ \end{align}
48
+
49
+ Where :math:`\alpha \in [0, 1]` is a mixing parameter between past observations and current innovations.
50
+ These equations arise by starting from the "component form":
51
+
52
+ .. math::
53
+
54
+ \begin{align}
55
+ \hat{y}_{t+1 | t} &= l_t \\
56
+ l_t &= \alpha y_t + (1 - \alpha) l_{t-1} \\
57
+ &= l_{t-1} + \alpha (y_t - l_{t-1})
58
+ &= l_{t-1} + \alpha \epsilon_t
59
+ \end{align}
60
+
61
+ Where $\epsilon_t$ are the forecast errors, assumed to be IID mean zero and normally distributed. The role of
62
+ :math:`\alpha` is clearest in the second line. The level of the time series at each time is a mixture of
63
+ :math:`\alpha` percent of the incoming data, and :math:`1 - \alpha` percent of the previous level. Recursive
64
+ substitution reveals that the level is a weighted composite of all previous observations; thus the name
65
+ "Exponential Smoothing".
66
+
67
+ Additional supposed specifications include:
68
+
69
+ * `ETS(A,A,N)`: Holt's linear trend method
70
+
71
+ .. math::
72
+
73
+ \begin{align}
74
+ y_t &= l_{t-1} + b_{t-1} + \epsilon_t \\
75
+ l_t &= l_{t-1} + b_{t-1} + \alpha \epsilon_t \\
76
+ b_t &= b_{t-1} + \alpha \beta^\star \epsilon_t
77
+ \end{align}
78
+
79
+ [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^\star`.
80
+
81
+ * `ETS(A,N,A)`: Additive seasonal method
82
+
83
+ .. math::
84
+
85
+ \begin{align}
86
+ y_t &= l_{t-1} + s_{t-m} + \epsilon_t \\
87
+ l_t &= l_{t-1} + \alpha \epsilon_t \\
88
+ s_t &= s_{t-m} + (1 - \alpha)\gamma^\star \epsilon_t
89
+ \end{align}
90
+
91
+ [1]_ also consider an alternative parameterization with :math:`\gamma = (1 - \alpha) \gamma^\star`.
92
+
93
+ * `ETS(A,A,A)`: Additive Holt-Winters method
94
+
95
+ .. math::
96
+
97
+ \begin{align}
98
+ y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
99
+ l_t &= l_{t-1} + \alpha \epsilon_t \\
100
+ b_t &= b_{t-1} + \alpha \beta^\star \epsilon_t \\
101
+ s_t &= s_{t-m} + (1 - \alpha) \gamma^\star \epsilon_t
102
+ \end{align}
103
+
104
+ [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^star` and
105
+ :math:`\gamma = (1 - \alpha) \gamma^\star`.
106
+
107
+ * `ETS(A, Ad, N)`: Dampened trend method
108
+
109
+ .. math::
110
+
111
+ \begin{align}
112
+ y_t &= l_{t-1} + b_{t-1} + \epsilon_t \\
113
+ l_t &= l_{t-1} + \alpha \epsilon_t \\
114
+ b_t &= \phi b_{t-1} + \alpha \beta^\star \epsilon_t
115
+ \end{align}
116
+
117
+ [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^\star`.
118
+
119
+ * `ETS(A, Ad, A)`: Dampened trend with seasonal method
120
+
121
+ .. math::
122
+
123
+ \begin{align}
124
+ y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
125
+ l_t &= l_{t-1} + \alpha \epsilon_t \\
126
+ b_t &= \phi b_{t-1} + \alpha \beta^\star \epsilon_t \\
127
+ s_t &= s_{t-m} + (1 - \alpha) \gamma^\star \epsilon_t
128
+ \end{align}
129
+
130
+ [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^star` and
131
+ :math:`\gamma = (1 - \alpha) \gamma^\star`.
132
+
133
+
134
+ Parameters
135
+ ----------
136
+ order: tuple of string, Optional
137
+ The exponential smoothing "order". This is a tuple of three strings, each of which should be one of 'A', 'Ad',
138
+ or 'N'.
139
+ If provided, the model will be initialized from the given order, and the `trend`, `damped_trend`, and `seasonal`
140
+ arguments will be ignored.
141
+ endog_names: str or list of str, Optional
142
+ Names associated with observed states. If a list, the length should be equal to the number of time series
143
+ to be estimated.
144
+ k_endog: int, Optional
145
+ Number of time series to estimate. If endog_names are provided, this is ignored and len(endog_names) is
146
+ used instead.
147
+ trend: bool
148
+ Whether to include a trend component. Setting ``trend=True`` is equivalent to ``order[1] == 'A'``.
149
+ damped_trend: bool
150
+ Whether to include a damping parameter on the trend component. Ignored if `trend` is `False`. Setting
151
+ ``trend=True`` and ``damped_trend=True`` is equivalent to order[1] == 'Ad'.
152
+ seasonal: bool
153
+ Whether to include a seasonal component. Setting ``seasonal=True`` is equivalent to ``order[2] = 'A'``.
154
+ seasonal_periods: int
155
+ The number of periods in a complete seasonal cycle. Ignored if `seasonal` is `False`
156
+ (or if ``order[2] == "N"``)
157
+ measurement_error: bool
158
+ Whether to include a measurement error term in the model. Default is `False`.
159
+ use_transformed_parameterization: bool, default False
160
+ If true, use the :math:`\alpha, \beta, \gamma` parameterization, otherwise use the :math:`\alpha, \beta^\star,
161
+ \gamma^\star` parameterization. This will change the admissible region for the priors.
162
+
163
+ - Under the **non-transformed** parameterization, all of :math:`\alpha, \beta^\star, \gamma^\star` should be
164
+ between 0 and 1.
165
+ - Under the **transformed** parameterization, :math:`\alpha \in (0, 1)`, :math:`\beta \in (0, \alpha)`, and
166
+ :math:`\gamma \in (0, 1 - \alpha)`
167
+
168
+ The :meth:`param_info` method will change to reflect the suggested intervals based on the value of this
169
+ argument.
170
+ dense_innovation_covariance: bool, default False
171
+ Whether to estimate a dense covariance for statespace innovations. In an ETS models, each observed variable
172
+ has a single source of stochastic variation. If True, these innovations are allowed to be correlated.
173
+ Ignored if ``k_endog == 1``
174
+ stationary_initialization: bool, default False
175
+ If True, the Kalman Filter's initial covariance matrix will be set to an approximate steady-state value.
176
+ The approximation is formed by adding a small dampening factor to each state. Specifically, the level state
177
+ for a ('A', 'N', 'N') model is written:
178
+
179
+ .. math::
180
+ \ell_t = \ell_{t-1} + \alpha * e_t
181
+
182
+ That this system is not stationary can be understood in ARIMA terms: the level is a random walk; that is,
183
+ :math:`rho = 1`. This can be remedied by pretending that we instead have a dampened system:
184
+
185
+ .. math::
186
+ \ell_t = \rho \ell_{t-1} + \alpha * e_t
187
+
188
+ With :math:`\rho \approx 1`, the system is stationary, and we can solve for the steady-state covariance
189
+ matrix. This is then used as the initial covariance matrix for the Kalman Filter. This is a heuristic
190
+ method that helps avoid setting a prior on the initial covariance matrix.
191
+ initialization_dampening: float, default 0.8
192
+ Dampening factor to add to non-stationary model components. This is only used for initialization, it does
193
+ *not* add dampening to the model. Ignored if `stationary_initialization` is `False`.
194
+ filter_type: str, default "standard"
195
+ The type of Kalman Filter to use. Options are "standard", "single", "univariate", "steady_state",
196
+ and "cholesky". See the docs for kalman filters for more details.
197
+ verbose: bool, default True
198
+ If true, a message will be logged to the terminal explaining the variable names, dimensions, and supports.
199
+ mode: str or Mode, optional
200
+ Pytensor compile mode, used in auxiliary sampling methods such as ``sample_conditional_posterior`` and
201
+ ``forecast``. The mode does **not** effect calls to ``pm.sample``.
202
+
203
+ Regardless of whether a mode is specified, it can always be overwritten via the ``compile_kwargs`` argument
204
+ to all sampling methods.
205
+
206
+
207
+ References
208
+ ----------
209
+ .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles and practice. OTexts, 2018.
210
+ """
211
+
23
212
def __init__ (
24
213
self ,
25
214
order : tuple [str , str , str ] | None = None ,
@@ -38,195 +227,6 @@ def __init__(
38
227
verbose : bool = True ,
39
228
mode : str | Mode | None = None ,
40
229
):
41
- r"""
42
- Exponential Smoothing State Space Model
43
-
44
- This class can represent a subset of exponential smoothing state space models, specifically those with additive
45
- errors. Following .. [1], The general form of the model is:
46
-
47
- .. math::
48
-
49
- \begin{align}
50
- y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
51
- \epsilon_t &\sim N(0, \sigma)
52
- \end{align}
53
-
54
- where :math:`l_t` is the level component, :math:`b_t` is the trend component, and :math:`s_t` is the seasonal
55
- component. These components can be included or excluded, leading to different model specifications. The following
56
- models are possible:
57
-
58
- * `ETS(A,N,N)`: Simple exponential smoothing
59
-
60
- .. math::
61
-
62
- \begin{align}
63
- y_t &= l_{t-1} + \epsilon_t \\
64
- l_t &= l_{t-1} + \alpha \epsilon_t
65
- \end{align}
66
-
67
- Where :math:`\alpha \in [0, 1]` is a mixing parameter between past observations and current innovations.
68
- These equations arise by starting from the "component form":
69
-
70
- .. math::
71
-
72
- \begin{align}
73
- \hat{y}_{t+1 | t} &= l_t \\
74
- l_t &= \alpha y_t + (1 - \alpha) l_{t-1} \\
75
- &= l_{t-1} + \alpha (y_t - l_{t-1})
76
- &= l_{t-1} + \alpha \epsilon_t
77
- \end{align}
78
-
79
- Where $\epsilon_t$ are the forecast errors, assumed to be IID mean zero and normally distributed. The role of
80
- :math:`\alpha` is clearest in the second line. The level of the time series at each time is a mixture of
81
- :math:`\alpha` percent of the incoming data, and :math:`1 - \alpha` percent of the previous level. Recursive
82
- substitution reveals that the level is a weighted composite of all previous observations; thus the name
83
- "Exponential Smoothing".
84
-
85
- Additional supposed specifications include:
86
-
87
- * `ETS(A,A,N)`: Holt's linear trend method
88
-
89
- .. math::
90
-
91
- \begin{align}
92
- y_t &= l_{t-1} + b_{t-1} + \epsilon_t \\
93
- l_t &= l_{t-1} + b_{t-1} + \alpha \epsilon_t \\
94
- b_t &= b_{t-1} + \alpha \beta^\star \epsilon_t
95
- \end{align}
96
-
97
- [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^\star`.
98
-
99
- * `ETS(A,N,A)`: Additive seasonal method
100
-
101
- .. math::
102
-
103
- \begin{align}
104
- y_t &= l_{t-1} + s_{t-m} + \epsilon_t \\
105
- l_t &= l_{t-1} + \alpha \epsilon_t \\
106
- s_t &= s_{t-m} + (1 - \alpha)\gamma^\star \epsilon_t
107
- \end{align}
108
-
109
- [1]_ also consider an alternative parameterization with :math:`\gamma = (1 - \alpha) \gamma^\star`.
110
-
111
- * `ETS(A,A,A)`: Additive Holt-Winters method
112
-
113
- .. math::
114
-
115
- \begin{align}
116
- y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
117
- l_t &= l_{t-1} + \alpha \epsilon_t \\
118
- b_t &= b_{t-1} + \alpha \beta^\star \epsilon_t \\
119
- s_t &= s_{t-m} + (1 - \alpha) \gamma^\star \epsilon_t
120
- \end{align}
121
-
122
- [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^star` and
123
- :math:`\gamma = (1 - \alpha) \gamma^\star`.
124
-
125
- * `ETS(A, Ad, N)`: Dampened trend method
126
-
127
- .. math::
128
-
129
- \begin{align}
130
- y_t &= l_{t-1} + b_{t-1} + \epsilon_t \\
131
- l_t &= l_{t-1} + \alpha \epsilon_t \\
132
- b_t &= \phi b_{t-1} + \alpha \beta^\star \epsilon_t
133
- \end{align}
134
-
135
- [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^\star`.
136
-
137
- * `ETS(A, Ad, A)`: Dampened trend with seasonal method
138
-
139
- .. math::
140
-
141
- \begin{align}
142
- y_t &= l_{t-1} + b_{t-1} + s_{t-m} + \epsilon_t \\
143
- l_t &= l_{t-1} + \alpha \epsilon_t \\
144
- b_t &= \phi b_{t-1} + \alpha \beta^\star \epsilon_t \\
145
- s_t &= s_{t-m} + (1 - \alpha) \gamma^\star \epsilon_t
146
- \end{align}
147
-
148
- [1]_ also consider an alternative parameterization with :math:`\beta = \alpha \beta^star` and
149
- :math:`\gamma = (1 - \alpha) \gamma^\star`.
150
-
151
-
152
- Parameters
153
- ----------
154
- order: tuple of string, Optional
155
- The exponential smoothing "order". This is a tuple of three strings, each of which should be one of 'A', 'Ad',
156
- or 'N'.
157
- If provided, the model will be initialized from the given order, and the `trend`, `damped_trend`, and `seasonal`
158
- arguments will be ignored.
159
- endog_names: str or list of str, Optional
160
- Names associated with observed states. If a list, the length should be equal to the number of time series
161
- to be estimated.
162
- k_endog: int, Optional
163
- Number of time series to estimate. If endog_names are provided, this is ignored and len(endog_names) is
164
- used instead.
165
- trend: bool
166
- Whether to include a trend component. Setting ``trend=True`` is equivalent to ``order[1] == 'A'``.
167
- damped_trend: bool
168
- Whether to include a damping parameter on the trend component. Ignored if `trend` is `False`. Setting
169
- ``trend=True`` and ``damped_trend=True`` is equivalent to order[1] == 'Ad'.
170
- seasonal: bool
171
- Whether to include a seasonal component. Setting ``seasonal=True`` is equivalent to ``order[2] = 'A'``.
172
- seasonal_periods: int
173
- The number of periods in a complete seasonal cycle. Ignored if `seasonal` is `False`
174
- (or if ``order[2] == "N"``)
175
- measurement_error: bool
176
- Whether to include a measurement error term in the model. Default is `False`.
177
- use_transformed_parameterization: bool, default False
178
- If true, use the :math:`\alpha, \beta, \gamma` parameterization, otherwise use the :math:`\alpha, \beta^\star,
179
- \gamma^\star` parameterization. This will change the admissible region for the priors.
180
-
181
- - Under the **non-transformed** parameterization, all of :math:`\alpha, \beta^\star, \gamma^\star` should be
182
- between 0 and 1.
183
- - Under the **transformed** parameterization, :math:`\alpha \in (0, 1)`, :math:`\beta \in (0, \alpha)`, and
184
- :math:`\gamma \in (0, 1 - \alpha)`
185
-
186
- The :meth:`param_info` method will change to reflect the suggested intervals based on the value of this
187
- argument.
188
- dense_innovation_covariance: bool, default False
189
- Whether to estimate a dense covariance for statespace innovations. In an ETS models, each observed variable
190
- has a single source of stochastic variation. If True, these innovations are allowed to be correlated.
191
- Ignored if ``k_endog == 1``
192
- stationary_initialization: bool, default False
193
- If True, the Kalman Filter's initial covariance matrix will be set to an approximate steady-state value.
194
- The approximation is formed by adding a small dampening factor to each state. Specifically, the level state
195
- for a ('A', 'N', 'N') model is written:
196
-
197
- .. math::
198
- \ell_t = \ell_{t-1} + \alpha * e_t
199
-
200
- That this system is not stationary can be understood in ARIMA terms: the level is a random walk; that is,
201
- :math:`rho = 1`. This can be remedied by pretending that we instead have a dampened system:
202
-
203
- .. math::
204
- \ell_t = \rho \ell_{t-1} + \alpha * e_t
205
-
206
- With :math:`\rho \approx 1`, the system is stationary, and we can solve for the steady-state covariance
207
- matrix. This is then used as the initial covariance matrix for the Kalman Filter. This is a heuristic
208
- method that helps avoid setting a prior on the initial covariance matrix.
209
- initialization_dampening: float, default 0.8
210
- Dampening factor to add to non-stationary model components. This is only used for initialization, it does
211
- *not* add dampening to the model. Ignored if `stationary_initialization` is `False`.
212
- filter_type: str, default "standard"
213
- The type of Kalman Filter to use. Options are "standard", "single", "univariate", "steady_state",
214
- and "cholesky". See the docs for kalman filters for more details.
215
- verbose: bool, default True
216
- If true, a message will be logged to the terminal explaining the variable names, dimensions, and supports.
217
- mode: str or Mode, optional
218
- Pytensor compile mode, used in auxiliary sampling methods such as ``sample_conditional_posterior`` and
219
- ``forecast``. The mode does **not** effect calls to ``pm.sample``.
220
-
221
- Regardless of whether a mode is specified, it can always be overwritten via the ``compile_kwargs`` argument
222
- to all sampling methods.
223
-
224
-
225
- References
226
- ----------
227
- .. [1] Hyndman, Rob J., and George Athanasopoulos. Forecasting: principles and practice. OTexts, 2018.
228
- """
229
-
230
230
if order is not None :
231
231
if len (order ) != 3 or any (not isinstance (o , str ) for o in order ):
232
232
raise ValueError ("Order must be a tuple of three strings." )
0 commit comments