ARNN#

class cultivars.univariate.mean_function.ARNN(endog, *, order, engine=None)[source]

Bases: _NeuralAutoRegressionModel[ARNNResult]

Neural autoregression: one learned function of order lagged levels.

The model \(y_t = f(y_{t-1}, \ldots, y_{t-p}) + \varepsilon_t\), with \(f\) fitted by the engine on the lag matrix and the innovation variance concentrated out. The default engine is a single-hidden-layer perceptron trained by L-BFGS with an L2 penalty on the weights and a handful of random restarts, so the fit is deterministic for a fixed seed and the capacity is set by hidden_units. Order selection by the information criteria is meaningful within one engine configuration only.

Variables:
  • _endog – The validated series.

  • _order – Number of lagged levels.

  • _engine (MeanFunctionEngine) – The training backend.

Parameters:
  • endog (ArrayLike) – The series.

  • order (int) – Number of lagged levels fed to the learner.

  • engine (MeanFunctionEngine | None) – Training backend. Anything exposing fit(features, target) -> MeanPredictor qualifies; defaults to the package’s reference L-BFGS-trained perceptron.

Raises:

See also

  • ARNNResult – what fit() returns.

  • TARNN – one function per regime.

  • AR – the linear model this generalizes.

  • LSTAR – a parametric nonlinearity with interpretable coefficients.

References

Kuan, C.-M., & White, H. (1994). Artificial neural networks: An econometric perspective. Econometric Reviews, 13(1), 1-91.

Trapletti, A., Leisch, F., & Hornik, K. (2000). Stationary and integrated autoregressive neural network processes. Neural Computation, 12(10), 2427-2450.

Example

>>> import numpy as np
>>> rng = np.random.default_rng(0)
>>> y = np.zeros(500)
>>> for t in range(1, 500):
...     y[t] = 0.8 * np.tanh(2.0 * y[t - 1]) + 0.3 * rng.standard_normal()
>>> res = ARNN(y, order=1).fit()
>>> bool(res.r_squared > 0.3)
True

The learned map beats the linear one on the same lags:

>>> from cultivars.univariate.autoregression import AR
>>> linear = AR(y, order=1).fit()
>>> bool(res.ssr < np.sum(linear.resid**2))
True