MarkovSwitchingARResult#

class cultivars.univariate.regime_switching.MarkovSwitchingARResult(*, endog, fittedvalues, resid, llf, nobs, n_params, order, n_regimes, switching_mean, switching_ar, switching_variance, transition, intercepts, ar_params, variances, filtered_prob, predicted_prob, smoothed_prob, ergodic_prob, expected_durations, n_iter, converged)[source]

Bases: _SummaryMixin, _SeriesMixin, _ComparisonMixin

A fitted Markov-switching autoregression.

The model

\[y_t = c_{S_t} + \sum_{i=1}^{p} \phi_{i,S_t}\, y_{t-i} + \varepsilon_t, \qquad \varepsilon_t \sim N(0, \sigma^2_{S_t}), \qquad \Pr(S_t = j \mid S_{t-1} = i) = P_{ij},\]

with \(S_t \in \{0, \ldots, K-1\}\) a latent first-order Markov chain and whichever of the intercept, autoregressive block and variance were declared switching taking regime-specific values. The regime is never observed, so every per-date quantity here is an expectation under a posterior over states: the fitted value is \(\sum_j \Pr(S_t = j \mid \cdot)\, m_{j,t}\), the residual is taken against it, and the three posteriors – predicted, filtered, smoothed – differ only in what they condition on. The parameters are the EM maximizer from the best of several screened starts, with the regimes relabelled by the convention label_ordering names.

Variables:
  • endog – The full input series.

  • fittedvalues – Posterior-weighted one-step means, sum_j p_j m_j.

  • resid – Residuals against those weighted means.

  • llf – Log-likelihood from the final Hamilton filter pass.

  • nobs – Effective sample, len(endog) - order.

  • n_params – Free parameters: K(K-1) transition probabilities plus the switching and non-switching coefficient blocks and the variances.

  • order – Autoregressive order within each regime.

  • n_regimes – Number of regimes K.

  • switching_mean – Whether the intercept switches.

  • switching_ar – Whether the autoregressive coefficients switch.

  • switching_variance – Whether the innovation variance switches.

  • transition – Row-stochastic (K, K) matrix.

  • intercepts – Per-regime intercepts, shape (K,).

  • ar_params – Per-regime autoregressive coefficients, shape (K, p).

  • variances – Per-regime innovation variances, shape (K,).

  • filtered_prob – Pr(S_t = j | y_1..t), shape (nobs, K).

  • predicted_prob – Pr(S_t = j | y_1..t-1), shape (nobs, K).

  • smoothed_prob – Pr(S_t = j | y_1..T), shape (nobs, K).

  • ergodic_prob – Stationary distribution of transition, shape (K,).

  • expected_durations – 1 / (1 - P_jj), in periods, shape (K,).

  • n_iter – EM iterations used by the refining run.

  • converged – Whether the refining run met its tolerance.

Note

Non-switching blocks are stored at full (K, ...) shape with identical rows, so ar_params[j] is always the block regime j uses whether or not it switches; n_params counts each shared block once. fittedvalues, resid and the three posteriors are aligned with the last nobs observations of endog. Standard errors are not yet reported by this estimator.

See also

References

Hamilton, J. D. (1989). A new approach to the economic analysis of nonstationary time series and the business cycle. Econometrica, 57(2), 357-384.

Kim, C.-J. (1994). Dynamic linear models with Markov-switching. Journal of Econometrics, 60(1-2), 1-22.

Krolzig, H.-M. (1997). Markov-Switching Vector Autoregressions. Springer.

Example

A two-regime shift in level, with the chain and the posterior dating compared against the truth:

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> p = np.array([[0.97, 0.03], [0.05, 0.95]])
>>> mu = np.array([-1.0, 1.5])
>>> s = np.zeros(1500, dtype=int)
>>> for t in range(1, 1500):
...     s[t] = np.searchsorted(np.cumsum(p[s[t - 1]]), rng.random())
>>> y = mu[s] + 0.5 * rng.standard_normal(1500)
>>> res = MarkovSwitchingAR(y, order=1, n_regimes=2).fit(seed=0)
>>> res.specification, res.converged, res.nobs, res.n_params
('MSIH(2)-AR(1)', True, 1499, 7)
>>> bool(np.allclose(res.transition, p, atol=0.03))
True
>>> bool(np.allclose(res.intercepts, mu, atol=0.1))
True
>>> bool(np.mean(res.most_likely_regime == s[1:]) > 0.98)
True

Private methods#

_comparison_label()

Specification label used when this result appears in a ranking.

_from_fit(fit, model)

Assemble the public result from a raw fit and its specification.

_likelihood_ratio_obstacle(counterpart)

Block only the comparison that changes the number of regimes.

_series()

Aligned per-observation output, widened by the regime posterior.

_summary_table()

Structured summary rendered by every display path.