Skip to main content

Paper-aligned AMI and extension pAMI diagnostics for forecastability triage

Project description

Forecastability Triage Toolkit

A deterministic pre-model triage toolkit for time series. Assess whether dependence is strong, direct, and exploitable before costly model search.

CI Version Docs Python 3.11-3.12 Based on arXiv:2601.10006

Install

pip install dependence-forecastability

With optional extras:

pip install "dependence-forecastability[transport]"   # FastAPI, MCP transport
pip install "dependence-forecastability[agent]"       # PydanticAI narration

Minimal example

import numpy as np
from forecastability.triage import run_triage, TriageRequest

rng = np.random.default_rng(42)
ts = rng.standard_normal(300)

result = run_triage(TriageRequest(series=ts, goal="univariate", random_state=42))
print(result.interpretation.forecastability_class)
print(result.recommendation)

Stability

Surface Status
Core deterministic triage (run_triage, run_batch_triage, analyzers, scorers) Stable
CLI (forecastability triage) Beta
HTTP API (FastAPI + SSE) Beta
Dashboard Optional
Agent layer (PydanticAI) Experimental
MCP server Experimental

What it does

Built on AMI (Catt 2026) as the paper-aligned foundation, extended with pAMI and nine diagnostic families drawn from multiple papers — forecastability profiles, information-theoretic ceilings, predictive-information learning curves, spectral predictability, Lyapunov stability, entropy-based complexity, batch multi-signal ranking, and exogenous screening — all behind a single run_triage() / run_batch_triage() entry point.

[!NOTE] AMI is the paper-aligned core. pAMI and all F1–F9 diagnostics are project extensions. See docs/wording_policy.md for the canonical product description.

Quickstart ladder (recommended)

Start with one deterministic signal and move from CLI to notebook, Python API, HTTP API, then optional agent/MCP surfaces:

Who this is for

  • Forecasting practitioners who need a pre-model diagnostic for lag usefulness.
  • Data scientists comparing direct vs mediated dependence across horizons.
  • Teams building production triage flows (CLI, API, or notebooks) around deterministic metrics.

Fastest quickstart (repo / contributor path)

uv sync && MPLBACKEND=Agg uv run python scripts/run_canonical_examples.py

What result you get

  • Canonical AMI and pAMI JSON outputs in outputs/json/canonical/.
  • Canonical diagnostic figures in outputs/figures/canonical/.
  • Deterministic A-E pattern classification plus lag recommendations per series.

Where to go next

Visual architecture summary

flowchart TD
    subgraph Adapters
        CLI["CLI"]
        API["FastAPI + SSE"]
        MCP["MCP Server"]
        Agent["PydanticAI Agent + Payload Adapters"]
    end
    subgraph Ports["Ports (9 Protocols)"]
        P["Validator · CurveCompute · Significance · Interpretation · Recommendation · ReportRenderer · Settings · EventEmitter · Checkpoint"]
    end
    subgraph UseCases["Use Cases"]
        UC1["run_triage() · run_batch_triage()"]
        UC2["Rolling-Origin Evaluation"]
    end
    subgraph Services["Diagnostic Services"]
        S1["Profile · IT Limits · Learning Curves"]
        S2["Spectral · Complexity Band · Lyapunov"]
    end
    subgraph Triage["Triage Sub-domain"]
        T1["Readiness Gate · Method Router"]
        T2["F1–F6 Diagnostic Models"]
        T3["Batch Ranking · Events · Result Bundle"]
    end
    subgraph Domain
        D1["metrics · validation · interpretation"]
        D2["surrogates · scorers · spectral_utils · config · types"]
    end

    Adapters --> Ports
    Ports --> UseCases
    UseCases --> Services
    Services --> Triage
    UseCases --> Triage
    Triage --> Domain

The package follows hexagonal (ports-and-adapters) architecture. Domain code has no dependency on adapters; adapters wire concrete implementations at the edge.

