yotambraun
APDTFlow
Python

APDTFlow is a modern and extensible forecasting framework for time series data that leverages advanced techniques including neural ordinary differential equations (Neural ODEs), transformer-based components, and probabilistic modeling. Its modular design allows researchers and practitioners to experiment with multiple forecasting models and easily

Last updated Jun 14, 2026
44
Stars
5
Forks
0
Issues
0
Stars/day
Attention Score
64
Language breakdown
No language data available.
Files click to expand
README

APDTFlow

APDTFlow: know WHEN it will happen

Website PyPI version License: MIT Downloads Python Versions CI Coverage Open In Colab

Visit the website -> yotambraun.github.io/APDTFlow

Website · Quickstart · Features · Documentation · Methodology · Benchmarks · Examples

Forecasting tools tell you what the value will be. APDTFlow models time as continuous (Neural ODEs), so it also answers the question operations teams actually ask: **when will it cross the line?** The answer comes with a calibrated uncertainty window on the time itself.

One trained model answers three questions:

| Question | API | |---|---| | What are the next k values? | model.predict() | | What is the value at any moment (14:37, in 3.6 days, beyond the trained horizon)? | model.predict_at(timestamps) | | When will the value cross a threshold, with uncertainty on the time itself? | model.predict_when(threshold) |

fleet dashboard

*One call, predictwhenfleet(), turns real NASA jet engines (never seen in training) into a maintenance schedule sorted by act-by date, with what actually happened marked. In this measured snapshot the calibrated windows covered 81% of the actual crossings.*

60-second start

pip install apdtflow

from apdtflow import APDTFlowForecaster

model = APDTFlowForecaster(forecasthorizon=40, decodertype='continuous', use_conformal=True) model.fit(df, targetcol='capacity', featurecols=sensor_cols)

model.predict() # classic grid forecast model.predict_at(['2026-06-11 14:37', 3.6]) # value at ANY moment result = model.predict_when(threshold=1.4, # WHEN it crosses the line direction='below') result.eta, result.act_by, result.censored schedule = model.predictwhenfleet(assets, # whole fleet -> ranked schedule threshold=1.4, direction='below')

Verified results (every number reproducible from experiments/)

evidence summary

| Event-timing audit (real NASA data, held-out units) | APDTFlow | Linear extrap. | Persistence | |---|---|---|---| | Battery end-of-life, 3 cells leave-one-battery-out (timing MAE, measured cycles) | 8.3 (2.8 on the typical cell) | 9.7 | 15.4 | | Turbofan FD001, 40 unseen engines (timing MAE, cycles; 0.6% false alarms) | 8.3 | 8.7 | 11.5 | | Turbofan FD002, 110 unseen engines, 6 operating regimes (timing MAE, cycles; 0.0% false alarms) | 9.2 | 8.1 | 11.3 |

