MarkovSwitchingVAR.fit#
- MarkovSwitchingVAR.fit(*, max_iter=500, tol=1e-6, n_init=10, screen_iter=15, seed=None)[source]#
Estimate by EM with multi-start screening.
Unlike the other multivariate families,
fittakes arguments, because the likelihood is multimodal and the answer genuinely depends on where the search starts. The default screensn_initstarts forscreen_iteriterations each and refines only the best; pass aseedwhen the fit must be reproducible.- Parameters:
max_iter (
int) – Iteration cap for the refining run.tol (
float) – Convergence tolerance on the log-likelihood increment.n_init (
int) – Starts to screen, the first being the linear fit split along whichever block switches.screen_iter (
int) – Iterations used to score each screening start.seed (
int|Generator|None) – Seed or generator for the random starts.
- Return type:
- Returns:
The fitted
MarkovSwitchingVARResult, regimes ordered by the conventionMarkovSwitchingVARResult.label_orderingnames.- Raises:
NumericalError – If every start fails to produce a finite likelihood.
Example
The same seed gives the same fit. Screening matters even on a cleanly separated problem: the deterministic first start alone converges to a local optimum in which one persistent regime absorbs the mean shift, more than a hundred log-points below the screened fit:
>>> import numpy as np >>> rng = np.random.default_rng(0) >>> s = np.repeat([0, 1, 0, 1], 100) >>> y = np.array([[-1.0, -0.5], [1.5, 1.0]])[s] + 0.4 * rng.standard_normal((400, 2)) >>> model = MarkovSwitchingVAR(y, order=1, n_regimes=2) >>> one, two = model.fit(seed=0), model.fit(seed=0) >>> one.llf == two.llf, one.converged, one.regime_shares.round(2) (True, True, array([0.5, 0.5])) >>> single = model.fit(seed=0, n_init=1) >>> single.converged, bool(single.llf < one.llf - 100), single.regime_shares.round(2) (True, True, array([0.92, 0.08]))