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 (the archive is gzipped despite a .json extension), 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 scoring pipeline that produces results/ is documented in VERIFICATION.md, and every reported number traces to a file there.

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

forecastaudit-0.1.0.tar.gz (69.8 kB view details)

Uploaded Source

Built Distribution

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

forecastaudit-0.1.0-py3-none-any.whl (66.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: forecastaudit-0.1.0.tar.gz
  • Upload date:
  • Size: 69.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for forecastaudit-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f714daa05fde9cde921f2dcc3e15128d5a70e3deb79b3d2352717055512d8109
MD5 b4106def344242c6756c7720eded7009
BLAKE2b-256 3d334778abd54f3820ace3e795b4fb6fc783bc9c19dc04fdd97361215dea6567

See more details on using hashes here.

File details

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

File metadata

  • Download URL: forecastaudit-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 66.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.10

File hashes

Hashes for forecastaudit-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 58c64e2b692a69c7812941d75f0d4fce13245ca9e13ac339d259f7ff41670ab6
MD5 7d874716cb921e9c98ddb0c682b12b98
BLAKE2b-256 1f91d9439b84b73f3ef9b7da72ce81f7587d774e251fe0e33b2c9cc686697b8e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 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