Skip to main content

Bayesian time-series forecasting with PyMC: train/forecast plumbing, backtesting, and metrics.

Project description

pymc_forecast

CI Docs

Bayesian time-series forecasting with PyMC: you write the generative model; the package handles the train/forecast plumbing, inference, backtesting, and evaluation.

A PyMC port of numpyro_forecast (itself a port of Pyro's pyro.contrib.forecast) — redesigned around PyMC idioms rather than a 1:1 translation.

Status: early development. The design and roadmap live in PLAN.md and the issue tracker.

Documentation: https://pymc-labs.github.io/pymc_forecast/ — API reference and executed example notebooks (univariate, hierarchical, covariates, state-space).

Quickstart

Write a model with one predict() call, fit it, and forecast:

import numpy as np, pandas as pd, pymc as pm, pytensor.tensor as pt
from pymc_forecast import Forecaster, backtest, evaluate_forecast, predict, time_series

# a trending weekly series; hold out the last 8 weeks
dates = pd.date_range("2024-01-07", periods=60, freq="W")
y = pd.Series(np.cumsum(np.random.default_rng(0).normal(0.2, 1.0, 60)) + 10, index=dates)
train, test = y.iloc[:52], y.iloc[52:]

def model(h, covariates):
    # a per-step drift latent; time_series adds the matching `_future` latent
    drift = time_series(h, "drift", lambda name, dims: pm.Normal(name, 0.0, 0.5, dims=dims))
    sigma = pm.HalfNormal("sigma", 1.0)
    predict(
        h,
        lambda name, mu, dims, obs: pm.Normal(name, mu, sigma, dims=dims, observed=obs),
        pt.cumsum(drift),                       # local-linear trend
    )

fc = Forecaster(model, train, num_steps=5_000, random_seed=0)   # ADVI
idata = fc.forecast(horizon=8, num_samples=500, random_seed=0)
forecast = idata["predictions"]["forecast"]     # dims: (chain, draw, time_future)

# score against the held-out weeks (aligned by dim name, not axis position)
truth = test.to_xarray().rename({"index": "time_future"})
print(evaluate_forecast(forecast, truth))       # {'mae': ..., 'rmse': ..., 'crps': ..., 'coverage': ...}

# rolling-origin backtest over the whole series
results = backtest(y, None, model, min_train_window=48, test_window=4, stride=4,
                   num_samples=200, forecaster_options={"num_steps": 3_000}, random_seed=0)

Swap Forecaster for HMCForecaster (NUTS, with nuts_sampler="nutpie"/"numpyro"/...) or PathfinderForecaster (pymc-extras) — the fit/forecast interface is identical. For models with real covariates, pass full-horizon covariates to .forecast() instead of horizon=. See markov_time_series for state-space latents and predict_mvn for observation noise correlated across time.

pymc-extras statespace structural models (level/trend, seasonality, SARIMAX, ...) are first-class citizens too: define one as a StatespaceModel and fit it with StatespaceForecaster — the same forecast (including exogenous-regression covariates), predict_in_sample, backtest, and metrics calls apply, with the Kalman filter marginalizing the latent states instead of sampling them (see docs/examples/scan_vs_statespace_local_level.ipynb). The pymc-extras integrations (PathfinderForecaster, StatespaceForecaster) are an optional extra: install with pip install 'pymc-forecast[extras]'.

Design principles

  • One model trains and forecasts. In-sample time latents are fitted; the forecast horizon uses separate {name}_future variables that pm.sample_posterior_predictive draws from the prior while replaying the posterior for everything else.
  • Dims and coords everywhere. No positional axis conventions: variables carry named dims ("time", "time_future", "obs", batch dims), results are arviz.InferenceData / xarray objects with real coordinates, and metrics are dim-aware.
  • Not AutoML. No model zoo, no automatic feature pipelines — a clean path from a hand-written PyMC model to probabilistic forecasts and scores.
  • Leverage the ecosystem. ADVI/NUTS from PyMC core, Pathfinder and state-space models from pymc-extras, diagnostics and storage from ArviZ.

Development

Requires Python >= 3.11 and uv:

uv sync --all-extras
uv run pytest
uv run ruff check .

To build the documentation (the example notebooks are committed fully executed; CI re-executes them with reduced sampling settings):

uv sync --all-extras --group docs
uv run sphinx-build -b html docs docs/_build/html

License

Apache-2.0. Portions derived from numpyro_forecast (Apache-2.0).

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

pymc_forecast-0.0.1.tar.gz (60.0 kB view details)

Uploaded Source

Built Distribution

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

pymc_forecast-0.0.1-py3-none-any.whl (48.6 kB view details)

Uploaded Python 3

File details

Details for the file pymc_forecast-0.0.1.tar.gz.

File metadata

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

File hashes

Hashes for pymc_forecast-0.0.1.tar.gz
Algorithm Hash digest
SHA256 a8328489f7b2f4a95d46079fa2d5e04b10b3854fcc91509c4b7c6848e65ab3ac
MD5 b601c38741bc21adc0f48678e01cc447
BLAKE2b-256 a8c152cb69ea1302077dac46e39310f535fe99398d6d13becd8765fbc517ee9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymc_forecast-0.0.1.tar.gz:

Publisher: release.yml on pymc-labs/pymc_forecast

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

File details

Details for the file pymc_forecast-0.0.1-py3-none-any.whl.

File metadata

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

File hashes

Hashes for pymc_forecast-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 adaa406daaec23a57ea33de9c42fcc9dfd97e54ffa5429b190340903af5dcdb2
MD5 ae22ee0f52cb06a2ca00dfbaba5ce5da
BLAKE2b-256 aeec7caa68901e3bc8360faff6760a8c2b9c6f039a82dd302ae5eb2439528c27

See more details on using hashes here.

Provenance

The following attestation bundles were made for pymc_forecast-0.0.1-py3-none-any.whl:

Publisher: release.yml on pymc-labs/pymc_forecast

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