Real-time per-day SHAP attribution for the 7-day forecast
The /v1/forecast/{cc}/7day endpoint already exposed an aggregate top_features list (3 SHAP contributions for the whole forecast). Journalists kept asking the same follow-up: "okay, but WHY is day 5 higher than day 0?" Until now the only honest answer was "an event boost gets applied outside the model." This finding ships per-day SHAP attribution as a structured response field. The 7-day forecast response now carries a top_features_per_day array aligned with the 8-day forecast list, where each entry exposes the top-3 signed contributions ranked across two pools: (a) the model-side SHAP contributions from shap.Explainer permutation on the XGBoost + isotonic predict_proba (constant across days because the model takes one country feature vector), and (b) the deterministic post-model overlay (event_within_Xd, day_decay). On 2026-05-21 the IR forecast for day 7 attributes 0.121 risk to event:Iranian-Election-2026-in-4d (+0.0682) + day_decay_t+7 (+0.0350) — both overlay components — while the aggregate model-side top three (ooni_anomaly_7d -0.0253, block_rate_roll30_mean +0.0214, block_rate_lag1 -0.0175) is also returned separately. A new lean endpoint GET /v1/forecast/{cc}/7day-shap returns just the per-day attribution for callers that do not need the full forecast envelope. Cached 6h on (country, hour); permutation SHAP costs ~3ms once the explainer is warm. Latency overhead added vs raw /7day: <1ms p95 on the upstream service (within noise; explainer + cache amortize). Honest caveats baked into every response: SHAP explains the calibrated predict_proba (post-isotonic), the model features do NOT actually change per day (only the post-model overlay does — exposed honestly), and the multi-horizon model has its own per-horizon SHAP at /v1/forecast/{cc}/multi-horizon. Implementation: scripts/patch-forecast-per-day-shap.py + worker/src/routes/hydra.ts handleForecast7daySHAP.
Raw data
- Live: IR per-day SHAP
- Live: CN per-day SHAP (Tiananmen anniversary boost grows day-over-day)
- Live: RU per-day SHAP
- Live: full forecast (now includes top_features_per_day)
- Related: multi-horizon per-horizon SHAP (separate codepath)
- Related: aggregate top_features methodology
- Related: forecast accuracy live
- Endpoint patcher