Skip to main content

Temporal cross-validation with leakage protection for time-series ML

Project description

temporalcv

Rigorous cross-validation for time series with leakage detection and gap enforcement.

CI PyPI Docs Python Coverage Open In Colab

DocumentationExamplesLeakage Tutorial


Installation

pip install temporalcv

Quick Start

Validate your model for temporal leakage in 4 lines:

from temporalcv import run_gates
from temporalcv.gates import gate_signal_verification

report = run_gates([gate_signal_verification(model, X, y, n_shuffles=100)])
print(report.status)  # HALT, WARN, or PASS
Status Meaning
HALT Signal detected — investigate (legitimate temporal pattern or leakage?)
WARN Marginal signal — proceed with caution
PASS No signal — model has no detectable predictive power

Why temporalcv?

Standard cross-validation shuffles data randomly. For time series, this means training on future data to predict the past — a form of data leakage that inflates metrics.

temporalcv provides:

  • Leakage detection via validation gates (shuffled target test, suspicious improvement)
  • Gap enforcement for h-step forecasting (no lag-feature contamination)
  • High-persistence metrics (MASE, MC-SS) that measure actual skill
  • Conformal coverage with caveats: marginal under exchangeability; time-series autocorrelation can invalidate the guarantee — use AdaptiveConformalPredictor (Gibbs & Candès 2021) for distribution-shift handling

Feature Comparison

Feature temporalcv sklearn sktime darts
Horizon-derived gap (auto) Manual¹ Manual Manual
Leakage detection gates
Conformal prediction Partial
sklearn-compatible API
Statistical tests (DM, PT) Partial

¹ sklearn TimeSeriesSplit(gap=N) (since v0.24) requires the user to compute N from the forecast horizon themselves; temporalcv derives gap = horizon + extra_gap automatically from the horizon parameter.


Core Features

Walk-Forward CV with Gap

from temporalcv import WalkForwardCV

cv = WalkForwardCV(
    window_type="sliding",
    window_size=104,    # 2 years of weekly data
    horizon=2,          # 2-step ahead forecast
    test_size=1
)

for train_idx, test_idx in cv.split(X, y):
    model.fit(X[train_idx], y[train_idx])
    pred = model.predict(X[test_idx])

The horizon parameter enforces a gap between training and test sets, preventing lagged features from leaking target information.

Validation Gates

from temporalcv.gates import gate_signal_verification, gate_suspicious_improvement

gates = [
    gate_signal_verification(model, X, y, n_shuffles=100),
    gate_suspicious_improvement(model_mae, baseline_mae, threshold=0.20),
]

report = run_gates(gates)
if report.status == "HALT":
    raise ValueError(f"Signal detected — investigate: {report.summary()}")

High-Persistence Metrics

When your series is "sticky" (ACF(1) > 0.9), standard MAE lies — predicting "same as yesterday" looks great but adds no value.

from temporalcv.metrics import mase, mc_skill_score

print(f"MASE: {mase(actual, predicted, y_train):.3f}")
print(f"MC-SS: {mc_skill_score(actual, predicted):.3f}")
Metric What It Measures
MASE Error relative to naive forecast (scale-free)
MC-SS Skill only when target moved

Validation Pipeline

flowchart TD
    A[Data + Model] --> B{Validation Gates}
    B -->|HALT| C[Stop & Investigate]
    B -->|WARN| D[Proceed with Caution]
    B -->|PASS| E[Walk-Forward CV]
    E --> F[Statistical Tests]
    F --> G[Deploy]

Common Leakage Patterns

Learn from these failure modes:

Pattern Example Why It's Bad
Rolling stats on full series .rolling().mean() without .shift() Features encode future
No gap for h-step forecast horizon=0 when predicting 2 steps ahead Lag features leak target
Threshold on full data Regime boundary uses all data Classification cheats

See the failure examples gallery for detailed walkthroughs:


Optional Dependencies

pip install temporalcv[benchmarks]   # M4/M5 benchmarks
pip install temporalcv[changepoint]  # PELT algorithm
pip install temporalcv[dev]          # Testing, linting
pip install temporalcv[all]          # Everything

Core: numpy >= 1.21, scipy >= 1.7, scikit-learn >= 1.0, statsmodels >= 0.13, matplotlib >= 3.5 • Optional: pandas >= 1.3 (pip install temporalcv[pandas])

Platforms: Linux, macOS, Windows | Python: 3.10+


Documentation

Resource Description
Quickstart Get running in 5 minutes
Leakage Tutorial Deep dive on detection
API Reference Full API docs
Examples Gallery 21 real-world cases

Validation Evidence

Test Reference Result
DM test golden values R forecast::dm.test() ✓ Match
Type I error rate 500 Monte Carlo sims 5% ± 2%
Conformal coverage Synthetic AR(1) 95% nominal
Benchmark M4 Competition (4,773 series) ✓ Validated

See Testing Strategy for details.


Citation

@software{temporalcv2025,
  author    = {Behring, Brandon},
  title     = {temporalcv: Temporal cross-validation with leakage protection},
  year      = {2025},
  publisher = {GitHub},
  url       = {https://github.com/brandon-behring/temporalcv}
}

Ecosystem

Part of the Rigorous AI Engineering ecosystem:

Project Description
temporalcv (this repo) Temporal cross-validation with leakage detection
ir-eval Statistical retrieval evaluation with drift detection
research-kb Graph-boosted semantic search for research literature

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

MIT License — see LICENSE

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

temporalcv-2.0.1.tar.gz (533.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

temporalcv-2.0.1-py3-none-any.whl (269.5 kB view details)

Uploaded Python 3

File details

Details for the file temporalcv-2.0.1.tar.gz.

File metadata

  • Download URL: temporalcv-2.0.1.tar.gz
  • Upload date:
  • Size: 533.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for temporalcv-2.0.1.tar.gz
Algorithm Hash digest
SHA256 d1a8aa85f02caf2e74636708b2c2883c2e7f53adbd8f9189fd94a5a687dce2a4
MD5 fcc2ee4425097f19ad13bbc075ab4ae6
BLAKE2b-256 fe10ef11444e130e0a503d88820a012d0e5f43db717d104a7a375f3ffd918d67

See more details on using hashes here.

Provenance

The following attestation bundles were made for temporalcv-2.0.1.tar.gz:

Publisher: publish.yml on brandon-behring/temporalcv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file temporalcv-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: temporalcv-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 269.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for temporalcv-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 054f2a7adb478c7fd5a7dac5f8ed465589427d43296ed288da4d6e89f91fc3f8
MD5 4a09a5db4398f947c360365f8d703003
BLAKE2b-256 09d3bc4b3717faa3f577ba8056019845c2be33b5a5c496d9fbcaf61bcf9f1457

See more details on using hashes here.

Provenance

The following attestation bundles were made for temporalcv-2.0.1-py3-none-any.whl:

Publisher: publish.yml on brandon-behring/temporalcv

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page