Common use cases

  • Signal triage — classify whether a series is likely forecastable at useful horizons.
  • Lookback / horizon screening — identify lag ranges where AMI and pAMI remain informative.
  • Forecastability profiling — compute the horizon-wise $h \to F(h)$ profile, peak horizon, and informative horizon set (F1).
  • Compression / ceiling detection — check whether theoretical MI limits are violated or nearly saturated (F2).
  • Lookback selection — use predictive-information learning curves to pick optimal embedding dimension (F3).
  • Spectral vs MI divergence — compare spectral predictability $\Omega$ with AMI to flag nonlinearity (F4).
  • Complexity screening — classify signals into low / medium / high complexity bands via permutation + spectral entropy (F6).
  • Batch diagnostic ranking — rank 50+ signals on all diagnostics in one call (F7).
  • Exogenous driver screening — rank candidate external drivers with CrossAMI/pCrossAMI plus FDR correction (F8).
  • Industrial / PdM context — prioritize sensors or telemetry channels before full model pipelines.

Versioning and stability

See the Stability table above. Full release history: CHANGELOG.md. Versioning policy: docs/versioning.md.

Production readiness

What this project adds beyond the paper

The original paper validates AMI as a frequency-conditional triage signal for model selection. This project adds diagnostics drawn from multiple papers and infrastructure the original paper does not provide:

Extension What it adds Paper basis
pAMI (partial AMI) Separates direct lag links from mediated lag chains via linear residualisation Project extension
directness_ratio AUC(pAMI) / AUC(AMI) — how much total dependence remains direct Project extension
F1 — Forecastability Profile Horizon-wise $h \to F(h)$ curve, peak horizon, informative horizon set, non-monotonicity detection Catt (2026), arXiv:2603.27074
F2 — IT Limit Diagnostics Theoretical MI ceiling under log loss, compression / DPI warnings Catt (2026), arXiv:2603.27074
F3 — Predictive Info Learning Curves EvoRate-inspired lookback analysis via kNN MI in embedding dim $k$, plateau detection, recommended lookback Morawski et al. (2025), arXiv:2510.10744
F4 — Spectral Predictability Welch PSD → spectral entropy → normalised predictability $\Omega$; divergence with AMI signals nonlinearity Wang et al. (2025), arXiv:2507.13556
F5 — Largest Lyapunov Exponent Experimental Rosenstein LLE via delay embedding; gated behind experimental: true Wang et al. (2025), arXiv:2507.13556
F6 — Entropy-Based Complexity Permutation entropy + spectral entropy → complexity band (low / medium / high) Ponce-Flores et al. (2020); Bandt & Pompe (2002)
F7 — Batch Multi-Signal Ranking run_batch_triage() with all diagnostics; handles 50+ signals Project extension
F8 — Enhanced Exogenous Screening Inter-driver redundancy penalty + Benjamini-Hochberg FDR correction Project extension
F9 — Benchmark & Reproducibility Full diagnostic regression fixtures for F1–F6, batch and exogenous regression, rebuild / verify scripts Project extension
Exogenous analysis ForecastabilityAnalyzerExog — CrossAMI + pCrossAMI between target and driver series Project extension
Scorer registry MI, Pearson, Spearman, Kendall, dCor — extensible via DependenceScorer protocol Project extension
Triage pipeline run_triage() — readiness gate → method routing → compute → interpretation → recommendation Project extension
Agent adapters Structured Pydantic payloads for all diagnostics (triage_agent_payload_models, triage_summary_serializer, triage_agent_interpretation_adapter) Project extension
Agentic interpretation PydanticAI agent narrates deterministic numeric results — never invents numbers Project extension
MCP server Model Context Protocol integration for IDE-integrated assistants Project extension
CLI forecastability triage, forecastability list-scorers Project extension
HTTP API FastAPI endpoints + SSE streaming for stage progress Project extension
Pattern classification Deterministic A–E modeling regime assignment Project extension

[!IMPORTANT] All extensions are clearly separated from the paper baseline. Domain code follows hexagonal architecture — adapters (CLI, API, MCP, Agent) never leak into core forecastability logic.

Features

