Skip to content

About

Leak-free causal deep learning for day-ahead short-term load forecasting (PyTorch + MATLAB). Adaptive dual-stage decomposition + Patch Transformer-BiGRU with cross-attention; honest 5-seed Diebold-Mariano protocol.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

31 Commits

Folders and files

Repository files navigation

Leakage, not decomposition: auditing decompose-then-split hybrids for short-term load forecasting

English · Español

Code and results for an audit of decomposition-based short-term load forecasting (STLF). Two findings: the decompose-then-split protocol that dominates this literature inflates reported accuracy by roughly half, and once that leak is closed the decomposition machinery does no measurable work. Released in PyTorch and MATLAB with a machine-checked causality certificate and a five-seed, significance-tested protocol. The manuscript is under review at Applied Energy.

Graphical abstract: the protocol inflates accuracy by half; a causal analogue permits an ablation; the decomposition is inert

Day-ahead accuracy across the three benchmarks


Why this repository exists

Most decomposition-based STLF hybrids in the literature apply CEEMDAN/EMD/VMD to the whole series before the train–test split. Because these are global transforms, this injects future information into every training subsequence and inflates reported accuracy far beyond what is attainable in operation. This project:

  1. Quantifies that bias. A matched contrast — the same CEEMDAN, the same feature layout, the same learner, computed globally or inside each window — shows the decompose-then-split protocol reports 46–51 % lower error than a causal protocol, an illusion created purely by the evaluation (python/leakage_demo.py, figures/Fig11_leakage_effect.png).
  2. Replaces it with a causal analogue, so that an ablation becomes interpretable at all. The offline CEEMDAN–sample-entropy–VMD chain becomes an in-model, end-to-end learnable, strictly causal analogue (multi-scale causal moving-average split → learnable causal FIR band-pass bank → differentiable complexity gate), tokenized into day-length patches, encoded by a Transformer, fused with future known covariates via cross-attention, decoded by a BiGRU with reversible instance normalization, and anchored by a per-component linear base plus a full-resolution covariate path.
  3. Evaluates honestly, and reports against itself. Operational day-ahead protocol (non-overlapping windows), train-only preprocessing statistics, unmodified test targets, five seeds, Holm-corrected Diebold–Mariano tests, a rolling-origin check, and an ablation on two benchmarks whose answer is that the decomposition in point 2 contributes nothing measurable.

Headline results (leak-free protocol, 5 seeds, MAPE %)

1. How much of the reported accuracy is the leak. Holding the decomposition, the features and the learner fixed and varying only whether the transform sees the future, the invalid protocol reports 46.4 % lower error on GEFCom2014 and 50.9 % on PJM (46–56 % across MAPE, MAE and RMSE). Reproduce with python leakage_demo.py --dataset GEFCom2014.

2. What the decomposition contributes once the leak is closed: nothing measurable. Ablated on a covariate-rich benchmark and on a univariate one, neither decomposition stage nor the adaptive gate moves day-ahead MAPE by more than the spread across five seeds:

Component removed GEFCom2014 AEMO
Stage 1 (multi-scale split) +0.00 pp +0.01 pp
Stage 2 (learnable filter bank) +0.10 pp −0.01 pp
Adaptive gate +0.02 pp +0.01 pp
Per-component linear base +0.21 pp +0.21 pp
Future covariates +3.26 pp −0.01 pp

The linear base — initialised at weekly persistence — is the only component with a resolved effect on both benchmarks.

3. The forecaster itself, for context. Fifteen models, operational day-ahead protocol, five seeds:

Dataset Proposed Rank Best other Verdict (Holm-DM)
PJM 4.87 1 of 15 PatchTST 4.98 none beat it
AEMO 5.53 2 of 15 TiDE 5.46 none beat it; it does not beat TiDE
GEFCom2014 4.73 11 of 15 TCN 4.13 none beat it

