Skip to main content

forecastaudit

Scoring, decomposing and recalibrating archived probabilistic forecasts: forecasts that were published and timestamped before their outcomes existed.

This is the code behind Skillful but overconfident: scoring the archived real-time SARS-CoV-2 variant forecasts. It is written to be reusable on any quantile-format forecast archive; nothing in the decomposition or the recalibrator is pathogen-specific.

Why it exists

Scoring an archive is not just applying a scoring rule. Two things have to happen first, and scoringutils (which solves the scoring itself well, and which you should use if you already have matched pairs) does neither:

  1. Backfill-aware truth. Observed frequencies for a past date keep changing as sequences are deposited, so "the outcome" depends on when you look.
  2. Partition matching. The categories these forecasts are defined over are redefined roughly every three to five weeks, faster than the observations settle. Matching a forecast to an outcome by label therefore compares different quantities, and produces coverage numbers that are artifacts. score_matched restricts comparison to snapshots sharing an identical category set.

And one thing has to happen after: an MCB / DSC / UNC decomposition of the weighted interval score, separating how much of the score is recoverable miscalibration from genuine discrimination. No existing tool computes this for the WIS.

Install

pip install forecastaudit

From a clone, for development:

pip install -e ".[dev]"
pytest -q

results/ ships the scored summaries and the small tables, which is enough for almost the whole suite. Seven tests guard claims against the full gisaid pair table, which is 24 MB and is not committed; they skip with no scored results on disk until you regenerate it with python src/score_matched.py.

The pieces

Module What it does
score snapshot loader, WIS, interval scores
backfill backfill-aware truth construction and the settling-lag profile
score_matched partition-matched scoring; keeps the raw interval bounds, which matters because most intervals are asymmetric about the median
decompose quantile-wise MCB / DSC / UNC decomposition of the WIS
idr_decompose interval-conditioned decomposition, fitted along linear extensions of the componentwise partial order
idr_exact the same problem solved exactly as a linear program, to bound the shortcut above
recalibrate conformalized quantile regression applied out-of-time by rolling origin
skill, clustered, stratified, heterosked, selection baselines and the robustness battery

The data

Public, no credentials, no account. The archive is at

s3://nextstrain-data/files/workflows/forecasts-ncov/

with the influenza replication set at files/workflows/forecasts-flu/. Note the prefix depth: forecasts-ncov/ on its own returns zero objects.

One thing worth knowing before writing a loader. The server sets Content-Encoding: gzip and requests decompresses transparently, so r.json() works directly. The files are not gzip members despite the .json extension, and calling gzip.decompress() on the body raises.

Reproducing the paper

Every figure and table is regenerated from results/ by:

python src/figures.py

The pipeline that produces results/ is src/score_matched.py. RESULTS.md records the numbers it yields, and results/README.md explains the file layout, including the _full suffix that distinguishes the full stride-7 run from an earlier capped one.

A note on the estimator

Isotonic quantile regression under a partial order is not solvable by pool-adjacent-violators. idr_decompose fits along linear extensions instead, which is provably conservative: more constraints can only make the fit worse, so the reported miscalibration is a lower bound. idr_exact measures how loose that bound is by solving the exact problem as a linear program on matched subsamples. On the archive in the paper the shortcut understates miscalibration by 3.8% on average and 2.0% at the 95% level, with zero ordering violations in 120 fits.

License

MIT. See LICENSE.

Metadata

Release files for forecastaudit 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for forecastaudit 0.1.1
File Size Uploaded
forecastaudit-0.1.1.tar.gz 69.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for forecastaudit 0.1.1
File Interpreter ABI Platform
forecastaudit-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 136.7 kB

Release files / forecastaudit-0.1.1.tar.gz

Download URL forecastaudit-0.1.1.tar.gz
Size 69.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4bb341bc194e8156a3e441bf77dd0fadd045573c871a8c5a35f3774684ab976b
BLAKE2b-256 checksum
How to use checksums
2407209c28152127f06e348f3d72c346e4f69914363f33f63fa26009773805d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / forecastaudit-0.1.1-py3-none-any.whl

Download URL forecastaudit-0.1.1-py3-none-any.whl
Size 67.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
734d7d3a142ab65159337873661ba9779026ae106dd2af27fc080ba18468febf
BLAKE2b-256 checksum
How to use checksums
6a0fdc164360150c8aa77b73264a860d10806c99bf6da34abf61234c967fc511
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page