Feature Description
AMI curves Horizon-specific mutual information with kNN estimator
pAMI curves Partial AMI via linear residualisation — direct lag links
Surrogate significance Phase-randomised FFT surrogates ($n \ge 99$) with 95% bands
Directness ratio AUC(pAMI) / AUC(AMI) — how much dependence is direct
Forecastability profile (F1) Horizon-wise $h \to F(h)$ profile, peak horizon, informative horizon set, non-monotonicity flag
IT limit diagnostics (F2) Theoretical MI ceiling, compression / DPI warnings, exploitation ratio
Predictive info learning curves (F3) kNN MI vs embedding dim $k$, plateau detection, recommended lookback, small-$n$ warnings
Spectral predictability (F4) Welch PSD → spectral entropy → normalised predictability $\Omega$
Largest Lyapunov exponent (F5) Experimental Rosenstein LLE via delay embedding (gated: experimental: true)
Entropy-based complexity (F6) Permutation entropy + spectral entropy → complexity band (low / medium / high)
Batch multi-signal ranking (F7) run_batch_triage() with all diagnostic columns; handles 50+ signals
Exogenous screening (F8) CrossAMI + pCrossAMI with redundancy penalty and Benjamini-Hochberg FDR correction
Benchmark & reproducibility (F9) Diagnostic regression fixtures for F1–F6, rebuild and verify scripts
Exogenous analysis CrossAMI + pCrossAMI between target and driver series
Scorer registry 5 built-in scorers (MI, Pearson, Spearman, Kendall, dCor); extensible via DependenceScorer protocol
Triage pipeline run_triage() — readiness → routing → compute → interpretation
Pattern classification Deterministic A–E modeling regime assignment
Rolling-origin evaluation Expanding-window backtest with train-only diagnostics
Agent adapters Structured Pydantic payloads for all diagnostics (payload models, serializer, interpretation adapter)
Agentic interpretation PydanticAI agent that narrates deterministic results (optional agent extra)
CLI forecastability triage, forecastability list-scorers
HTTP API FastAPI endpoints + SSE streaming (transport extra)
MCP server Model Context Protocol tools for IDE-integrated assistants (transport extra)

Core workflow

flowchart LR
    A[Series input] --> B[Validation and stationarity checks]
    B --> C[Compute AMI per horizon]
    B --> D[Compute pAMI per horizon]
    C --> E[Surrogate upper band]
    D --> F[Directness summary]
    E --> G[Interpretation patterns]
    F --> G
    G --> H[Modeling regime recommendation]

Quality and invariants

Project invariants:

  • AMI/pAMI are horizon-specific.
  • Rolling-origin diagnostics are train-window only.
  • Surrogate runs require n_surrogates >= 99.
  • Integrals use np.trapezoid (not np.trapz).
  • directness_ratio > 1.0 is treated as an ARCH/estimation warning, not direct evidence.

Installation matrix

Profile PyPI install Repo / dev install Includes
Core pip install dependence-forecastability uv sync Base package dependencies
Transport pip install "dependence-forecastability[transport]" uv sync --extra transport FastAPI, Uvicorn, and MCP transport adapters
Agent pip install "dependence-forecastability[agent]" uv sync --extra agent PydanticAI narration adapter
Dev uv sync --group dev Test, lint, and type-check toolchain
Notebook (optional) uv sync --group notebook Jupyter and notebook execution tooling

Python compatibility notes:

  • Project metadata declares requires-python = ">=3.11,<3.13".
  • Use Python 3.11 or 3.12 for supported installs.
  • Python 3.13+ is intentionally excluded until compatibility is validated.

Run

uv sync
uv run pytest -q -ra
uv run ruff check .
uv run ty check

Agent quickstart

The agentic triage layer wraps the deterministic run_triage() pipeline with an LLM adapter that explains results in plain language. All numbers come from deterministic tools — the agent never invents numeric values.

Prerequisites

pip install "dependence-forecastability[agent]"  # PyPI
# or, in the repo: uv sync --extra agent

Configure in .env (see .env.example):

OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4o            # or gpt-4o-mini, gpt-4.1, etc.

Minimal usage (deterministic only — no LLM)

import numpy as np
from forecastability.triage import run_triage, TriageRequest

rng = np.random.default_rng(42)
ts = np.array([0.85 ** i + rng.standard_normal() * 0.1 for i in range(300)])

result = run_triage(TriageRequest(series=ts, goal="univariate", random_state=42))
print(result.interpretation.forecastability_class)  # "high"
print(result.recommendation)