Like-for-like five-seed ensembles (every model's, never one against single runs): 1st of 13 on PJM (4.74), 2nd on AEMO (5.22 vs TiDE 5.19), 9th of 13 on GEFCom2014 (4.27 vs 3.70 for TCN).

No baseline outperforms the proposed model at the Holm-corrected 5 % level on any benchmark — read as statistical parity at n = 259/902/274, not as demonstrated equality. The model confidence set (Hansen–Lunde–Nason, python/model_confidence_set.py, results/mcs_v4.json) says the same thing set-wise: the proposed model is in the 90 % MCS on every benchmark under both losses; on PJM under absolute loss that set contains only the proposed model, PatchTST and TiDE. On a rolling-origin evaluation over three disjoint PJM test periods it is first on all three by MAPE (mean 4.10 vs 4.33 for PatchTST), though no per-period test is individually significant and the spread between periods (~0.7 pp) is several times the spread between models.

An earlier version of this repository claimed the decomposition was load-bearing on univariate load — "the mirror image of the univariate case". That rested on a ranking argument, not an ablation. The univariate ablation refutes it, and the claim is withdrawn.

Repository layout

.
├── python/        Reference implementation (PyTorch)
│   ├── main.py                 full pipeline: train, evaluate, DM tests, tables, figures
│   ├── model_proposed.py       the proposed CPTB model + causal decomposition
│   ├── models_baselines.py     14 baselines incl. DLinear, PatchTST, TiDE, seasonal-naïve
│   ├── data_utils.py           leak-free loading, windowing, observed-data masking
│   ├── prepare_data.py         raw public downloads → the canonical CSVs, row-count checked
│   ├── train_pipeline.py       training loop, causal error correction, GBM/ARIMA
│   ├── metrics_stats.py        metrics + Diebold–Mariano (Newey-West, HLN, Holm)
│   ├── figures_tables.py       every table + the single driver for all 12 figures
│   ├── figstyle.py             shared publication style; palette validated for CVD
│   ├── figures_diagrams.py     Figs 1–2 (protocol contrast, architecture)
│   ├── figures_results.py      Figs 3–12, all computed from saved result files
│   ├── leakage_demo.py         the controlled decompose-then-split leakage experiment
│   ├── model_confidence_set.py Hansen–Lunde–Nason MCS over the saved forecasts
│   ├── build_latex_tables.py   every table of the manuscript, printed from results/
│   ├── graphical_abstract.py   the graphical abstract, drawn from results/
│   ├── verify_cptb.py          machine-checked causality / reconstruction certificate
│   └── scripts/                experiment drivers (rolling origin, validation-only selection, TiDE re-run)
├── matlab/        Independent MATLAB port (Deep Learning Toolbox), verified in parity
├── results/       Result tables (CSV + LaTeX) and JSON summaries
├── figures/       Publication figures (PDF + 300-dpi PNG)
└── data/          Place datasets here (see data/README.md)

Regenerating every table and figure from the saved results takes seconds and needs no GPU:

cd python && python -c "import figures_tables as f; f.regenerate_from_saved()"

Quick start (Python)

cd python
pip install -r requirements.txt          # torch, numpy, pandas, scikit-learn, xgboost, lightgbm, statsmodels
python verify_cptb.py                     # machine-checked causality certificate (seconds)
python prepare_data.py --raw /path/to/raw_downloads   # build the canonical CSVs
python main.py                            # full 3-dataset, 5-seed protocol + ablation + figures
python main.py --smoke                    # tiny end-to-end validation run
python leakage_demo.py --dataset GEFCom2014   # reproduce the leakage quantification

Quick start (MATLAB)

cd matlab
verify_cptb                 % correctness certificate: shapes, exact reconstruction,
                            % strict causality, naive-init, all ablations, gradient flow
results = main_v4('GEFCom2014');   % full protocol on one dataset

Requires MATLAB R2022b+ and the Deep Learning Toolbox only. See matlab/README.md.

Figures

All twelve are written by one driver from the saved result files, in a shared style whose categorical palette is machine-validated for colour-vision deficiency (OKLab ΔE on every adjacent pair, plus a contrast check).

1 protocol contrast 2 architecture 3 causal decomposition of one window
4 accuracy across benchmarks 5–7 day-ahead forecasts, one per dataset 8 ablation, two benchmarks
9 cross-attention 10 lead time vs time of day 11 the leakage experiment
12 rolling-origin stability

Two of them report against the paper's own thesis. Figure 8 puts the same ablation on a covariate-rich and a univariate benchmark side by side, and finds both decomposition stages inert on each. Figure 10 shows the error is shaped as much by time of day as by lead time, and that the once-a-day issue schedule confounds the two.

Reproducibility & rigor

  • Causality is machine-checked, not asserted: verify_cptb (both languages) perturbs the most recent input and confirms no earlier decomposition output changes, and checks exact reconstruction and the seasonal-naïve initialization.
  • No fabricated ground truth: multi-week gaps in GEFCom2014 are detected and every window overlapping fabricated data is excluded from training and evaluation.
  • Every figure is generated from result files, and a missing input raises rather than falling back to a default. This is enforced, not merely intended: an audit of this repository found Fig. 11 being drawn from literals typed into the figure code, because leakage_demo.py printed its measurement without saving it. It now writes results/leakage_GEFCom2014.json, and the figure reads it back.
  • Two independent implementations (PyTorch and MATLAB) with verified numerical parity.

Datasets

All three benchmarks are public; download instructions are in data/README.md. GEFCom2014 (hourly, with temperature), PJM Interconnection East (hourly), and AEMO New South Wales (half-hourly).

Citation

@article{Valdivieso2026leakage,
  author  = {Valdivieso, V{\'i}ctor and L{\'o}pez-Lao, Emilio and Garc{\'i}a-Chica, Antonio
             and Cama-Pinto, Alejandro and Arrabal-Campos, Francisco M.},
  title   = {Leakage, not decomposition: auditing decompose-then-split hybrids
             for short-term load forecasting},
  journal = {Applied Energy},
  note    = {Under review},
  year    = {2026}
}

Corresponding author: Francisco M. Arrabal-Campos (fmarrabal@ual.es).

Funding

This work was supported by the Spanish Ministry of Science and Innovation (grants PDC2021-121248-I00, PLEC2021-007774, PID2021-126445OB-I00 and CPP2022-009967) and by the Gobierno de España MCIN/AEI/10.13039/501100011033 and Unión Europea Next Generation EU/PRTR.

License

Released under the MIT License.

About

Leak-free causal deep learning for day-ahead short-term load forecasting (PyTorch + MATLAB). Adaptive dual-stage decomposition + Patch Transformer-BiGRU with cross-attention; honest 5-seed Diebold-Mariano protocol.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages