Data#

Forecasting must respect time: you never shuffle, and you never let the future leak into the past. TimeSeriesDataset takes one univariate series and produces chronological train / validation / test splits, turns them into sliding (lookback lookahead) windows, and applies leakage-free scaling.

from memory_esn import TimeSeriesDataset

ds = TimeSeriesDataset(series, lookback=20, lookahead=5, test_size=50, scaling="standard")

The chronological split#

The series is cut from the end: the last test_size points are the test set, the val_size points before it are validation (default val_size = 2 × test_size), and everything earlier is training. Order is always past → future.

Scaling fitted on Train only min/max · mean/std · log same params applied → Train Val Test N − val_size − test_size val_size (≈ 2×test) test_size (latest) past time →

Each split has an accessor that returns (X, y) sliding windows:

method

windows built over

typical use

get_train_data()

Train

fit a candidate model while tuning

get_val_data()

Val (with lookback context from Train’s tail)

score / select hyperparameters

get_full_train_data()

Train + Val

refit the chosen model before testing

get_test_data()

Test (with context; trailing targets NaN-padded)

final, once-only evaluation

Typical workflow: tune on get_train_data()get_val_data(), refit on get_full_train_data(), then report on get_test_data(). Validation and test windows borrow lookback context from the preceding data, so their very first target is predictable.

Sliding windows: lookback → lookahead#

Every sample pairs the last lookback observations (the input X) with the next lookahead observations (the target y). lookahead is the forecast horizon H. The window slides one step at a time across the split.

X · lookback (past) y · lookahead = H window slides one step → one sample = (X, y)

Scaling: fit on train, transform everything, invert predictions#

Scaling parameters are computed from the training split only and then reused to transform validation, test, and the full-train series, no statistic ever sees the future. Predictions come out on the scaled axis, so map them back with inverse_scaling().

Train values fit params (min,max) / (mean,std) transform Train · Val · Test (scaled) model predictions (scaled axis) inverse_scaling original scale

scaling

transform (params from Train)

inverse

none

x

x

minmax

(x min) / (max min)

x·(max min) + min

standard

(x mean) / std

x·std + mean

log

ln(x) (requires x > 0)

exp(x)

Putting it together#

import numpy as np
from memory_esn import TimeSeriesDataset, fESN

series = np.sin(np.linspace(0, 60, 1500)) + 0.1 * np.random.randn(1500)

ds = TimeSeriesDataset(series, lookback=20, lookahead=5, test_size=60, scaling="standard")
print(ds.get_info())            # split sizes, ranges, scaling params

X_tr, y_tr = ds.get_full_train_data()     # (n_samples, lookback), (n_samples, lookahead)
X_te, y_te = ds.get_test_data()

model = fESN(n_reservoir=(200, 150), d=0.4, K=80, random_state=0)
model.fit(X_tr, y_tr, washout=50)

y_pred_scaled = model.predict(X_te)
y_pred = ds.inverse_scaling(y_pred_scaled)   # back to the original units

The full method signatures are in the API reference reference.