With LLM explanation (requires agent extra)

import asyncio
import numpy as np
from forecastability.adapters.pydantic_ai_agent import run_triage_agent

async def main():
    rng = np.random.default_rng(42)
    ts = np.array([0.85 ** i + rng.standard_normal() * 0.1 for i in range(300)])
    explanation = await run_triage_agent(ts, max_lag=30, random_state=42)
    print(explanation.narrative)
    print(explanation.caveats)

asyncio.run(main())

Provider selection

The agent defaults to the model configured in OPENAI_MODEL (settings layer). Override per call:

from forecastability.adapters.pydantic_ai_agent import create_triage_agent
agent = create_triage_agent(model="openai:gpt-4o-mini")

Any PydanticAI-compatible provider string works (e.g. "anthropic:claude-3-5-sonnet-latest").

[!IMPORTANT] The agent only narrates deterministic results. It does not generate numeric values. TriageResult.narrative is always None for plain run_triage() calls.

See notebooks/walkthroughs/03_triage_end_to_end.ipynb for a full interactive walkthrough.

Interactive Notebooks

Install extras and register the kernel once:

uv sync --group notebook
uv run python -m ipykernel install --user --name forecastability

Notebook taxonomy is frozen to exactly two long-lived families:

  • notebooks/walkthroughs/ — curated end-to-end user and maintainer surfaces.
  • notebooks/triage/ — deterministic deep dives for specific diagnostic methods.

Ownership and architecture discipline:

  • Notebooks are consumer and demonstrator surfaces, not runtime implementation surfaces.
  • Runtime logic must live in src/forecastability/ and follow hexagonal boundaries (adapters -> use_cases -> domain) with SOLID responsibilities.
  • Notebook cells may orchestrate examples and visual explanations, but they must not become authoritative runtime paths.

Deprecation policy for root-level notebooks:

  • No new long-lived notebooks may be added under notebooks/ root.
  • Root-level notebook files are redirect shims pointing to the corresponding notebooks/walkthroughs/ notebooks.

Notebook taxonomy (final):

Surface Path(s) Role
Long-lived family notebooks/triage/ Deterministic deep-dive track (active).
Long-lived family notebooks/walkthroughs/ Curated walkthrough track (active).

Durable narrative pages for walkthrough surfaces:

Documentation map

Full documentation index: docs/README.md

Area Key Documents
Executive overview docs/executive_summary.md
Architecture docs/architecture.md
Theory — foundations docs/theory/foundations.md · docs/theory/interpretation_patterns.md · docs/theory/pami_residual_backends.md
Theory — triage diagnostics docs/theory/forecastability_profile.md · docs/theory/spectral_predictability.md · docs/theory/entropy_based_complexity.md
Triage methods docs/triage_methods/predictive_information_learning_curves.md · docs/triage_methods/largest_lyapunov_exponent.md
Code reference docs/code/module_map.md · docs/code/exog_analyzer.md
Examples examples/triage/ — 12 standalone scripts covering F1–F8 features and agent adapter demos
Planning docs/plan/README.md · docs/plan/acceptance_criteria.md
Archive docs/archive/ (27 historical build-phase documents)

Paper baseline (what we are based on)

Primary paper (AMI triage signal)

  • Peter Maurice Catt, The Knowable Future: Mapping the Decay of Past-Future Mutual Information Across Forecast Horizons, arXiv:2601.10006 (January 2026; v3 February 2026)

Paper setup reproduced here:

  • M4 frequencies: Yearly, Quarterly, Monthly, Weekly, Daily, Hourly
  • Horizon caps by frequency (paper Section 3.1): 6, 8, 18, 13, 14, 48 respectively
  • Rolling-origin protocol with train-only diagnostics and post-origin forecast scoring
  • Surrogate significance logic with $n_{\text{surrogates}} \ge 99$ and 95% bands

Paper finding used as anchor:

  • AMI is a frequency-conditional triage signal for model selection.
  • Strongest negative AMI-sMAPE rank association appears in higher-information regimes (Hourly/Weekly/Quarterly/Yearly), weaker for Daily and moderate for Monthly.

Extended paper references (triage diagnostics F1–F6)

