Stand: 2026-09-16 · Branch main · Commit 554e391
Quellen: config/config.yaml (2256 Zeilen) + Implementierungscode in bluegreencity_ki/ — nicht die Doku. Alle Werte unten sind aus Code/Config ausgelesen.
Vorgänger: Der Snapshot vom 2026-08-29 ist archiviert. Wichtige Änderungen seitdem: SWBM swbm-v0.1 → swbm-v0.3 (kapillarer Aufstieg aktiv), ML-Panel v4 → v6 (35 statt 48 Features, time_limit 3600 s, NN_TORCH min_time_limit 300 s, dynamic_stacking: false), Label-Quelle auf das v6-Baumkataster.
| Modell | Output-Spalte | Berechnung |
|---|---|---|
| Rulebased | drought_risk_rulebased |
Gewichtete Summe von 25 Kriterien (21 aktiv, 4 mit Gewicht 0) |
| ML | drought_risk_ml (Alias: ml_damage_score_t1) |
AutoGluon-Wahrscheinlichkeit P(starkes Dürreschaden in snapshot_year+1) |
| SWBM | swbm_daily_state → soil_water_stress_today, soil_water_stress_forecast_max_7d, irrigation_demand_liters |
Physikalisches Tag-für-Tag-Bodenwassermodell (Multi-Layer), eigenständiger Runner |
Kopplung (aktuelle Operation):
site_vulnerability_rulebased — 5 Effektklassen zu je 20 %.irrigation_demand_liters > 0 (SWBM-Layer-1-Trigger < 0.4 aus dem Ursprungsskript). Ohne Bedarf → Priorität 0.0.5·SWBM-ForecastStress + 0.3·ML-Score + 0.2·SiteVulnerability, geteilt durch 1.0.docs/plans/done/2026-08-30-kaskade-label-feature-reduktion.md (Block A; lokales Plan-Dokument, nicht Teil der öffentlichen Doku).conservative_max über Unsicherheitsszenarien) + ML-Risiko (Gewicht 1.0) + Site Vulnerability (0.2 im Policy-Score).drought_risk_ml, Baseline drought_risk_rulebased.project.scenario): ml_operational_panel_2018_2023_predict_2024_validate_2025.Achtung — aktuell deaktiviert in der Config (Kode vorhanden, Flags aus):
climate.water_balance.enabled: false (SWBM läuft nicht in der Hauptpipeline, sondern über scripts/run_daily_water_balance.py / run_swbm_warmup.ps1; täglicher Scheduled Task BlueGreenCity-KI daily soil water balance, 04:00 Uhr)climate.water_balance.capillary_rise.enabled: true — seit swbm-v0.3 (GitHub #218): Kapillarer Grundwasseraufstieg aktiviert, Tiefe aus krigiertem mittlerem Flurabstand (Details: water_balance/capillary_rise.md). model_version wurde von swbm-v0.2 auf swbm-v0.3 hochgezogen.climate.water_balance.irrigation.enabled: false und irrigation_event_import.enabled: falseirrigation_planning.enabled: falseintegration.greenspace_api.enabled: falseswbm-v0.3)Code: bluegreencity_ki/water_balance/ (19 Module). Config: climate.water_balance.
| Parameter | Wert | Quelle |
|---|---|---|
model_version |
swbm-v0.3 |
Config |
mode |
local_observation |
Config |
method |
fao56 (Penman-Monteith via pyet.pm_fao56) |
Config + Code |
forecast_days |
7 (7-Tage-Stress-Vorhersage) | Config |
soil_data_source |
nfk_polygons |
Config |
et0_source (Config-Feld) |
openmeteo — aber: ET0 wird tatsächlich in-Process aus den Wetterdaten mit schattierten Strahlungskorrekturen berechnet (shaded_reference_et0_mm), nicht als Open-Meteo-ET0-Variable |
Code meteorology.py |
meteorology.elevation_m |
55.0 m (fest für die Stadt) | Config |
Qualitätsfaktoren (source_quality) — fließen als data_quality in jeden Tageszustand (min. mit baumspezifischer Qualität):
| Quelle | Qualität |
|---|---|
dwd |
1.0 |
parquet |
1.0 |
openmeteo |
0.7 |
| Default (unbekannt) | 0.5 |
Kaskade: DWD-Grid-Cache (lokal, data/cache/water_balance/daily_cells_{year}.parquet, hourly_cells_{year}.parquet, daily_cell_meta_{year}.parquet, hourly_cell_meta_{year}.parquet) → falls unvollständig: Open-Meteo (archive-api für Historie, forecast-API ab today − forecast_past_days (5 Tage), Config climate.water_balance.meteorology.openmeteo_fallback, Timezone Europe/Berlin, Timeout 30 s, räumliche Auflösung 2 Dezimalstellen). Die Tagesquelle steht je Zeile in der meteorology_source-Spalte der swbm_daily_state-Tabelle.
DWD-Vorverarbeitung (dwd_preprocessing):
[9.62, 52.28, 9.95, 52.48]hyras_version: "6-1", HYRAS-Grid (täglich) + HOstrada (stündlich)download_timeout_seconds: 120ET0-Berechnung (Code, shaded_reference_et0_mm):
inverse_distance = 1 + 0.033·cos(2π·J/365), declination = 0.409·sin(2π·J/365 − 1.39)Rso = (0.75 + 2e-5·Höhe_m) · RaRso_eff = SVF · RsoKt = Rs/Rso:
Kt ≤ 0.22: 1 − 0.09·Kt0.22 < Kt ≤ 0.80: 0.9511 − 0.1604·Kt + 4.388·Kt² − 16.638·Kt³ + 12.336·Kt⁴Kt > 0.80: 0.165sunlit_hours / daylight_hours (geclippt 0–1)shadow·(Rs − diffuse) + SVF·diffusepyet.pm_fao56 mit tmean/tmin/tmax, rhmin/rhmax, wind 2m, Rs_eff, Rso_eff, Lat, Höheclimate.water_balance.forcing| Parameter | Wert |
|---|---|
sunlit_hours_fallback_enabled |
true |
sunlit_hours_fallback |
Frühlings-Anker 8 h, Sommer 14 h, Herbst 10 h, Winter 4 h (Qualität 0.5) |
stem_diameter_fallback_enabled |
true |
stem_diameter_fallback_cm |
30 cm (Qualität 0.3) |
unknown_svf_scenarios |
shaded 0.3, medium 0.6, exposed 0.9 (Qualität 0.3) |
Sunlit Hours sind zyklisch linear anhand des Day-of-year (Index 1..366, date.timetuple().tm_yday) zwischen den 4 saisonalen Raster-Ankern (DOY von 20.03 / 21.06 / 22.09 / 21.12) auf jeden Tag interpoliert (sunlight.py). Die DOY-Ankerung löst zusätzlich auch Zukunftstage und den Kalenderjahres-Übergang ohne weiteres Mapping (der Sonnen-Jahreszyklus ist jährlich identisch).
Flusslogik pro Tag (Code forcing.py):
min(precip, 1.0 mm/LAI-Einheit)(1 − 0.10) · Throughfall · Bodenfläche/1000(1 − 0.15) · Throughfall · Baumscheibenfläche/1000 + 0.55 · Throughfall · (Bodenfläche − Scheibenfläche)/1000ET0 · Kronenfläche/1000 · transpiration_fraction · Stressreduktion
(verfügbar − ET0-Volumen + Infiltration) / verfügbare_Kapazitätposition/0.8canopy_fraction = min(LAI/LAI_max, 0.8)WP + 0.8·(FC − WP); total-evaporable: 0.5·WPmin(reduktion · (1.05 − transpiration_fraction), exposed_wet · 1.05)climate.water_balance.vegetation)Formel: LAI_max = a · max(D_Stamm_cm, 1) ^ b (Allometrie), saisonale lineare Rampe zwischen branch_area_index (laublos) und Maximum über die Phenologie-Termine (Tag-im-Jahr): leaf_on → full_on → leaf_off → full_off.
Defaults (alle anderen Gattungen):
Gattungsspezifisch (eigene Parameter in der Config — Auszug der Gattungen mit eigenen Werten):
| Gattung | LAI a | LAI b | BAI | Transp. max | Transp. min | Phenologie (on/full_on/off/full_off) |
|---|---|---|---|---|---|---|
| Acer | 1.6863 | 0.1539 | 0.41 | 0.81 | 0.1 | Default |
| Platanus | 1.1855 | 0.1994 | 0.41 | 0.76 | 0.1 | Default |
| Tilia | 1.7985 | 0.2058 | 0.38 | 0.87 | 0.1 | Default |
| Aesculus | 1.4138 | 0.2046 | 0.44 | 0.79 | 0.1 | Default |
| Quercus | 0.8822 | 0.2549 | 0.35 | 0.79 | 0.1 | Default |
| Robinia | 2.2248 | 0.1483 | 0.30 | 0.76 | 0.1 | 121, 176, 176, 305 |
| Corylus | 1.1016 | 0.2777 | 0.35 | 0.8 | 0.1 | Default |
| Sorbus | 1.0141 | 0.2034 | 0.35 | 0.80 | 0.1 | Default |
| Populus | 1.2077 | 0.2080 | 0.35 | 0.80 | 0.1 | Default |
| Gleditsia | 0.6058 | 0.2434 | 0.35 | 0.80 | 0.1 | Default |
| Sophora | 1.2286 | 0.1578 | 0.35 | 0.80 | 0.1 | Default |
| Betula | 0.4989 | 0.4033 | 0.35 | 0.80 | 0.1 | Default |
| Fagus | 0.7330 | 0.3449 | 0.42 | 0.80 | 0.1 | Default |
| Carpinus | 1.7559 | 0.1158 | 0.35 | 0.80 | 0.1 | Default |
| Prunus | 1.2935 | 0.2087 | 0.38 | 0.80 | 0.1 | Default |
(Robinia = einzige Gattung mit eigener Phenologie; alle anderen nutzen Default.)
climate.water_balance.soil)| Parameter | Wert | Bedeutung |
|---|---|---|
field_capacity |
0.26 (volumetrisch) | Feldkapazität, global |
wilting_point |
0.07 | Welkpunkt, global |
default_planting_site_area_m2 |
6.0 m² | Baumscheibe ohne Angabe |
redistribution_rate |
0.1 | Horizontale/vertikale Umlagerung pro Tag (mit Sättigungs-Glatter exp(−(1−min_saturation))) |
drainage_rate |
0.35 | Perkolation über FC pro Tag nach unten bzw. Drainage |
interception_mm_per_lai |
1.0 | Interzeptions-Kapazität pro LAI |
green_space_runoff_fraction |
0.1 | Abfluss-Anteil auf Grünflächen |
planting_site_runoff_fraction |
0.15 | Abfluss-Anteil Baumscheibe |
surrounding_surface_infiltration_fraction |
0.55 | Infiltration des Umlands (nicht Scheibe) |
Bodenprofil-Aufbau (Code profiles.py):
effektive Scheibenfläche = min(Baumscheibenfläche oder 6 m², Kronenfläche)capillary_rise) — aktiviert seit swbm-v0.3 (#218)| Parameter | Wert |
|---|---|
enabled |
true (seit swbm-v0.3, GitHub #218; bereits im 2026-08-29-Snapshot) |
source |
kriged_groundwater |
interpolation_method |
kriging (Variogramm exponential; idw mit idw_power: 2 als Fallback) |
max_distance_m / min_neighbors |
5000 / 3 (Coverage-Gate wie im groundwater-Criterion) |
max_plausible_depth_m |
20.0 |
trigger_available_fraction |
0.5 (nur bei < 50 % verfügbarem Wasser) |
maximum_available_fraction |
0.2 |
| Lookup (Entfernung GW → Wurzelsohle, in cm → mm/Tag) | 0–30 cm: 5.0; 40: 2.7; 50: 1.5; 60: 0.9; 70: 0.6; 80: 0.4; 90: 0.3; 100: 0.2; 110–120: 0.1 |
Pro-Baum-Grundwassertiefe (Flurabstand): mehrjähriger Median pro Messstelle, kriging- (Fallback: IDW-)interpoliert auf jeden Baum — gleiche Datenbasis und gleiches Coverage-Gate wie das groundwater-Criterion (gemeinsame Hilfsfunktionen load_flurabstand_csvs / aggregate_wells / kriging_interpolate / idw_interpolate). Bäume außerhalb des Gates (zu wenige Messstellen im Radius) simulieren ohne kapillaren Aufstieg — keine Extrapolation über das Messnetz. Die Aufstiegsfläche ist die in 1.5 dokumentierte, altersabhängige A_soil (profile.soil_area_m2), also identisch zur übrigen Bilanz.
Logik (Code engine.py): kein Anstieg, wenn der Grundwasserspiegel höchstens 0.05 m unterhalb der Wurzelsohle liegt (groundwater_depth_m − root_depth_m ≤ 0.05); sonst Rate aus Lookup × Trockenheits-Ratio, begrenzt durch freies Füllvolumen der tiefsten Schicht. Designentscheidungen und bewusste Abweichungen vom h_da-Standalone (krigierte Fläche statt nächstgelegener Messstelle, Median über alle Jahre statt Einjahreswert): water_balance/capillary_rise.md.
Tägliche Ausführung: Seit 2026-09-12 läuft der tägliche SWBM-Lauf über den Windows Scheduled Task BlueGreenCity-KI daily soil water balance (04:00 Uhr, S4U/Standard, LastTaskResult 0). Details: Soil_Water_Balance_Integration.md.
tree_adapter.py)Alter auflösen (Reihenfolge): age_value → standalter → pflanzjahr (Referenzjahr − Jahr) → Schätzung aus Stammumfang/Durchmesser (estimate_age_from_circumference) → sonst Unbekannt-Alter-Szenarien (Config: young 5 J, mature 20 J, old 40 J — jeder wird simuliert).
Kronendurchmesser auflösen: Messwert/Enrichment → art-spezifische lineare Regression Umfang→Krone (Mindest 10 Proben/Art, Konfig crown.min_species_samples) → globale Regression → Altersklassen-Default: 2 m (≤ 5 J), 5 m (≤ 15 J), 10 m (> 15 J). Plausibilitätsgrenzen: 1.0–35.0 m.
Datenqualität pro Baum = min aus:
| Quelle | Alter | Krone | Fläche |
|---|---|---|---|
| Werte | age_value/stand_age/planting_year: 1.0; circumference: 0.7; stem_diameter: 0.6; Unknown-Szenario: 0.3 | gemessen: 1.0; Art-Regression: 0.7; Global-Regression: 0.6; Altersklasse: 0.4 | gemappt: 1.0; sonst 0.7 |
Tages-data_quality = min(Wetterqualität, Baumqualität).
engine.py, advance_daily_state)Reihenfolge pro Tag:
swbm-v0.3, s. 1.6)0.35 · (Wasser − FC) nach unten, Austritt am BodenOutputs pro Baum/Tag (swbm_daily_state):
soil_water_fraction_total, soil_water_fraction_layer_1/2/3 (verfügbares Wasser als Bruchteil von FC−WP, max 1.2)soil_water_stress_today = 1 − min(layer_1_fraction, 1)soil_water_stress_forecast_max_7d = max Stress der nächsten 7 Tage — streng zukünftige Tage, heute ausgeschlossen (forward_forecast_max_stress bewertet das Fenster index+1 … index+forecast_days; nur als Fallback, wenn kein zukünftiger Forecast-Zustand existiert, fällt es auf den eigenen Stress zurück)irrigation_demand_liters: wenn Layer-1-Fraktion < 0.4 → Aufwässermenge auf 0.8 von (FC−WP)irrigation_trigger_date (Tag mit aktivem Trigger), irrigation_avoidable_by_rain (True nur an Trigger-Tagen, an denen Prognose-Regen innerhalb des 7-Tage-Fensters den Boden wieder über den Trigger-Schwellwert hebt — siehe docs/water_balance/swbm_7_day_forecast.md Abschnitt 7), soil_water_m3_*, surface_wet_fraction, model_version, data_quality, meteorology_sourceVersionierung: model_version = "swbm-v0.3:profile-{Szenario}-{12-stelliger-Fingerprint}:irrigation-{lower|central|typical}" (Fingerprint = SHA256 der Profil-Geometrie/Hydraulik).
Bewässerungsevents (unscharfe Mengen, Code irrigation.py):
lower: 0 l (untere Grenze) — Default des Runnerscentral: modelliertes Defizit zum Ziel (s. o.)typical: typical_amount_liters = 150 l (Config irrigation.typical_amount_liters)event_key = SHA256(source + source_event_id))irrigation: trigger_soil_water_fraction_layer_1: 0.4, target_field_capacity_fraction: 0.8, unknown_amount_strategy: modeled_deficit, species_specific: true| Parameter | Wert |
|---|---|
execution.tree_features_path |
data/derived/water_balance/tree_features.gpkg |
execution.prepared_features_path |
data/derived/water_balance/tree_features.gpkg |
execution.dwd_cache_dir |
data/cache/water_balance |
execution.write_batch_size |
5000 |
execution.write_postgis |
true |
execution.schedule_time |
04:00 |
postgis |
schema bgcki, Tabellen swbm_daily_state, irrigation_event |
parquet |
data/derived/water_balance/daily_state.parquet, irrigation_events.parquet |
| Warm-up | Vorjahr komplett + aktuelles Jahr bis heute + 7 Tage Forecast (run_swbm_warmup.ps1) |
Code: bluegreencity_ki/ml/. Config: ml.
| Parameter | Wert |
|---|---|
ml.enabled |
true |
dataset_mode |
operational_panel |
training_data |
data/derived/ml/training_dataset_v6_operational_panel_2018_2024.csv |
drought_csv (Label-Quelle) |
data/input/trees/Baum-2010-2025-v6_historisch_prod.csv |
labeling.strategy |
operational_panel_drought_damage |
labeling.snapshot_year |
2025 (Aktivitätsfenster der Labels) |
labeling.label_horizon_years |
1 |
labeling.target_label |
future_drought_damage_severe_t1 |
labeling.min_join_coverage |
0.05 (Fail-fast bei ID-Schemata-Fehler) |
operational_panel.start_year / end_year |
2018 / 2024 (7 Panel-Snapshots) |
operational_panel.feature_query_mode |
snapshot_year (Spalte snapshot_year) |
annual_validation.output_dir |
data/models/autogluon/annual_validation (Round-Ordner <YYYY_MM>/train_<a>_<b>__predict_<p>__validate_<v>) |
operational.output_dir |
data/models/autogluon/operational (refit-final, Round-Ordner <YYYY_MM>/train_<a>_<b>__predict_<p>) |
Panel-Design: Für jedes Snapshot-Jahr Y (2018–2024): Features = PostGIS-Zeilen aus bgcki.analysis_tree_risk_scores_ml_operational_panel mit snapshot_year = Y; Label = Kronendiagnosen aus Jahr Y+1 aus dem Baumkataster-CSV. Zeilen: snapshot_year, label_year = Y+1, label_available, exclude_from_training_reason.
label_extractor.py)Aus den Spalten Krone Wipfeldürre, Krone Totholzbildung, Krone Belaubung (Auffälligkeiten) („J“/„N“):
drought_damage_score = 3·Wipfeldürre + 2·Totholz + 1·Belaubung (Max über alle Beobachtungen im Fenster)future_drought_damage_severe_t1 = 1, wenn score ≥ 3 → d. h. Wipfeldürre im Folgejahr ODER (Totholz + Belaubungsauffälligkeit zusammen)future_wipfelduerre_binary_t1, future_totholz_binary_t1, future_belaubung_auffaellig_binary_t1, future_drought_damage_binary_t1, _score_t1, damage_years_count_t1, first_damage_year_t1vitality_deterioration (Geschwindigkeitsschwelle 5 J), fast_deterioration (75. Perzentil), growth_anomaly (< 0.5 × 2.5 cm/J), maintenance_stress, critical_failure (Fällgründe, ×1.5-Gewichtung für 2018/2019/2022)TabularPredictor)| Parameter | Wert |
|---|---|
problem_type |
binary |
presets |
best_quality |
eval_metric |
roc_auc |
time_limit |
3600 s (seit 2026-09-15, ml.training.time_limit; zuvor 2400 s) |
num_gpus |
1 |
num_bag_folds / num_bag_sets |
5 / 1 |
num_stack_levels |
1 |
fit_kwargs.dynamic_stacking |
false (DyStack-Erkundung deaktiviert; bei CPU-Fallback crashten Runs mit „Not enough time left“ – DyStack bestimmte selbst 1 Stack-Level als optimal) |
model_path |
data/models/autogluon |
features_table |
bgcki.analysis_tree_risk_scores_ml_operational_panel |
Preset-Konfig extreme (nur falls presets=extreme) |
zeroshot_2025_12_18_gpu |
Explizite Hyperparameter-Portfoliogewichtung (ml.training.hyperparameters):
| Familie | Kandidaten | GPUs |
|---|---|---|
| GBM (LightGBM) | [extra_trees=true (Suffix „XT“), Standard] | 0 |
| CAT (CatBoost) | Standard | 0 |
| XGB | Standard | 0 |
| NN_TORCH | Standard, min_time_limit: 300 (seit 2026-09-15: garantierter Zeitanteil, damit NN_TORCH auch konkurrieren kann, wenn die Tree-Ensembles das Gros des time_limit verbrauchen; bei Bagging auf 5 Folds geteilt → ~60 s/Fold ≈ 2 Epochen. 600 s verdrängte im 2026-09-15-Run das L2-Stacking komplett → 300 s + time_limit: 3600) |
1 |
| RF | [criterion=gini (Suffix „Gini“), criterion=entropy (Suffix „Entr“)] | 0 |
| XT (ExtraTrees) | [criterion=gini (Suffix „Gini“), criterion=entropy (Suffix „Entr“)] | 0 |
(Alle Kandidaten: ag_args.ignore_constraints nicht gesetzt außer via ignore_model_constraints_families; RF/XT nur binary+multiclass.)
Features: exakt 35 Spalten (ml.training.feature_columns, ml.training.labels):
species_genusspecies_binomialkr_durchmst_umfangdist_road_mstreet_type_valuesalt_valueland_use_valueplanting_site_surface_typeplanting_site_area_m2planting_site_tree_countm_svf_valuem_sunlit_hours_valuem_air_temp_14h_valuem_air_temp_04h_valuem_cold_air_kvs_valuegroundwater_level_latest
18–28. 11 × citree_*: lichtanspruch, bodenverdichtungstoleranz, staunaessetoleranz, salzvertraeglichkeit, grundigkeit, bodeneigenschaft, bodenfeuchtetoleranz, kronenform, oberflaechennahe_wurzeln, trockenheitstoleranz, hitzevertraeglichkeitdwsi_summer_valueprecip_may_oct_mmprecip_nov_apr_mmtemp_mean_may_oct_cet0_may_oct_mmp_et0_ratio_may_octp_et0_ratio_anomaly_may_oct(Die Nummerierung folgt exakt der Reihenfolge in ml.training.feature_columns; maßgeblich ist config/config.yaml. Feature-Begründung, Wichtigkeiten aus dem 2026_09-Trainings-Run und die Reduktionen Plan-Block C (2026-08-30) + Issue #217 (2026-09-15): ../risk_assessment_ml/automl_features.md.)
Explizit ausgeschlossen (81 Spalten, ml.training.excluded_columns — technische Sicherheitsstufe IDs/Leakage, nicht die fachliche Feature-Auswahl; Aufzählung = 26 + 12 + 17 + 12 + 14 = 81): alle Label-Spalten (aktuell + future + t1, 26), objectid, ga_lang, vitality_value, snapshot_year, label_year, label_horizon_years, label_available, exclude_from_training_reason, albedo_value, field_capacity_value, nfkwe, nfkwe_stufe, tree_disc_value, pit_size_value (14 IDs/Technik-/Rohwert-Spalten), sämtliche ndvi_*-Detailspalten (12), 17 × obskh_*-Rohdaten, sowie die aus Plan-Block C/#217 entfernten Features (12: age_value, gk25_material_class, subway_tunnel_dist_m, citree_krankheiten_schaedlinge, m_uhi_intensity_value, m_cold_air_kpr_value, groundwater_level_median/max/std, m_sunlit_hours_spring/summer/autumn) — wichtig: kein drought_risk_rulebased, keine *_risk-Scores (Leakage-Schutz; ML lernt nur Rohwerte).
| Block | Parameter |
|---|---|
grouped_cv |
5 Splits, Gruppe objectid, Threshold 0.5, random_state 42, Output in den Validierungs-Run-Ordner (<run_dir>/grouped_cv), year_column: snapshot_year für Per-Year-OOF |
rolling_validation |
min. 4 Trainingsjahre, Jahr-Spalte snapshot_year, Gruppe objectid, Threshold 0.5, Arten-Spalte ga_lang |
annual_validation |
Basis data/models/autogluon/annual_validation, jeder Lauf erzeugt <YYYY_MM>/train_<a>_<b>__predict_<p>__validate_<v>, export_gpkg: true |
operational |
Basis data/models/autogluon/operational, refit-final (train inkl. Holdout-Jahr) → <YYYY_MM>/train_<a>_<b>__predict_<p> |
Aktuell (Runde 2026_09) |
Validierung: train 2018–2023 → predict 2024 → validate 2025 (Holdout ROC-AUC 0.9647, Grouped CV 0.8563 · s. grouped-CV-Report) · Operativ: train 2018–2024 (365,059 Zeilen) → predict 2025 |
Plausibilisierung plausibility.ml |
max 5000 Zeilen, Korrelations-Threshold 0.85 (aktiv), PCA (aktiv), Clustering (aktiv), Explainability (aktiv), Arten-Cluster: 6 (min. 5 Proben) |
| Parameter | Wert |
|---|---|
ml.inference.label |
future_drought_damage_severe_t1 |
| Modell-Pfad (Inferenz) | auto-resolved: <training.model_path>/<label>/ (operativ: data/models/autogluon/operational/2026_09/train_2018_2024__predict_2025) |
thresholds |
critical ≥ 0.85, high ≥ 0.30, medium ≥ 0.15, low ≥ 0.00 (absteigend, erster Treffer gewinnt; Config übersteuert immer DEFAULT_THRESHOLDS in predictor.py; high/medium am 2026‑09‑19 von 0.60/0.40 gesenkt; täglich beim Produkt‑Refresh aus Rohscore + Config neu abgeleitet) |
drought_risk_ml |
P(positiv) aus predict_proba |
drought_risk_ml_class |
critical/high/medium/low aus Thresholds |
drought_risk_ml_confidence |
|p − 0.5| · 2 (geclippt 0–1) |
drought_risk_ml_class_margin |
Distanz zum nächsten Threshold |
ml_damage_score_t1 |
Alias von drought_risk_ml (für Action Priority) |
| PostGIS-Output | enabled: true, schema bgcki, Prefix {scenario}, Mode replace |
| Local-Explainability | enabled: true, scope: all, top_k: 3, batch_size: 500, extreme_group_quantile: 0.05; Kandidaten = Features mit positiver Trainings-Permutationswichtigkeit (p < 0.05); Referenzprofil (Median/Modus) wird neben dem Modell persistiert |
| SHAP | scope: high-risk, risk_classes_include: [critical, high, medium, low], risk_classes_max_rows_per_class: 50 (random_state 42), high_risk_max_rows: 25, background_sample_size: 50, waterfall_limit: 10, batch_size: 50 → shap/risk_classes_shap_values.csv + _feature_values.csv, Spalten ..._drivers_shap |
Explainability (zwei Stufen):
top_k: 3, batch_size: 500, scope: all → Spalten drought_risk_ml_top_positive_drivers_approx / _negative_drivers_approxscope: high-risk, 4 risk classes à max 50 Zeilen (random_state 42), davon 25 High-Risk-Deep-Dives, Background-Sample 50, Waterfall-Limit 10, Batch 50 → shap/risk_classes_shap_values.csv + _feature_values.csv, Spalten ..._drivers_shapCode: bluegreencity_ki/criteria/ + pipelines/risk_scoring.py. Config: criteria (25 Einträge) + mapping.
w_sum = Σ weight_i (= 1.050971 aktuell, codeverifiziert 2026-09-16)
drought_risk_rulebased = Σ (weight_i / w_sum) · <kriterium>_risk_i
Jedes Kriterium liefert einen Score in [0, 1] (index-aligned auf tree_id). 21 Kriterien aktiv, 4 inaktiv (weight = 0) — inaktive werden zwar berechnet (Spalten im Output), tragen aber nichts zum Score bei.
| Kriterium | Raw-Weight | Normiert | Kern-Parameter (Config) |
|---|---|---|---|
vitality |
0.412844 | 39.28 % | exclude_stages: [4, 5], stage0_score: 0.5 |
sky_view_factor |
0.109819 | 10.45 % | tree_percentile 10/90, svf_low: 0.3, svf_high: 0.7, Interpretation shading_protection |
groundwater |
0.105861 | 10.07 % | scoring_source: median, Kriging (exponential, idw_power 2, max 5000 m, min 3 Nachbarn), Breakpoints 0→0.1, 1→0.2, 2→0.4, 4→0.6, 6→0.8, 10 m→0.95, Trend aus (Grimm-Strele) |
ndvi |
0.050970 | 4.85 % | sample_percentile 5/95, ndvi_low: 0.2, ndvi_high: 0.6, mode single_date (2020→ndvi_value_2020, 2024→ndvi_value_2024) |
dwsi |
0.050970 | 4.85 % | sample_percentile 5/95, dwsi_low: −20, dwsi_high: +20, valid −100..100, Cloud-Mask 5000, 7 Jahresraster 2018–2025 |
field_capacity |
0.045653 | 4.34 % | Breakpoints NFKWE: 0→1.0, 50→0.9, 90→0.7, 120→0.5, 160→0.3, 250→0.1 mm; new_planting_year_threshold: 2015 → Score 0.3 (NFKWE=170), missing_score: 0.9 |
age |
0.038598 | 3.67 % | Normalizer q_low 0.05 / q_high 0.95, clip |
uhi_intensity |
0.032883 | 3.13 % | tree_percentile 5/95, uhi_low: 0.0, uhi_high: 4.0 K, outside-coverage 0.0 |
air_temperature_day |
0.032755 | 3.12 % | tree_percentile 5/95, zonal, 20.0–30.0 °C (14 h, Klimaanalyse 2022) |
sunlit_hours |
0.030051 | 2.86 % | tree_percentile 10/90, Saisons spring/summer/autumn, 4.0–10.0 h |
cold_air |
0.028361 | 2.70 % | sample_percentile 5/95, KPR 5–30, KVS 1–10, kpr_weight: 0.5, kvs_weight: 0.5 |
air_temperature_night |
0.024931 | 2.37 % | tree_percentile 5/95, zonal, 15.0–22.0 °C (04 h) |
pit_size |
0.019992 | 1.90 % | Mapping: versiegelt 0.9; <2×2 m 0.8; Streifen <2 m 0.7; 2×2–3×3 m 0.5; Streifen 2–3 m 0.4; >3×3 m 0.3; >3 m 0.2; unversiegelt 0.1; Graben/Böschung 0.3; NaN/leer 0.5 |
albedo |
0.015353 | 1.46 % | sample_percentile 5/95, scale_factor: 0.001, valid 0–1.2, albedo_low: 0.1, albedo_high: 0.22 |
land_use |
0.014763 | 1.40 % | Raster-Code-Mapping (s. u.) + 41 Werte für planting_site_surface_type (s. u.), nodata_value: 28 |
street_type |
0.010783 | 1.03 % | (kein Params-Block; OSM/ALKIS Straßentyp-Klassifikation) |
planting_structure |
0.006219 | 0.59 % | Radius 25 m, mode breaks, Nachbar-Breaks [0, 4, 9] → Scores [0.8, 0.5, 0.3, 0.1] |
salt |
0.005871 | 0.56 % | aha-Winterdienst-Mapping: W1 → 1.0, W2 → 0.5, W0 → 0.0 (ALKIS-Fußstücken-Join ≤ 50 m) |
tree_disc |
0.004945 | 0.47 % | Mapping: bewachsen 0.1; Kies/Mulch 0.2; unterpflanzt 0.2; vegetationsfrei 0.3; Baumrost Holz/Stahl 0.5; Beton 0.6; Lochstein 0.65; Großpflaster 0.7; Wassergebunden 0.3; Klinker 0.85; Asphalt 0.9; NaN 0.5 |
drought_tolerance |
0.004708 | 0.45 % | citree: sehr tolerant 0.1; trockentolerant 0.3; mittel 0.5; empfindlich 0.8; keine Toleranz 0.8; unbekannt/leer 0.5 |
heat_tolerance |
0.004641 | 0.44 % | citree: gut 0.1; mittel 0.4; schwach 0.7; unbekannt/leer 0.5 |
seasonal_weather |
0.0 | — | inaktiv (CSV data/derived/ml/dwd_seasonal_weather.csv als Feature nur für ML) |
gk25 |
0.0 | — | inaktiv; Material-Scores vorhanden: anthropogenic 0.8, water 0.1, rock 0.6, peat 0.2, clay 0.4, silt_loam 0.3, mixed_silt_sand 0.5, gravel 0.8, sand 0.7 |
subway_tunnel |
0.0 | — | inaktiv; Breaks 15/30 m → Scores 0.8/0.5/0.1 |
construction_sites |
0.0 | — | inaktiv; Break 25 m → Scores 0.7/0.1 |
Summe der Raw-Gewichte: 1.050971 → Normierung im Code (Division), nicht in der Config.
mapping in Config)| Code | Score | Label |
|---|---|---|
| 7 | 0.9 | Gleis |
| 20 | 0.9 | Gebäude |
| 22 | 0.9 | Ebenerdig versiegelt |
| 24 | 0.9 | Baum über Versiegelung |
| 26 | 0.7 | Baum über Rasen naturferner Boden |
| 23 | 0.5 | Rasen naturferner Boden |
| 25 | 0.3 | Baum über Rasen |
| 9 | 0.1 | Freiland/Rasen |
| 14 | 0.1 | Wasser |
| 28 | 0.5 | NoData |
Pflanzstandort-Oberflächen (Grünflächenkataster, 41 Typen, Auszug nach Stufen): 0.1 Baumbestände/Sukzession/Grünland/Gewässer; 0.2 Wiese/Sträucher/Hecken/Beete/Spontanvegetation/Versickerung; 0.3 Rasen/offener Boden/Offene Scheiben/Sportrasen/Acker/Grabeland/Gartenbau; 0.4 abgedeckte Scheibe/Häcksel; 0.5 Sand/Wassergebunden/Schotterrasen; 0.6 Schotter/Tennis/Rasengitter/Holzflächen; 0.8 Platten/Pflaster/Sonstige befestigt/Kunststoff/Stege; 0.9 Asphalt/Beton/Mauern/Treppen/Kleinbauwerke/Brücken etc.
risk_products.site_vulnerability, aktiv)Fünf Effektklassen, je Gewicht 0.2 (normalisiert), fehlende Komponente → 0.5:
| Klasse | Komponenten (internes Gewicht) |
|---|---|
water_soil |
groundwater 0.4, field_capacity 0.4, gk25 0.2 |
root_site |
pit_size 0.3, tree_disc 0.15, land_use 0.3, planting_structure 0.25 |
exposure |
svf 0.2, sunlit_hours 0.15, temp_day 0.15, uhi 0.15, cold_air 0.15, temp_night 0.1, albedo 0.1 |
species_resilience |
drought_tolerance 0.5, heat_tolerance 0.5 |
chronic_load |
salt 0.25, street_type 0.35, subway_tunnel 0.4 |
→ site_vulnerability_rulebased = gewichtete Summe der 5 Klassenscores.
irrigation_action_priority (Code risk_products.calculate_action_priority):
irrigation_demand_liters ≤ 0Bewässerungsplanung (irrigation_planning, aktuell disabled):
| Parameter | Wert |
|---|---|
candidate_preparation.rulebased_risk_weight / ml_risk_weight |
0.0 / 1.0 |
state_scenario_strategy |
conservative_max |
minimum_risk_join_fraction |
0.95 |
policy.version |
irrigation-policy-v0.1 |
horizon_days |
7 |
risk_threshold |
0.7 |
urgent_stress_threshold |
0.8 |
min_irrigation_interval_days |
3 |
solver_time_limit_seconds |
30 |
priority_levels |
critical 0.8 / high 0.6 / medium 0.4 |
priority_weights |
risk 0.3, forecast_stress 0.5, site_vulnerability 0.2, rest 0.0 |
heatwave |
≥ 30 °C für ≥ 3 Tage → Prioritäts-Boost +0.1 |
resources |
28 000 l/Tag, 2 Teams × 7 h/Tag, 2 Fahrzeuge × max. 60 Aufträge |
| Parameter | Wert |
|---|---|
project.crs |
EPSG:25832 |
project.scenario |
ml_operational_panel_2018_2023_predict_2024_validate_2025 |
project.feature_reference_year |
2024 |
project.neutral_score |
0.5 |
| Aktive Study Area | hannover_gesamt (v6-Baumkataster Baum-2010-2025-v6_historisch_prod.csv; 2026-09-16 Operational-Run: 89,280 Bäume) |
| ML-Training Study Area | hannover_ml_training_2010 (Snapshot 2010-12-31) |
validation |
Primär drought_risk_ml, Threshold 0.5, Baseline drought_risk_rulebased, top-k 5/10/20 %, mode: pipeline_monitoring |
plausibility |
Spot-Checks (Toleranz 1e-6) über 9 Kriterien, Monotonie-Toleranz 0.02, räumliche Warnung Std > 0.2 pro Stadtteil |
drought_risk_rulebased — die Kriterien sind statisch. SWBM erscheint nur in swbm_daily_state, irrigation_action_priority und der Bewässerungsplanung.drought_risk_rulebased und alle *_risk-Spalten stehen in excluded_columns; ML lernt nur Rohwerte.seasonal_weather, gk25, subway_tunnel, construction_sites) — berechnet, aber score-neutral (Features für ML/Site-Vulnerability: gk25 & subway_tunnel tauchen weiterhin als Komponente in site_vulnerability auf!).mode: local_observation, et0_source: openmeteo, species_specific: true (SWBM-Irrigation) sind Konfig-Felder, deren operative Auswirkung in der aktuellen Code-Version teilweise nicht (etwa mode) oder nur über den getrennten Runner (Irrigation) greift.