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.
Each split has an accessor that returns (X, y) sliding windows:
method |
windows built over |
typical use |
|---|---|---|
|
Train |
fit a candidate model while tuning |
|
Val (with lookback context from Train’s tail) |
score / select hyperparameters |
|
Train + Val |
refit the chosen model before testing |
|
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.
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().
|
transform (params from Train) |
inverse |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
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.