Feature Paper Reference
F1 — Forecastability Profile Catt (2026) arXiv:2603.27074
F2 — IT Limit Diagnostics Catt (2026) arXiv:2603.27074
F3 — Predictive Info Learning Curves Morawski et al. (2025) arXiv:2510.10744
F4 — Spectral Predictability Wang et al. (2025) arXiv:2507.13556
F5 — Largest Lyapunov Exponent Wang et al. (2025) arXiv:2507.13556
F6 — Entropy-Based Complexity Ponce-Flores et al. (2020); Bandt & Pompe (2002)
F7 — Batch Ranking Goerg (2013) — ForeCA inspiration

Time-series applicability (paper + implementation)

From the paper:

  • Very short, sparse, or degenerate series can make MI estimates unstable.
  • Hourly/Weekly/Quarterly/Yearly showed clearer AMI-error discrimination than Daily.
  • Frequency-specific horizon caps are required to avoid infeasible or noisy long-horizon evaluation.

From this implementation:

AMI minimum length constraint:

  • ( N \ge \max(\texttt{max_lag} + \texttt{min_pairs_ami} + 1, 30) )

pAMI minimum length constraint (linear residual backend):

  • ( N \ge \max(\texttt{max_lag} + \texttt{min_pairs_pami} + 1, 2, \texttt{max_lag}) )

Defaults (max_lag=100, min_pairs_ami=30, min_pairs_pami=50) imply:

  • AMI: ( N \ge 131 )
  • pAMI: ( N \ge 201 )

Operational guidance:

  • Use series with at least 200–300 observations for reliable results.
  • For very short series (< 150 points), consider downsampling or frequency aggregation first.
  • Always validate minimum length before calling run_triage().

Extension disclosure

AMI is paper-native (arXiv:2601.10006). The following are project extensions not present in the original paper:

  • pAMI, exogenous cross-dependence (CrossAMI / pCrossAMI), scorer-registry generalisation
  • F1–F2 (forecastability profile, IT limits) — based on arXiv:2603.27074
  • F3 (predictive info learning curves) — based on arXiv:2510.10744
  • F4–F5 (spectral predictability, Lyapunov exponent) — based on arXiv:2507.13556
  • F6 (entropy-based complexity) — based on Ponce-Flores et al. (2020) and Bandt & Pompe (2002)
  • F7 (batch multi-signal ranking), F8 (enhanced exogenous screening), F9 (benchmark & reproducibility)
  • Deterministic triage pipeline (run_triage(), run_batch_triage())
  • Agent adapters (payload models, summary serialiser, interpretation adapter)
  • Agentic interpretation layer (PydanticAI), CLI, HTTP API (FastAPI + SSE), MCP server

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

dependence_forecastability-0.1.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

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

dependence_forecastability-0.1.0-py3-none-any.whl (184.2 kB view details)

Uploaded Python 3

File details

Details for the file dependence_forecastability-0.1.0.tar.gz.

File metadata

File hashes

Hashes for dependence_forecastability-0.1.0.tar.gz
Algorithm Hash digest
SHA256 717aa25d42ebc3de53d9ce6afa9f2bab470cded9923eb00909363e5eb4bb3e48
MD5 7bd32f4e9e881e3edc071ad416a666f9
BLAKE2b-256 6bb15039a0416edc30e3f7e1cdb38352d0c7fea0d9ccf57d2377dd7cea043990

See more details on using hashes here.

Provenance

The following attestation bundles were made for dependence_forecastability-0.1.0.tar.gz:

Publisher: publish-pypi.yml on AdamKrysztopa/dependence-forecastability

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

File details

Details for the file dependence_forecastability-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for dependence_forecastability-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fcaf619e8195253ed4d22f39955079fea7df896e0fbdfffd3221406f76d48e76
MD5 74fc1e064e8dc213605f8633262436b6
BLAKE2b-256 1fd4b9a47dbf0ab3aaf4917e8ef865564fb396b7b6a18bbc2fa1caf17e8ce4fc

See more details on using hashes here.

Provenance

The following attestation bundles were made for dependence_forecastability-0.1.0-py3-none-any.whl:

Publisher: publish-pypi.yml on AdamKrysztopa/dependence-forecastability

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