API reference#
The full public API, generated from the source docstrings.
Overview#
Single-reservoir Echo State Network. |
|
Multi-reservoir Echo State Network with separate inputs per reservoir. |
|
Two-reservoir Echo State Network. |
|
Fractional Echo State Network: dual-reservoir ESN with a fractional-differencing memory branch. |
|
Wavelet Echo State Network: dual-reservoir ESN with a MODWT + fractional-differencing memory branch. |
|
Create lookback/lookahead windows for forecasting. |
Models#
- class memory_esn.BaseESN(n_reservoir=100, spectral_radius=0.9, input_scaling=0.5, input_init='uniform', reservoir_init='uniform', bias_init='uniform', leaky=1.0, activation='tanh', bias_scaling=0.0, noise=0.0, sparsity=0.9, random_state=None, alphas=(0.01, 0.1, 1.0, 10.0), ridge_cv_params=None, concatenate_input=True)[source]#
Bases:
PersistenceMixinSingle-reservoir Echo State Network.
- Parameters:
n_reservoir (int, default=100) – Number of reservoir neurons.
spectral_radius (float, default=0.9) – Target spectral radius of the reservoir weight matrix (controls memory / stability; keep < 1 for the echo-state property).
input_scaling (float, default=0.5) – Scale of the random input weights.
input_init (str, default='uniform') – Distribution for the input weights: ‘uniform’, ‘gaussian’/’normal’, ‘bernoulli’/’binary’, or ‘laplace’. See
memory_esn.weights. (Uniform is the paper’s initialisation.)reservoir_init (str, default='uniform') – Distribution for the reservoir weights (same options). The matrix is still rescaled to
spectral_radiusafterwards.bias_init (str, default='uniform') – Distribution for the neuron bias (same options; only used when
bias_scaling > 0).leaky (float, default=1.0) – Leaky-integration rate (1.0 = no leak).
activation (str, default='tanh') – Reservoir nonlinearity. One of: ‘tanh’, ‘sigmoid’, ‘relu’, ‘leaky_relu’, ‘elu’, ‘selu’, ‘softplus’, ‘swish’/’silu’, ‘gelu’, ‘hard_tanh’, ‘softsign’, ‘mish’, ‘hard_sigmoid’, ‘relu6’, ‘tanhshrink’, ‘sin’, ‘identity’/’linear’.
bias_scaling (float, default=0.0) – Scale of the random neuron bias (0.0 = no bias).
noise (float, default=0.0) – Std-dev sigma of isotropic additive state noise eta(t) ~ N(0, sigma^2 I) injected into the pre-activation each timestep (0.0 = no noise). Drawn from the reservoir RNG, so results are reproducible for a fixed seed.
sparsity (float, default=0.9) – Fraction of reservoir connections forced to zero (0.0 = dense, 0.9 = 90% zeros). Matches the paper’s sparsification proportion phi.
random_state (int or None, default=None) – Seed for reproducibility.
alphas (tuple of float, default=(0.01, 0.1, 1.0, 10.0)) – Candidate ridge penalties for
RidgeCV.ridge_cv_params (dict, optional) – Extra keyword arguments forwarded to
RidgeCV.concatenate_input (bool, default=True) – If True, append the raw input to the reservoir states before the readout.
Examples
>>> esn = BaseESN(n_reservoir=200, spectral_radius=0.95, random_state=0) >>> esn.fit(X_train, y_train, washout=100) >>> y_pred = esn.predict(X_test)
- predict(X, x0=None, continuation=False)[source]#
Predict outputs for
X(optionally continuing from the last state).
- class memory_esn.MultiESN(n_reservoirs=3, n_reservoir=100, spectral_radius=0.9, input_scaling=0.5, input_init='uniform', reservoir_init='uniform', bias_init='uniform', leaky=1.0, activation='tanh', bias_scaling=0.0, noise=0.0, sparsity=0.9, random_state=None, alphas=(0.01, 0.1, 1.0, 10.0), ridge_cv_params=None, concatenate_inputs=True, verbose=False)[source]#
Bases:
PersistenceMixinMulti-reservoir Echo State Network with separate inputs per reservoir.
Every per-reservoir hyperparameter accepts either a single value (broadcast to all reservoirs) or a list of length
n_reservoirs.- Parameters:
n_reservoirs (int, default=3) – Number of parallel reservoirs.
n_reservoir (Union[int, List[int]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).spectral_radius (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).input_scaling (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).input_init (Union[str, List[str]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).reservoir_init (Union[str, List[str]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).bias_init (Union[str, List[str]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).leaky (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).activation (Union[str, List[str]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).bias_scaling (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).noise (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).sparsity (Union[float, List[float]]) – Per-reservoir hyperparameters – scalar (broadcast) or list of length
n_reservoirs. SeeBaseESN(*_initselect the weight distribution: ‘gaussian’, ‘uniform’, ‘bernoulli’, ‘laplace’).random_state (int, list of int, or None, default=None) – Seed(s). A single int gives each reservoir a distinct derived seed (reproducible but not identical). A list is used verbatim as the per-reservoir seeds and must have length
n_reservoirs. None disables reproducibility.alphas (tuple of float, default=(0.01, 0.1, 1.0, 10.0)) – Candidate ridge penalties for the shared readout.
ridge_cv_params (dict, optional) – Extra keyword arguments for
RidgeCV.concatenate_inputs (bool, default=True) – If True, append all raw inputs to the combined states before the readout.
verbose (bool, default=False) – Print a short fit summary.
Examples
>>> esn = MultiESN(n_reservoirs=3, n_reservoir=100, random_state=0) >>> esn.fit([X1, X2, X3], y, washout=100) >>> y_pred = esn.predict([X1_test, X2_test, X3_test])
- predict(X_list, x0_list=None, continuation=False)[source]#
Predict outputs for a list of per-reservoir input sequences.
- get_reservoir_states(X_list, x0_list=None, reservoir_idx=None, continuation=False)[source]#
Return states for one reservoir (
reservoir_idx) or all of them.
- class memory_esn.DoubleReservoirESN(n_reservoir=100, spectral_radius=0.9, input_scaling=0.5, input_init='uniform', reservoir_init='uniform', bias_init='uniform', leaky=1.0, activation='tanh', bias_scaling=0.0, noise=0.0, sparsity=0.9, random_state=None, alphas=(0.01, 0.1, 1.0, 10.0), ridge_cv_params=None, concatenate_inputs=True, verbose=False)[source]#
Bases:
MultiESNTwo-reservoir Echo State Network.
Each per-reservoir hyperparameter is either a scalar (applied to both reservoirs) or a length-2 pair
(value_reservoir_1, value_reservoir_2).- Parameters:
n_reservoir (Union[int, Pair]) – Scalar or length-2 pair. See
BaseESN.spectral_radius (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.input_scaling (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.input_init (Union[str, Pair]) – Scalar or length-2 pair. See
BaseESN.reservoir_init (Union[str, Pair]) – Scalar or length-2 pair. See
BaseESN.bias_init (Union[str, Pair]) – Scalar or length-2 pair. See
BaseESN.leaky (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.activation (Union[str, Pair]) – Scalar or length-2 pair. See
BaseESN.bias_scaling (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.noise (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.sparsity (Union[float, Pair]) – Scalar or length-2 pair. See
BaseESN.
Examples
>>> esn = DoubleReservoirESN(n_reservoir=(150, 100), random_state=0) >>> esn.fit([X1, X2], y, washout=100) >>> y_pred = esn.predict([X1_test, X2_test])
- class memory_esn.fESN(n_reservoir=100, spectral_radius=0.9, input_scaling=0.5, input_init='uniform', reservoir_init='uniform', bias_init='uniform', leaky=1.0, activation='tanh', bias_scaling=0.0, noise=0.0, sparsity=0.9, d=0.5, K=100, skip_initial=True, random_state=None, alphas=(0.01, 0.1, 1.0, 10.0), ridge_cv_params=None, concatenate_inputs=True, verbose=False)[source]#
Bases:
DoubleReservoirESNFractional Echo State Network: dual-reservoir ESN with a fractional-differencing memory branch.
- Parameters:
n_reservoir (Union[int, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
spectral_radius (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
input_scaling (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
input_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
reservoir_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
bias_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
leaky (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
activation (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
bias_scaling (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
noise (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
sparsity (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = fracdiff).
d (float or list of float, default=0.5) – Fractional differencing order(s) (0 = none, 1 = first difference). A single value (default) gives a univariate fracdiff branch; a list, e.g.
[0.3, 0.6], applies each order and stacks the results, making the second reservoir’s input multivariate (one block of channels per order).K (int, default=100) – Number of lags in the fractional-difference filter.
skip_initial (bool, default=True) – If True, drop the first
Ktimesteps (where the filter window is not yet full) instead of using a partial window.
Notes
When
skip_initial=Trueandcontinuation=False, outputs areKtimesteps shorter than the input; align targets accordingly.Examples
>>> # univariate fracdiff branch (default) >>> fesn = fESN(n_reservoir=(200, 150), d=0.5, K=100, random_state=0) >>> fesn.fit(X_train, y_train, washout=100) # single raw series in >>> y_pred = fesn.predict(X_test)
>>> # multivariate: three differencing orders stacked >>> fesn = fESN(n_reservoir=(200, 150), d=[0.3, 0.5, 0.8], K=100)
- fit(X, y, washout=0, x0_list=None)[source]#
Fit on a single raw series
X(targets aligned to the fracdiff branch).
- class memory_esn.wESN(n_reservoir=100, spectral_radius=0.9, input_scaling=0.5, input_init='uniform', reservoir_init='uniform', bias_init='uniform', leaky=1.0, activation='tanh', bias_scaling=0.0, noise=0.0, sparsity=0.9, d=0.25, K=100, wavelet='haar', wavelet_level=2, wavelet_components='smooth', wavelet_norm='modwt', skip_initial=True, random_state=None, alphas=(0.01, 0.1, 1.0, 10.0), ridge_cv_params=None, concatenate_inputs=True, verbose=False)[source]#
Bases:
DoubleReservoirESNWavelet Echo State Network: dual-reservoir ESN with a MODWT + fractional-differencing memory branch.
- Parameters:
n_reservoir (Union[int, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
spectral_radius (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
input_scaling (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
input_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
reservoir_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
bias_init (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
leaky (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
activation (Union[str, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
bias_scaling (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
noise (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
sparsity (Union[float, Pair]) – Scalar or length-2 pair (reservoir 1 = raw, reservoir 2 = processed).
d (float or list of float, default=0.25) – Fractional differencing order(s) applied to the selected wavelet component(s). A single value (default) is univariate; a list applies each order and stacks the results, so the second reservoir’s input is the cross-product of components and orders (
n_features x n_components x n_dchannels).K (int, default=100) – Number of lags in the fractional-difference filter.
wavelet (str, default='haar') – Discrete wavelet understood by PyWavelets (e.g. ‘haar’, ‘db4’, ‘sym4’). Continuous wavelets (‘mexh’, ‘morl’, …) are rejected – see
_validate_wavelet().wavelet_level (int, default=2) – MODWT decomposition depth
J(number of detail levels produced).wavelet_components (default='smooth') –
Which MODWT component(s) feed reservoir 2. One of:
'smooth'/'approx'– the level-Japproximation (default, i.e. the classic smooth trend).an int
kin1..J– detail coefficients at levelk.'details'– all detail levelsD_1..D_J.'all'– all details plus the smooth.a list mixing ints and
'smooth', e.g.[1, 2, 'smooth'].
Selecting more than one component makes the second reservoir’s input multivariate (one column per selected component, per input feature).
wavelet_norm ({'modwt', 'classic'}, default='modwt') – MODWT filter normalisation. ‘modwt’ uses the standard Percival-Walden rescaling (Haar smooth filter [1/2, 1/2]); ‘classic’ uses the DWT orthonormal filters ([1/sqrt2, 1/sqrt2]). The two differ only by a per-level constant that the random memory-input weights absorb, so they are model-equivalent; ‘classic’ reproduces the paper’s example equation literally.
skip_initial (bool, default=True) – If True, drop the first
Ktimesteps of the differenced branch.
Examples
>>> # classic smooth trend (backward-compatible default) >>> wesn = wESN(n_reservoir=(200, 150), wavelet='db4', wavelet_level=2) >>> # multivariate: levels 1 & 2 detail plus the smooth >>> wesn = wESN(wavelet='db4', wavelet_level=3, ... wavelet_components=[1, 2, 'smooth'])
- fit(X, y, washout=0, x0_list=None)[source]#
Fit on a single raw series
X(wavelet -> fracdiff for reservoir 2).
Data#
- class memory_esn.TimeSeriesDataset(series, lookback, lookahead, test_size, val_size=None, scaling='none')[source]#
Bases:
objectCreate lookback/lookahead windows for forecasting.
- Parameters:
series (ndarray, shape (n_timesteps,)) – Univariate time series.
lookback (int) – Number of past steps used as input X.
lookahead (int) – Number of future steps to predict (Y).
test_size (int) – Number of final timesteps reserved for testing.
val_size (int, optional) – Validation length; defaults to
2 * test_size.scaling ({'none', 'minmax', 'standard', 'log'}, default='none') – Scaling fitted on the train split only.
Weight initialization#
Weight-initialisation distributions for memory_esn.
Only the distribution the weights are drawn from is configurable here – the reservoir is still rescaled to the target spectral radius and the optional sparsity mask is still applied, exactly as before. This keeps the knob simple: pick a distribution for the input weights, the reservoir weights, and the bias.
Supported distributions (ESN literature draws input weights from a uniform range and reservoir weights from a normal law; bimodal/Bernoulli weights are also common):
'gaussian'(aliases'normal','randn') – N(0, scale^2) [default]'uniform'– U(-scale, scale)'bernoulli'(aliases'binary','bimodal','sign') – {-scale, +scale}'laplace'– Laplace(0, scale)
scale is input_scaling for the input weights and bias_scaling for the
bias; for the reservoir it is 1.0 (absolute scale is set afterwards by the
spectral-radius rescaling, so only the shape of the distribution matters there).
- memory_esn.weights.validate_distribution(distribution, arg_name='init')[source]#
Raise
ValueErrorunlessdistributionis a known name/alias.
- memory_esn.weights.init_input_weights(rng, n_reservoir, n_inputs, scaling=0.5, distribution='gaussian')[source]#
Input weight matrix
W_inof shape (n_reservoir, n_inputs).
- memory_esn.weights.use_sparse_reservoir(n_reservoir, sparsity)[source]#
Whether to store
Was a scipy sparse matrix for this configuration.True only for large, highly-sparse reservoirs (see the module-level thresholds), where a sparse matvec beats a dense BLAS
dgemv. Small, mid-sized, or dense reservoirs keep the dense NumPy path.
- memory_esn.weights.init_reservoir_weights(rng, n_reservoir, spectral_radius=0.9, distribution='gaussian', sparsity=0.0, sparse=None)[source]#
Reservoir matrix
Wdrawn fromdistribution, sparsified, then rescaled so its spectral radius equalsspectral_radius.Returns a dense
np.ndarray(default) or, for large highly-sparse reservoirs, a scipy CSR matrix.sparseforces the storage choice; whenNoneit is decided automatically byuse_sparse_reservoir(). The random draw and sparsity mask are identical in both cases, so the two paths hold the same weights – only the storage format (and the matvec used at runtime) differs.
Speed-up kernels#
Compiled speed-up kernels for memory_esn.
Three performance-critical routines live here as Cython extensions:
esn_reservoir_optimized– BLAS-backed reservoir state update.fractional_diff– fractional differencing (binomial weights).modwt_fast– maximal-overlap discrete wavelet transform.
Each has a pure-Python/NumPy fallback in memory_esn._speedups._fallback
so the package remains importable even when the extensions are not compiled.
The public API of memory_esn transparently selects the compiled kernel
when available and the fallback otherwise.
- memory_esn._speedups.reservoir_update(input_sequence, W_in, W_reservoir, activation='tanh', leaky=1.0, bias=None, W_feedback=None, feedback_sequence=None, x0=None, noise_sequence=None)
- memory_esn._speedups.reservoir_update_sparse(input_sequence, W_in, W_reservoir, activation='tanh', leaky=1.0, bias=None, x0=None, noise_sequence=None)[source]
Sparse-
Wreservoir update; fused Cython CSR kernel when available.
- memory_esn._speedups.fractional_diff(X, d=0.5, K=100, skip_initial=True, include_zero_lag=True)
Apply fractional differencing to a time series with single d parameter.
- Parameters:
X (ndarray, shape (n_timesteps, n_features)) – Input time series
d (float, default=0.5) – Fractional differencing parameter - d = 0: no differencing - d = 1: standard first differencing - 0 < d < 1: fractional differencing
K (int, default=100) – Window size (number of lags to use)
skip_initial (bool, default=True) – If True, skip first K timesteps (where full window not available) If False, use available data (partial window)
include_zero_lag (bool, default=True) – If True, compute the standard (1-B)^d series which includes the zero-lag term weight w_0 = 1 (i.e. keeps the present value X[t]). If False, drop the zero-lag term (w_0 = 0), yielding the pure-memory filter ((1-B)^d - 1) X[t] = sum_{k>=1} w_k X[t-k].
- Returns:
X_diff (ndarray, shape (n_timesteps - K, n_features) or (n_timesteps, n_features)) – Fractionally differenced series
- memory_esn._speedups.modwt(x, filters, level, norm_factor=0.7071067811865476)
The compiled Cython kernels (with NumPy fallbacks) are selected automatically. Use these flags to check which path is active:
import memory_esn as m
m.USING_CYTHON_RESERVOIR
m.USING_CYTHON_FRACDIFF
m.USING_CYTHON_MODWT