We trained three LightGBM quantile regressors (alpha=0.05, 0.50, 0.95) on the same
15,351-row country-day forecast dataset that powers
/v1/forecast/{cc}/7day. The goal was to ship a journalist-grade
p5..p95 band alongside the existing point estimate so reporters
citing Voidly could quote a confidence interval rather than a single number.
We are not promoting this model to a live endpoint. The reason is instructive and worth documenting publicly: the model is correct, the metric is correct, the gate is correct, and the conclusion is "the data does not admit a well-calibrated low-quantile estimate."
objective='quantile' at alpha = 0.05,
0.50, 0.95.target_sum_7day — the continuous share of shutdown-positive
days in the forward 7-day window (in [0, ~1]; max observed 5.2 for stacked windows).forecast_features.json (same set as forecast v1).| Quantile | Nominal | Empirical | Error | Within ±5pp? |
|---|---|---|---|---|
| p5 | 5.0% | 81.3% | +76.3pp | NO |
| p50 | 50.0% | 90.5% | +40.5pp | NO |
| p95 | 95.0% | 98.0% | +3.0pp | YES |
Only the upper bound (p95) is well-calibrated. The lower and median quantiles massively over-cover.
The target target_sum_7day is zero-inflated: 80% of
country-day windows have exactly zero shutdown-positive days. The positive rate of
the binary target_7day is 5.2%; the mean of the continuous version is
0.23 (windows that do contain shutdowns rarely cover the entire week).
Quantile regression on this distribution converges to:
With q05 = 0 nearly always, P(y ≤ q05) = P(y = 0) ≈ 0.80, so the
empirical coverage of the p5 prediction is 80%, not 5%. This is not a model bug —
a calibrated p5 on this distribution would require negative quantiles, which is
nonsensical for "share of days censored".
CQR (the standard post-hoc fix) shifts the band by an additive constant. We measured that constant on a held-out calibration fold per LOCO iteration; the learned shift was 0.002 — essentially zero, because the model is already at the edge of the achievable distribution.
Three viable paths forward:
None of those is a quick add-on, so we are publishing the negative result rather
than papering over it. The existing point estimate at
/v1/forecast/{cc}/7day remains the authoritative shutdown forecast;
its 90% conformal interval (delivered by ACI on every response) already gives a
band — derived from residual conformal inference, not quantile regression, and
properly calibrated to nominal coverage.
Even though the calibration story is negative, the feature importance from the median model is informative — it tells us what the model thinks drives shutdown intensity, not just occurrence:
block_rate_roll14_mean (65.9% gain) — the trailing 14-day average
block rate dominates.block_rate_roll7_std (11.8%) — volatility in recent block rates.block_rate_roll7_mean (9.3%) — 7-day trailing average.block_rate_lag7 (4.2%) — 7-day-lagged value.week_of_year (1.7%) — modest seasonality.This is consistent with the v3.3 classifier: rolling block-rate features explain the vast majority of gain. Event features (elections, protests, GDELT unrest) contribute <1% of total gain — the model is essentially a smoother over recent block rates with a small seasonal correction.
scripts/train-quantile-forecast.py/opt/voidly-ai/ml-deploy/quantile_forecast_v1.pkl (saved
with promoted: false, partial_promote: true)/opt/voidly-ai/ml-deploy/quantile_forecast_v1.json/opt/voidly-ai/ml-deploy/quantile_forecast_loco.parquetThe model file is preserved so future work (hurdle models, Beta likelihoods) has a baseline to beat.