Forecastability triage for time series using AMI, pAMI, and covariate-aware dependence diagnostics before expensive model search.
Project description
Forecastability Triage Toolkit
Forecastability triage for time series before expensive model search.
dependence-forecastability is a Python toolkit for answering the question that
should come before model selection:
Does this time series contain exploitable structure, and what should a forecasting model be allowed to use?
It is not another forecasting library.
It is a deterministic pre-modeling layer that helps you inspect readiness,
informative horizons, target lags, seasonality structure, covariate usefulness,
leakage risk, and model-family direction before you spend time on Darts,
MLForecast, StatsForecast, Nixtla, sklearn, Prophet, or custom models.
Why this exists
Many forecasting projects start too late:
data → model search → tuning → more features → more compute → still poor results
This package encourages a different workflow:
data
→ forecastability triage
→ lag / driver / readiness diagnostics
→ ForecastPrepContract
→ downstream model search
The goal is to avoid blind model iteration by asking practical questions first:
- Is the target series forecastable at all?
- Which horizons contain useful information?
- Which target lags are informative?
- Is there a seasonal structure worth modeling?
- Are exogenous drivers predictive, merely contemporaneous, or useless?
- Which variables are safe to use without leakage?
- Which model families are plausible enough to test next?
- When should the workflow abstain and fall back to baselines?
Install
pip install dependence-forecastability
# or with uv
uv add dependence-forecastability
Optional extras:
# Causal screening methods such as PCMCI / PCMCI-AMI
pip install "dependence-forecastability[causal]"
# HTTP API, dashboard, and transport surfaces
pip install "dependence-forecastability[transport]"
# Agent-facing narration surfaces
pip install "dependence-forecastability[agent]"
# Holiday calendar features in ForecastPrepContract
pip install "dependence-forecastability[calendar]"
Supported Python versions:
Python 3.11, 3.12
Quickstart
Run deterministic univariate triage:
from forecastability import TriageRequest, generate_ar1, run_triage
series = generate_ar1(n_samples=300, phi=0.8, random_state=42)
result = run_triage(
TriageRequest(
series=series,
goal="univariate",
max_lag=20,
n_surrogates=99,
random_state=42,
)
)
summary = {
"blocked": result.blocked,
"readiness_status": result.readiness.status.value,
"forecastability_class": (
None
if result.interpretation is None
else result.interpretation.forecastability_class
),
"primary_lags": (
[]
if result.interpretation is None
else list(result.interpretation.primary_lags)
),
}
print(summary)
Minimal runnable files:
What you get
| Output | Why it matters |
|---|---|
| Readiness report | Detects cases where triage should be blocked or interpreted cautiously |
| Informative horizons | Shows where the target contains usable lag information |
| Primary lags | Suggests target lags for downstream modeling |
| Forecastability class | Gives a deterministic high / medium / low style interpretation |
| Seasonality hints | Helps separate short-memory and seasonal structure |
| Covariate informativeness | Screens whether exogenous drivers add signal |
| Lagged-exogenous map | Selects sparse predictive driver lags |
| Routing recommendation | Suggests model-family direction before model search |
| ForecastPrepContract | Exports machine-readable downstream guidance |
What this is not
This package does not replace downstream forecasting libraries.
It does not try to be:
- Darts
- MLForecast
- StatsForecast
- Nixtla
- Prophet
- sklearn
- statsmodels
- a full AutoML system
- a causal-discovery guarantee
- a model-training library
Instead, it sits one step earlier:
forecastability triage → model-family choice → framework-specific modeling
Downstream frameworks are consumers of triage results, not competitors.
Core capabilities
1. Univariate forecastability triage
Use this when you want to know whether the target series itself carries useful predictive structure.
Typical questions:
- Does the target have informative lags?
- Is the signal closer to noise, short-memory, seasonal, or structured?
- Which lags should be considered before creating features?
- Should the downstream process abstain or start from simple baselines?
Entry points:
from forecastability import TriageRequest, run_triage
Relevant docs:
2. Extended forecastability analysis
Use this when you want the implemented AMI-first extended fingerprint plus a deterministic routing summary in one additive result.
Entry points:
from forecastability import TriageRequest, run_extended_forecastability_analysis, run_triage
Direct use case:
result = run_extended_forecastability_analysis(series, max_lag=24, period=12)
print(result.profile.predictability_sources)
print(result.routing_metadata["descriptive_only"])
CLI equivalent:
forecastability extended --csv data.csv --col value --max-lag 24 --period 12 --format brief
Operational notes:
- AMI geometry stays first. If it is disabled or unavailable, the profile remains descriptive-only and does not emit routing-grade family recommendations.
run_triage(..., include_extended_fingerprint=True)additively attachesextended_forecastability_analysisfor non-exogenous routes only. Exogenous requests leave the field omitted rather than pretending exogenous-aware extended analysis exists.- The surface suggests starting model families only; it does not fit models or wire downstream frameworks.
Relevant docs:
docs/how-to/extended_forecastability_fingerprint.mddocs/explanation/extended_forecastability_profile.mddocs/public_api.md
3. Forecastability fingerprint
The fingerprint surface summarizes AMI-first information geometry into compact diagnostic features and deterministic model-family routing hints.
Use it when you want a quick structural profile of a series:
from forecastability import (
generate_fingerprint_archetypes,
run_forecastability_fingerprint,
)
series = generate_fingerprint_archetypes(n=320, seed=42)["seasonal_periodic"]
bundle = run_forecastability_fingerprint(
series,
target_name="seasonal_periodic",
max_lag=24,
n_surrogates=99,
random_state=42,
)
print(bundle.recommendation.primary_families)
Run the smoke showcase:
MPLBACKEND=Agg uv run scripts/run_showcase_fingerprint.py --smoke
Relevant files:
scripts/run_showcase_fingerprint.pydocs/theory/forecastability_fingerprint.mddocs/code/fingerprint_showcase.md
4. Lagged-exogenous triage
Use this when you have candidate drivers and need to decide whether they are actually useful for forecasting.
The lagged-exogenous surface classifies drivers by lag role and emits a sparse lag map that can be used for downstream tensor construction.
from forecastability import generate_lagged_exog_panel, run_lagged_exogenous_triage
df = generate_lagged_exog_panel(n=1500, seed=42)
target = df["target"].to_numpy()
drivers = {name: df[name].to_numpy() for name in df.columns if name != "target"}
bundle = run_lagged_exogenous_triage(
target,
drivers,
target_name="target",
max_lag=6,
n_surrogates=99,
random_state=42,
)
for row in bundle.selected_lags:
if row.selected_for_tensor:
print(f"{row.driver} @ lag={row.lag} tensor_role={row.tensor_role}")
Run the smoke showcase:
MPLBACKEND=Agg uv run scripts/run_showcase_lagged_exogenous.py --smoke
Relevant files:
[!IMPORTANT]
selected_for_tensor=Trueis impossible atlag=0by default. Useknown_future_driversonly for variables whose contemporaneous future values are genuinely known at prediction time, such as calendar flags, planned promotions, or externally scheduled variables.
5. Lag-Aware ModMRMR sparse covariate-lag selection
Use this when you need a forecast-safe sparse covariate-lag selector before the
framework-neutral ForecastPrepContract hand-off.
run_lag_aware_mod_mrmr() blocks illegal measured lags, preserves declared
known-future covariates with provenance, and returns selected, rejected, and
blocked rows with scorer diagnostics.
from forecastability import (
LagAwareModMRMRConfig,
PairwiseScorerSpec,
run_lag_aware_mod_mrmr,
)
Run the smoke showcases:
MPLBACKEND=Agg uv run scripts/run_showcase_lag_aware_mod_mrmr.py --smoke
MPLBACKEND=Agg uv run scripts/run_showcase_lag_aware_catt_mod_mrmr.py --smoke
Relevant files:
scripts/run_showcase_lag_aware_mod_mrmr.pyscripts/run_showcase_lag_aware_catt_mod_mrmr.pydocs/theory/lag_aware_mod_mrmr.mddocs/code/lag_aware_mod_mrmr.mddocs/recipes/forecast_prep_to_external_frameworks.md
6. Covariant / exogenous analysis
Use this when you want to screen whether another series contains information about the target.
Supported method names include:
cross_amicross_pamitegcmipcmcipcmci_ami
The PCMCI methods require the optional causal extra:
pip install "dependence-forecastability[causal]"
[!NOTE] The causal methods are optional screening tools. They should not be interpreted as a complete causal proof.
7. Routing validation
Routing validation audits deterministic routing against controlled archetypes and sanity panels.
It does not train or benchmark forecasting models.
It checks whether the routing policy emits defensible family-level guidance
before a downstream framework hand-off.
Run the smoke path:
uv run python scripts/run_routing_validation_report.py --smoke --no-real-panel
Relevant files:
docs/theory/routing_validation.mdoutputs/reports/routing_validation/report.mdexamples/univariate/agents/routing_validation_agent_review.py
ForecastPrepContract
ForecastPrepContract is the framework-neutral hand-off boundary between
forecastability diagnostics and downstream model configuration.
It converts diagnostic outputs into a machine-readable object containing:
- recommended target lags,
- seasonal lag hints,
- past covariates,
- known-future covariates,
- calendar features,
- rejected covariates,
- model-family recommendations,
- baseline families,
- confidence labels,
- caution flags,
- downstream notes.
Example:
from forecastability import (
build_forecast_prep_contract,
forecast_prep_contract_to_lag_table,
forecast_prep_contract_to_markdown,
)
bundle = build_forecast_prep_contract(
triage_result,
horizon=12,
target_frequency="MS",
add_calendar_features=True,
)
contract = bundle.contract
print(contract.model_dump_json(indent=2))
print(forecast_prep_contract_to_markdown(contract))
lag_rows = forecast_prep_contract_to_lag_table(contract)
for row in lag_rows:
print(row)
Relevant docs:
[!IMPORTANT] The contract is not a model trainer. It gives structured, evidence-backed guidance that users can translate into framework-specific configuration.
Downstream framework hand-off
The core package intentionally does not import Darts, MLForecast, StatsForecast, Nixtla, or similar downstream libraries.
Instead, the recommended workflow is:
run triage
→ build ForecastPrepContract
→ translate contract into framework-specific settings
→ train and compare models outside the core package
Illustrative mappings are documented in:
Executable notebooks live in the sibling examples repository:
forecastability-exampleswalkthroughs/05_forecast_prep_to_models.ipynbrecipes/contract_roundtrip.ipynb
Hero example: CausalRivers lag and feature selection
The strongest practical demo is the CausalRivers notebook in the sibling examples repository:
This notebook demonstrates deterministic lag and feature selection on the CausalRivers benchmark.
The intended story is simple:
target river station
→ candidate upstream positives
→ unrelated negative controls
→ lag / feature triage
→ selected drivers and lags
→ downstream forecast-prep guidance
Use this example when you want to show that forecastability triage is not only a toy Air Passengers workflow. It can be used as a practical pre-modeling screening layer on graph-structured, real-world time series.
Core repo surfaces related to this workflow:
Examples and notebooks
From v0.4.0, walkthrough notebooks live in the sibling repository:
The core package remains library-first and framework-agnostic.
The examples repository contains tutorial notebooks, framework hand-offs, and
benchmark-style demonstrations.
Important notebooks:
| Notebook | Purpose |
|---|---|
00_air_passengers_showcase.ipynb |
Simple canonical forecastability triage |
02_forecastability_fingerprint_showcase.ipynb |
Forecastability fingerprint surface |
03_lagged_exogenous_triage_showcase.ipynb |
Sparse lagged-exogenous selection |
05_forecast_prep_to_models.ipynb |
Contract hand-off to Darts / MLForecast / sklearn |
06_triage_driven_vs_naive_on_m4.ipynb |
Triage-driven model-family selection on M4 monthly subset |
07_causal_rivers_lag_and_feature_selection.ipynb |
CausalRivers lag and feature selection demo |
Full index:
Start here
| User type | Start with |
|---|---|
| Python user | examples/minimal_python.py, then docs/public_api.md |
| CLI user | examples/minimal_cli.sh, then docs/quickstart.md |
| Notebook user | forecastability-examples |
| ForecastPrepContract user | docs/reference/forecast_prep_contract.md |
| Downstream framework user | docs/recipes/forecast_prep_to_external_frameworks.md |
| CausalRivers user | walkthroughs/07_causal_rivers_lag_and_feature_selection.ipynb |
| Contributor | docs/maintenance/developer_guide.md |
| Coding agent / LLM | AGENTS.md, llms.txt, .github/copilot-instructions.md |
Runtime surfaces
| Surface | Entry point | Stability |
|---|---|---|
| Python facade | forecastability |
Stable |
| Advanced triage namespace | forecastability.triage |
Stable |
| CLI | forecastability |
Beta |
| Dashboard | forecastability-dashboard |
Beta |
| HTTP API | forecastability.adapters.api:app |
Beta |
| MCP adapter | experimental adapter surface | Experimental |
| Agent narration | experimental adapter surface | Experimental |
The primary integration surface is the Python API:
from forecastability import TriageRequest, run_triage
Advanced users can import triage-specific models from:
from forecastability.triage import BatchTriageRequest, run_batch_triage_with_details
See:
Repository workflow
For local development:
git clone https://github.com/AdamKrysztopa/dependence-forecastability.git
cd dependence-forecastability
uv sync
Run tests:
uv run pytest
Run linting:
uv run ruff check .
uv run ruff format --check .
Run a smoke showcase:
MPLBACKEND=Agg uv run scripts/run_showcase_fingerprint.py --smoke
Run routing validation smoke path:
uv run python scripts/run_routing_validation_report.py --smoke --no-real-panel
Main maintainer scripts:
| Script | Role |
|---|---|
scripts/run_canonical_triage.py |
Canonical single-series workflow |
scripts/run_benchmark_panel.py |
Benchmark-panel workflow |
scripts/build_report_artifacts.py |
Report artifact builder |
scripts/run_triage_handoff_demo.py |
Triage-first downstream hand-off demo |
scripts/run_causal_rivers_analysis.py |
CausalRivers triage analysis |
scripts/check_repo_contract.py |
Repository contract validation |
scripts/check_published_release.py |
Post-publish PyPI / GitHub release verification |
Statistical notes
- AMI is computed per horizon rather than aggregated before computation.
- pAMI is a project extension and a linear-residual approximation, not exact conditional mutual information.
- Surrogate significance uses phase-randomized FFT surrogates with two-sided confidence bands.
- "Significance skipped" and "no significant lags" are different outcomes.
- In rolling-origin workflows, diagnostics should be computed on the training window only.
- Phase surrogates can be conservative for strongly periodic series.
- Covariate informativeness is not the same as causal proof.
- Model-family routing is deterministic guidance, not a replacement for validation on holdout data.
- The package may recommend abstention when the evidence is weak or the input is not ready.
Methodological boundaries
This package is designed to be useful, but conservative.
It is appropriate for:
- pre-modeling diagnostics,
- lag selection,
- exogenous-driver screening,
- forecastability profiling,
- deterministic model-family routing,
- contract generation for downstream model search,
- agent- and LLM-readable forecasting preparation.
It is not enough for:
- final model validation,
- production forecast approval,
- causal claims without domain evidence,
- automated business decisions without holdout testing,
- replacing expert review in high-stakes settings.
Documentation map
| Need | Start here |
|---|---|
| Quickstart | docs/quickstart.md |
| Public API | docs/public_api.md |
| ForecastPrepContract | docs/reference/forecast_prep_contract.md |
| Framework recipes | docs/recipes/forecast_prep_to_external_frameworks.md |
| Examples index | docs/examples_index.md |
| Theory docs | docs/theory |
| Module map | docs/code/module_map.md |
| HTTP API contract | docs/reference/api_contract.md |
| Developer guide | docs/maintenance/developer_guide.md |
| Release notes | CHANGELOG.md, RELEASES.md |
Project status
The package is in beta.
The current direction is:
library-first core
+ framework-agnostic contracts
+ examples in a sibling repository
+ better visibility for coding agents and LLM workflows
The core repository should stay focused on deterministic triage logic and stable contract surfaces.
Executable walkthroughs, benchmark notebooks, and framework-specific examples belong in:
Citation
If this package supports your research, analysis, or tooling, please cite the repository using the metadata in:
Contributing
Contributions are welcome, especially around:
- clearer documentation,
- additional benchmark examples,
- forecast-prep contract improvements,
- deterministic validation cases,
- downstream recipe examples in the sibling examples repository,
- better tests for edge cases and readiness failures.
For contributor workflow, see:
For issues:
- Core library issues: https://github.com/AdamKrysztopa/dependence-forecastability/issues
- Notebook / examples issues: https://github.com/AdamKrysztopa/forecastability-examples/issues
License
MIT — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dependence_forecastability-0.4.3.tar.gz.
File metadata
- Download URL: dependence_forecastability-0.4.3.tar.gz
- Upload date:
- Size: 3.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a452ab7aa61ca3cb8908b1e3a3f5dfbbca38133063467c9ddc823a89bed9dd16
|
|
| MD5 |
a717c4916ab5cc27f83011ef5042eebe
|
|
| BLAKE2b-256 |
f64d12f5b0a2fbe9c56d78f58b311fb5a2f2c8c0c7bcc528b82ce8027c031244
|
Provenance
The following attestation bundles were made for dependence_forecastability-0.4.3.tar.gz:
Publisher:
publish-pypi.yml on AdamKrysztopa/dependence-forecastability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dependence_forecastability-0.4.3.tar.gz -
Subject digest:
a452ab7aa61ca3cb8908b1e3a3f5dfbbca38133063467c9ddc823a89bed9dd16 - Sigstore transparency entry: 1439994362
- Sigstore integration time:
-
Permalink:
AdamKrysztopa/dependence-forecastability@2e2e2b561af457ede9cb5ec9ff63a356822822f7 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/AdamKrysztopa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2e2e2b561af457ede9cb5ec9ff63a356822822f7 -
Trigger Event:
push
-
Statement type:
File details
Details for the file dependence_forecastability-0.4.3-py3-none-any.whl.
File metadata
- Download URL: dependence_forecastability-0.4.3-py3-none-any.whl
- Upload date:
- Size: 439.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ad3ef3dc5ad35a533ce2d62205b4e8a08512c8f21ffe5f4a250960b90e8d62c
|
|
| MD5 |
1fe47039d4913e66b62fcc46648c87d3
|
|
| BLAKE2b-256 |
2e51146b87569214f7af9082fd18fb1da50751fa4e6aec7071a459e59c83349d
|
Provenance
The following attestation bundles were made for dependence_forecastability-0.4.3-py3-none-any.whl:
Publisher:
publish-pypi.yml on AdamKrysztopa/dependence-forecastability
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dependence_forecastability-0.4.3-py3-none-any.whl -
Subject digest:
1ad3ef3dc5ad35a533ce2d62205b4e8a08512c8f21ffe5f4a250960b90e8d62c - Sigstore transparency entry: 1439994381
- Sigstore integration time:
-
Permalink:
AdamKrysztopa/dependence-forecastability@2e2e2b561af457ede9cb5ec9ff63a356822822f7 -
Branch / Tag:
refs/tags/v0.4.3 - Owner: https://github.com/AdamKrysztopa
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@2e2e2b561af457ede9cb5ec9ff63a356822822f7 -
Trigger Event:
push
-
Statement type: