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:
- Backfill-aware truth. Observed frequencies for a past date keep changing as sequences are deposited, so "the outcome" depends on when you look.
- 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_matchedrestricts 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
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 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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f714daa05fde9cde921f2dcc3e15128d5a70e3deb79b3d2352717055512d8109
|
|
| MD5 |
b4106def344242c6756c7720eded7009
|
|
| BLAKE2b-256 |
3d334778abd54f3820ace3e795b4fb6fc783bc9c19dc04fdd97361215dea6567
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
58c64e2b692a69c7812941d75f0d4fce13245ca9e13ac339d259f7ff41670ab6
|
|
| MD5 |
7d874716cb921e9c98ddb0c682b12b98
|
|
| BLAKE2b-256 |
1f91d9439b84b73f3ef9b7da72ce81f7587d774e251fe0e33b2c9cc686697b8e
|