cultivars.univariate.smooth_transition#

Smooth-transition autoregressions: LSTAR and ESTAR.

Two linear autoregressions blended by a weight that moves continuously with a lagged value of the series,

\[y_t = \bigl(1 - G(y_{t-d})\bigr)\,\phi_L' x_t + G(y_{t-d})\,\phi_U' x_t + \varepsilon_t, \qquad x_t = (1, y_{t-1}, \ldots, y_{t-p})',\]

with the logistic transition \(G(z) = \bigl(1 + \exp(-\gamma (z - c)/s)\bigr)^{-1}\) – monotone, so the regimes are low and high – or the exponential transition \(G(z) = 1 - \exp(-\gamma (z - c)^2 / s^2)\) – symmetric about \(c\), so the regimes are near and far from it. \(s\) is the standard deviation of the transition variable, so \(\gamma\) is a speed per standard deviation and comparable across series; as \(\gamma \to \infty\) the logistic weight becomes an indicator and the model is the hard-switch threshold model with two extra parameters. Conditional on \((\gamma, c)\) the model is linear in \((\phi_L, \phi_U)\), so estimation concentrates the regime blocks out by least squares and searches only the two transition parameters,

\[(\hat\gamma, \hat c) = \arg\min_{\gamma, c}\; \min_{\phi_L, \phi_U} \sum_t \varepsilon_t(\gamma, c, \phi_L, \phi_U)^2,\]

by derivative-free multi-start, because the surface is flat in \(\gamma\) away from the data and multimodal in \(c\).

Two commitments shape the surface. First, the transition is reported on a scale a reader can judge: gamma per standard deviation with the scale retained, and a flag, is_effectively_abrupt, raised when the fitted speed has driven the weight to an indicator and the likelihood is flat in gamma – the smooth model has then said nothing a SETAR would not, and the summary says so. Second, nonlinearity is not tested here. Under linearity the threshold, the delay and the speed drop out of the likelihood, so a chi-squared likelihood ratio against the linear autoregression has no limit distribution (the Davies problem); the result’s likelihood_ratio_test refuses, the criteria rank specifications without testing them, and the Terasvirta linearity test is terasvirta().

Layout. LSTAR and ESTAR fix the transition family and delegate to _SmoothTransitionModel in _internals, which validates order and delay through validate_order and the family through validate_choice against Transition; _build_objective lays out the regressors with deterministic_columns and lag_matrix, seeds the threshold from the best hard split over interior quantiles, and hands a _SmoothTransitionObjective – whose least_squares is ols from _core on the weighted blocks – to _maximize_likelihood under Nelder-Mead. The packed _SmoothTransitionFit is assembled by STARResult._from_fit(); the result extends _ObservedRegimeResult, which supplies the per-regime stability verdicts, the refusal of the likelihood-ratio test and simulate through _simulate_two_regime, and emits its mean as a NonlinearSSM through NonlinearSSM._lag_stack_state_space. The hard-switch counterpart is threshold; the latent-regime counterpart is regime_switching; the vector form is cultivars.multivariate.regime_switching.

References

Terasvirta, T. (1994). Specification, estimation, and evaluation of smooth transition autoregressive models. Journal of the American Statistical Association, 89(425), 208-218.

van Dijk, D., Terasvirta, T., & Franses, P. H. (2002). Smooth transition autoregressive models: A survey of recent developments. Econometric Reviews, 21(1), 1-47.

Davies, R. B. (1987). Hypothesis testing when a nuisance parameter is present only under the alternative. Biometrika, 74(1), 33-43.

Example

A smooth switch fitted three ways; the smooth model wins on BIC, the hard switch is close, and the linear fit is not in the race:

>>> import numpy as np
>>> from cultivars.univariate.autoregression import AR
>>> from cultivars.univariate.threshold import SETAR
>>> rng = np.random.default_rng(0)
>>> y = np.zeros(800)
>>> for t in range(1, 800):
...     w = 1.0 / (1.0 + np.exp(-10.0 * y[t - 1]))
...     y[t] = (1 - w) * (0.5 + 0.6 * y[t - 1]) + w * (-0.5 - 0.6 * y[t - 1])
...     y[t] += 0.3 * rng.standard_normal()
>>> smooth = LSTAR(y, order=1).fit()
>>> hard = SETAR(y, order=1).fit()
>>> linear = AR(y, order=1).fit()
>>> bic = [fit.information_criteria.bic for fit in (smooth, hard, linear)]
>>> bool(bic[0] < bic[1] < bic[2]), bool(bic[2] - bic[0] > 400)
(True, True)
>>> smooth.is_effectively_abrupt, bool(abs(smooth.threshold - hard.threshold) < 0.2)
(False, True)

Classes#

ESTAR

Exponential smooth-transition autoregression.

LSTAR

Logistic smooth-transition autoregression.

STARResult

A fitted smooth-transition autoregression.