MarkovSwitchingVARResult#
- class cultivars.multivariate.regime_switching.markov_switching.MarkovSwitchingVARResult(*, endog, names, order, trend, n_regimes, switching_mean, switching_ar, switching_variance, transition, regimes, filtered_prob, predicted_prob, smoothed_prob, ergodic_prob, expected_durations, fittedvalues, resid, llf, nobs, n_params, label_ordering, n_iter, converged)[source]#
A fitted Markov-switching vector autoregression.
Conditional on a latent first-order Markov chain \(S_t \in \{0, \dots, M-1\}\) with transition matrix \(P\), the panel follows
\[y_t = D_{S_t} d_t + \sum_{i=1}^{p} A_{i, S_t}\, y_{t-i} + u_t, \qquad u_t \mid S_t = m \sim N(0, \Sigma_m),\]with each of the three blocks either switching with the chain or held common across regimes. The chain is never observed: the record carries its filtered, predicted and smoothed posteriors, and every quantity that depends on the regime – fitted values, residuals, the regime a date “is in” – is an expectation under the smoothed posterior.
Note
Two consequences of the mixture form are enforced here rather than left to the reader. The likelihood is invariant to relabelling the regimes, so a sorting convention is imposed and
label_orderingnames it; without it two runs of the same model could not be compared coefficient by coefficient. And the number of regimes cannot be tested by a likelihood ratio: under the null of fewer regimes the extra regime’s parameters are unidentified and its transition probabilities lie on the boundary, solikelihood_ratio_test()refuses any comparison that changesMwhile allowing those that hold it fixed.- Variables:
endog – The observed
(n, k)panel.names – Variable labels, in column order.
order – Autoregressive order
pwithin each regime.trend –
"n","c"or"ct".n_regimes – Number of latent regimes
M.switching_mean – Whether the deterministic block switches.
switching_ar – Whether the lag coefficients switch.
switching_variance – Whether the innovation covariance switches.
transition – Row-stochastic
(M, M)matrix,transition[i, j] = Pr(S_t = j | S_{t-1} = i).regimes – One closed-system view per regime, in label order; the composition hook the structural layer consumes.
filtered_prob –
Pr(S_t = m | y_1..t), shape(nobs, M).predicted_prob –
Pr(S_t = m | y_1..t-1), shape(nobs, M).smoothed_prob –
Pr(S_t = m | y_1..T), shape(nobs, M).ergodic_prob – Stationary distribution of
transition.expected_durations –
1 / (1 - P_mm), in periods.fittedvalues –
(nobs, k)posterior-weighted one-step means.resid –
(nobs, k)residuals against those weighted means.llf – Log-likelihood from the final filter pass.
nobs – Effective sample size
n - p.n_params – Free parameters:
M (M - 1)transitions, the coefficient blocks counted once per regime that switches them, and the covariance block(s).label_ordering – Which quantity regimes were sorted by, ascending.
n_iter – EM iterations used by the refining run.
converged – Whether the refining run met its tolerance.
See also
MarkovSwitchingVAR– the model whosefit()returns this record.MarkovSwitchingSVAR– one identification scheme applied to everyregime()view.MarkovSwitchingAR– the scalar family on the same filter and smoother.TVAR– the regime computed from an observable instead of inferred.
References
Hamilton, J. D. (1990). Analysis of time series subject to changes in regime. Journal of Econometrics, 45(1-2), 39-70.
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. Chapters 6 and 9.
Example
Two regimes that differ in their intercepts and scales around a common lag block. EM recovers the means, the transition matrix and the regime path, and the fitted values are the smoothed-posterior mixture of the two regimes’ conditional means:
>>> 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, -0.5], [1.5, 1.0]]) >>> s, y = np.zeros(600, dtype=int), np.zeros((600, 2)) >>> for t in range(1, 600): ... s[t] = np.searchsorted(np.cumsum(p[s[t - 1]]), rng.random()) ... y[t] = mu[s[t]] + 0.3 * y[t - 1] + 0.4 * rng.standard_normal(2) >>> res = MarkovSwitchingVAR(y, order=1, n_regimes=2).fit(seed=0, n_init=3) >>> res.specification, res.converged, res.nobs, res.n_params ('MSIH(2)-VAR(1)', True, 599, 16.0) >>> np.vstack([view.deterministic[0] for view in res.regimes]).round(1) array([[-1. , -0.5], [ 1.5, 1. ]]) >>> bool(np.abs(res.transition - p).max() < 0.03) True >>> bool((res.most_likely_regime == s[1:]).mean() > 0.98) True >>> mixture = sum( ... res.smoothed_prob[:, [m]] * (v.deterministic[0] + y[:-1] @ v.coefficients[0].T) ... for m, v in enumerate(res.regimes) ... ) >>> bool(np.allclose(mixture, res.fittedvalues)) True
Attributes#
The observed |
|
Variable labels, in column order. |
|
Autoregressive order within each regime. |
|
The deterministic specification shared by every regime's design. |
|
Number of latent regimes |
|
Whether the deterministic block switches with the chain. |
|
Whether the lag coefficients switch with the chain. |
|
Whether the innovation covariance switches with the chain. |
|
The row-stochastic |
|
One closed linear system per regime, in label order. |
|
|
|
|
|
|
|
The stationary distribution of |
|
|
|
The |
|
|
|
Log-likelihood from the final filter pass. |
|
Effective sample size |
|
transitions, the switching and common blocks, the covariance(s). |
|
The quantity regimes were sorted by, ascending. |
|
EM iterations used by the refining run. |
|
Whether the refining run met its tolerance. |
|
AIC, BIC, and HQIC derived from the likelihood and parameter count. |
|
Whether every regime is stable read as a linear VAR. |
|
Number of endogenous variables. |
|
Pointwise most probable regime under the smoothed posterior. |
|
Average smoothed probability of each regime over the sample. |
|
Mean posterior entropy, normalized so |
|
Krolzig code for which blocks switch, e.g. |
Methods#
|
Rank this result against others by an information criterion. |
|
Test this result as the restricted model against a nesting one. |
|
Return one of the three regime posteriors. |
|
One regime's closed-system view, identity-stable across calls. |
One row per regime: scale, persistence, and how much sample it owns. |
|
|
The estimation summary, renderable as text, HTML, or a dataframe. |