Status (October 2026, v6): The retraining round
2026_10is complete. The validation model (train 2018–2023, predict 2024, validate 2025) and the refit-final operational model (train 2018–2024, predict 2025) both live underdata/models/autogluon/, and the 2026-10-09operational-currentrun populated the canonical current table (irrigation_review.inputs.risk_pathpoints at it). This document is kept in sync with the v6 operational panel (54 features, labelfuture_drought_damage_severe_t1).
BlueGreenCity-KI runs two separate prediction products from one versioned model:
The current path does not retrain and does not claim that every inventory row
was observed in the planning year. operational-current selects each tree’s
latest available observation up to the pinned run year, and each
time-dependent criterion (age, DWSI, NDVI, seasonal weather) is additionally
pinned to its own last usable year (plan F.3, decision D19), so every feature
carries its own provenance-tracked reference year.
The inventory update also requires a fresh Water Balance state. The
irrigation_planning safety gate (minimum_risk_join_fraction: 0.95) applies
to any later irrigation-planning run; the 2026-10-09 operational run
completed with 89,280 scored trees.
Validation round (data/models/autogluon/annual_validation/2026_10/train_2018_2023__predict_2024__validate_2025):
0.9697 (OOF control 0.9861, gap 0.0164)objectid, 141,394 rows / 29,178 groups):
pooled ROC-AUC 0.8881, PR-AUC 0.6654, Brier score 0.0898h3_res8, 261 groups): pooled ROC-AUC 0.8032Operational model (data/models/autogluon/operational/2026_10/train_2018_2024__predict_2025):
refit-final WeightedEnsemble_L2 trained on 365,059 panel rows (2018–2024)
with the 54-feature allowlist, predicting 2025 (label
future_drought_damage_severe_t1, Platt-calibrated,
calibration.json: a=2.2831, b=0.6840, n=25,334). The 2026-10-09 operational-current run
(data/output/2026_10_09_ml_operational_train_2018_2024_predict_2025) scored
89,280 trees and wrote the canonical current table.
The validation path is immutable evidence for temporal generalization. Moving its 2024 holdout to the latest inventory would destroy comparability. The current path answers a different question: what does the validated model predict for the newest city inventory?
Outputs are isolated:
| Path | Scenario | Main PostGIS table |
|---|---|---|
| Validation | ml_validation_train_2018_2023_predict_2024_validate_2025 |
bgcki.analysis_tree_risk_scores_validation_2024 |
| Current | ml_operational_train_2018_2024_predict_2025 |
bgcki.analysis_tree_risk_scores_operational_current |
ML prediction tables use the prefixes ml_predictions_validation_2024 and
ml_predictions_operational_current respectively.
The model window is resolved only from ml.operational_panel. In 2027,
advance its end year from 2024 to 2025 only after 2026 labels are available;
the same code then resolves training 2018-2024, prediction 2025, and
validation 2026.
Validation and retraining:
conda run -n bgcki_wesemann python scripts/run_ml_path.py validation `
--config config/config.yaml --train --shap high-risk --skip-approx
Current inference with the existing operational model:
conda run -n bgcki_wesemann python scripts/run_ml_path.py operational-current `
--config config/config.yaml --current-year 2026 --shap off --skip-approx
--provisional writes to a separate scenario and
analysis_tree_risk_scores_operational_current_provisional. It is suitable for
technical integration tests and must not be presented as the current
operational model result.
The complete v6 refresh rebuilds panel snapshots for 2018-2024, regenerates the training dataset, retrains and validates (with SHAP for the high-risk subset in both the validation and operational runs), runs current inference only if all preceding steps succeed, refreshes the feature input used by the daily Water Balance module, updates the operational risk pointer, and finally synchronizes the Grafana analytics tables (validation metrics, feature importance, SHAP values, leaderboard):
pwsh -NoProfile -File scripts/run_ml_refresh_overnight.ps1 `
-Config config/config.yaml -CurrentYear 2026 -StartDetached
The detached process survives VS Code closure and writes to logs/ml/
(notes the log file names still carry a cosmetic v4_ prefix).
Drift watch (issue #260). The metrics import keeps one row per monthly
retrain in bgcki.ml_validation_history and compares the external holdout
against the previous month: a ROC-AUC drop or Brier rise beyond
ml.annual_validation.drift_watch.metric_delta (default 0.05) emits a
WARNING in the log. The Validierung dashboard shows the monthly trend in
two Drift-Watch panels.
Note: after a model feature-set change (e.g. new SWBM features), the SHAP
stage silently skips recomputation when a SHAP cache exists. Pass
--force-shap-recompute (via a direct
python -m bluegreencity_ki.runners.cli --config <runtime.yaml> invocation
after run_ml_path.py --write-config-only) to rebuild the SHAP artifacts
before the Grafana sync.
Grafana should retain the validation pages for model evidence and add a
separate current-operations page sourced from
bgcki.analysis_tree_risk_scores_operational_current. That page can later
join the Phase 1 SWBM state and the irrigation_plan_decision table. Phase 3
Taipy remains responsible for changing resources, scenarios, overrides, and
approvals; Grafana remains read-only monitoring and analysis.
The Lagebild counts trees of the current operational run
(operational_tree_product, 2026-09-16: 89,280 = the full v6 inventory
extract 09/2026, including trees first registered in 2026). The KPI
“Bäume im aktuellen Datenstand” counts all scored trees, including
vitality stages 4/5; map and analysis panels keep the 4/5 exclusion. The
additional KPI “Bäume 2025 mit Prognose 2026” (years derived from
ml.operational_panel.end_year) counts the subset with a 2025 inventory
observation (~81,379) — the previous-year population that carries the
2026 forecast. The Vorjahresprognose page shows its 2024 holdout population
(62,727) the same way.