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]#

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

Attributes#

endog

(n,) observed series, as given.

fittedvalues

(nobs,) smoothed-posterior-weighted one-step means.

resid

(nobs,) residuals against fittedvalues.

llf

Log-likelihood from the Hamilton filter at the final parameters.

nobs

Effective sample, len(endog) - order.

n_params

Free parameters, counting each non-switching block once.

order

Autoregressive order within each regime.

n_regimes

Number of regimes \(K\).

switching_mean

Whether the intercept takes a regime-specific value.

switching_ar

Whether the autoregressive block takes regime-specific values.

switching_variance

Whether the innovation variance takes a regime-specific value.

transition

(K, K) row-stochastic matrix, [i, j] from i to j.

intercepts

(K,) intercepts, ascending when they switch.

ar_params

(K, p) autoregressive coefficients, rows identical when shared.

variances

(K,) innovation variances, entries identical when shared.

filtered_prob

(nobs, K) real-time posterior Pr(S_t | y_1..t).

predicted_prob

(nobs, K) one-step-ahead posterior Pr(S_t | y_1..t-1).

smoothed_prob

(nobs, K) full-sample posterior Pr(S_t | y_1..T).

ergodic_prob

(K,) stationary distribution of transition.

expected_durations

(K,) mean regime spell lengths 1 / (1 - P_jj).

n_iter

EM iterations used by the refining run.

converged

Whether the refining run met its tolerance within max_iter.

information_criteria

AIC, BIC, and HQIC derived from the likelihood and parameter count.

is_regimewise_stationary

Whether every regime is stationary read as a linear autoregression.

label_ordering

Which quantity regimes were sorted by, ascending.

most_likely_regime

Pointwise most probable regime under the smoothed posterior.

params

Estimated parameters keyed by display name, in table order.

regime_shares

Average smoothed probability of each regime over the sample.

regime_uncertainty

Mean posterior entropy, normalized so 0 is sharp and 1 is flat.

specification

Krolzig code for which blocks switch, e.g. "MSIH(2)-AR(4)".

state_space

The fitted system, re-applicable to data it was not estimated on.

unconditional_mean

Ergodic mean of the process, or None if it is not defined.

Methods#

compare(*others[, criterion])

Rank this result against others by an information criterion.

likelihood_ratio_test(unrestricted)

Test this result as the restricted model against a nesting one.

probabilities([kind])

Return one of the three regime posteriors.

regime_stability(regime)

Companion-eigenvalue verdict for one regime's autoregressive block.

regime_table()

One row per regime: level, scale, and how long it lasts.

simulate([n, seed, burn])

A fresh sample path at the fitted parameters.

simulate_regimes([n, seed, burn])

A fresh sample path together with the regimes that generated it.

summary()

The estimation summary, renderable as text, HTML, or a dataframe.

to_dict()

The aligned per-observation outputs as plain numpy arrays.

to_pandas(*[, index])

The aligned per-observation outputs as a pandas.DataFrame.

to_polars()

The aligned per-observation outputs as a polars.DataFrame.

transition_table()

The estimated transition matrix, rows indexed by the origin regime.