APDTFlow wins the battery and FD001 audits outright and **loses to linear on FD002**, published as measured (it does win FD002's matched subset, 6.8 vs 7.8 cycles, and posts zero false alarms across 2,638 no-crossing windows, the property that matters most against alarm fatigue). Time-window coverage measured 96% / 40% / 54% against a 90% target across the three audits: strong within-distribution, stretched by cross-unit transfer; the trust panel below shows exactly that.

Reproduce: python experiments/batteryeoldemo.py, experiments/turbofanwhendemo.py, experiments/fd002robustnessdemo.py. Full details: docs/experiment_results.md.

Real-world demo: battery end-of-life

battery

Real-world demo: jet-engine maintenance under shifting operating regimes

fd002

Multivariate sensor fusion (fit(..., feature_cols=sensors)) exposes interpretable sensor weights via model.sensorimportance, and, measured on the same audit, trades coverage for sharpness: when the fused model commits to a timing it is markedly more accurate (caught-event error 5.9 vs 8.3 cycles, zero false alarms), but it commits far less often. Published as measured:

multivariate

Trust panel: this package tells you its own limits

trust

The panel reports its own miss: on cross-unit transfer the windows measured under their 90% target, and for distant events the point estimate saturates toward mid-horizon (the flattening scatter). That is why the operational rule exists: **schedule by act_by (the window's earliest edge), never by the point estimate**. The API returns act_by as a first-class field for exactly this reason, and the per-lead-time error bars tell you how much to trust each horizon.

predict_at: forecast at any moment in time

predict_at

One trained model, queried at arbitrary real-valued timestamps (fractional steps, between observations, even beyond the trained horizon), because the decoder integrates a continuous-time ODE. Conformal intervals come interpolated across time. (python examples/predictatdemo.py produced this plot.)

predict_when: a calibrated answer to "when?"

predict_when

*"When will solar activity rise above 80?" The calibrated 90% window covered the true crossing, and the act_by edge landed before it. Windows are calibrated on crossing-time errors (time space), not value bands; that distinction is what makes the coverage hold.* (python examples/predictwhendemo.py.)

Is the base forecaster accurate? Honest numbers

6 datasets (2 real, 4 synthetic), 12-step horizon, 30 epochs, MAE relative to seasonal-naive (<1.0 beats it). Measured June 2026; reproduce: python experiments/benchmark_multidomain.py.

| Dataset | APDTFlow | Linear | Holt-Winters | |---|---|---|---| | Daily min temperature (real) | 0.73 | 0.74 | 0.80 | | Regime-switching nonlinear | 0.77 | 0.83 | 0.86 | | Trend + dual seasonality | 0.85 | 0.50 | 0.38 | | Retail-like multiplicative seasonal | 1.01 | 0.68 | 0.81 | | Electric production (real, 397 pts) | 1.52 | 1.03 | 1.23 | | Random walk (unpredictable) | 1.86 | 1.15 | 1.12 |

APDTFlow beats seasonal-naive on 3 of 6 domains (parity on a 4th) and beats every baseline on two. For pure grid accuracy on regular data, tuned deep models (NeuralForecast) or zero-shot foundation models (Chronos-2, TimesFM, Moirai-2) may be stronger; APDTFlow's value is what grid models cannot do. We are not aware of another forecasting library offering predict_at at arbitrary timestamps or calibrated predict_when event timing (as of June 2026); if you use a foundation model for grid accuracy, APDTFlow is complementary.

What each tool family offers (capabilities, not accuracy)

| Capability | APDTFlow | Grid DL libraries (NeuralForecast, Darts) | Foundation models (Chronos-2, TimesFM, Moirai-2) | |---|:-:|:-:|:-:| | Grid forecasts (predict) | ✅ | ✅ | ✅ | | Calibrated conformal intervals | ✅ | partial | partial | | Forecast at arbitrary real-valued times (predict_at) | ✅ | ✗ | ✗ | | Event timing with calibrated time windows (predict_when) | ✅ | ✗ | ✗ | | Fleet-level act-by scheduling | ✅ | ✗ | ✗ | | Zero-shot (no training) | ✗ | ✗ | ✅ |

When NOT to use APDTFlow

  • Stock prices / crypto: random-walk regime; nothing beats naive, including us
(it's in our benchmark table on purpose).
  • Event timing on noise-driven crossings (e.g., which exact day a noisy daily
series first dips): no model has skill there; expect wide, honest windows.
  • Irregularly-sampled / heavily missing data: we tested ODE-RNN encoders and
missingness features; both lost to simple imputation baselines (documented).
  • Very short series (< ~500 points): use ETS/ARIMA.

Industry-grade plumbing

*Each capability below, with what it's for and a usage snippet, is on the Features page (and in docs/features.md).*

  • Split & adaptive conformal prediction on every API; time-space calibrated
windows for event timing
  • Multivariate health-indicator fusion (feature_cols=) with readable
sensorimportance; per-regime normalization (apdtflow.preprocessing.regime_normalize) for multi-condition equipment
  • Fleet API: predictwhenfleet() → act-by-sorted schedule, CSV/dict export
  • Exogenous & categorical features, backtesting (historical_forecasts),
MASE/sMAPE/CRPS/coverage metrics
  • Robust persistence (save/load with scalers + calibration; pre-0.4
checkpoints are rejected with guidance), TorchScript export, FastAPI serving example, sklearn-style getparams/setparams, score_recent() drift hook, set_seed() deterministic mode, MLflow/W&B logging hook, py.typed
  • Architectures: Neural ODE (default), Transformer, TCN, Ensemble

Versioning

Pre-1.0 we follow SemVer pragmatically: breaking changes land only in minor releases, are flagged in CHANGELOG.md, and deprecated aliases are kept for one minor release. **All checkpoints from versions ≤ 0.3.x are invalid**: those versions contained a defect that made predictions independent of the input data; see the engineering history in docs/METHODOLOGY.md.

Have degradation or depletion data?

Run the audit yourself: python experiments/auditpredictwhen.py benchmarks predict_when against persistence, linear extrapolation, and seasonal baselines on your data. If APDTFlow wins, open a PR and we will feature your domain with your numbers. That pipeline is how every result on this page was produced, including the ideas we tested and rejected (docs/METHODOLOGY.md).

Articles

*Both articles cover earlier versions; the core ideas still apply, but the API has grown since (predictat, predictwhen, fleet scheduling) and v0.4.0 fixed a critical model defect; see the CHANGELOG before following old code snippets.*

Citation

If APDTFlow is useful in your research, please cite it:

@software{apdtflow,
  author = {Braun, Yotam},
  title  = {APDTFlow: continuous-time forecasting with Neural ODEs},
  url    = {https://github.com/yotambraun/APDTFlow},
  year   = {2026},
  version = {0.4.0}
}

More

Methodology & references · Benchmarks · Model architectures · Documentation · Examples · Quickstart notebook · Contributing

License

MIT

🔗 More in this category

© 2026 GitRepoTrend · yotambraun/APDTFlow · Updated daily from GitHub