Claude‐Chat ‐ KI‐Parkhaus‐Prognose — Architektur & Umsetzungskonzept - roger-infanger-weibel/cas-hzw-ai-innovation GitHub Wiki
KI-Parkhaus-Prognose — Architektur & Umsetzungskonzept
Stand: Juli 2026 Ziel: Web-basiertes Prognosesystem für freie Parkplätze, gebaut in Python, selbst gehostet auf Linux, basierend auf historischen 15-Minuten-Zeitreihendaten seit Januar 2026.
1. Big Picture
Ein wichtiger Punkt vorweg, weil er die ganze Architektur prägt:
Die Prognose selbst ist ein Zeitreihen-/ML-Problem, kein LLM-Problem. Ein LLM (Sprachmodell) ist nicht darauf trainiert, numerische Muster in Zeitreihen präzise vorherzusagen. Was du willst, ist eher „klassisches" Forecasting (Gradient Boosting, ggf. Deep Learning für Zeitreihen). Ein LLM kann optional als Interaktionsschicht obendrauf sitzen (Chat-Interface, Erklärungen, Anomalie-Kommentare), sollte aber nicht die Prognose selbst berechnen.
Daraus ergibt sich eine Zwei-Schichten-Architektur:
┌─────────────────────────────────────────────────────────────┐
│ WEB FRONTEND │
│ Dashboard (Charts, Karte, Belegung live + Prognose) │
│ optional: Chat-Widget ("Frag die Prognose") │
└───────────────────────────┬────────────────────────────────┘
│ REST / WebSocket
┌───────────────────────────▼────────────────────────────────┐
│ API-SERVICE (FastAPI) │
│ /forecast /current /history /chat (optional LLM) │
└───────────────────────────┬────────────────────────────────┘
│
┌────────────────────┼─────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Forecasting- │ │ Feature Store / │ │ Optionale LLM- │
│ Engine │ │ Zeitreihen-DB │ │ Schicht │
│ (LightGBM/ │ │ (TimescaleDB / │ │ (lokales Ollama- │
│ Darts/TFT) │ │ PostgreSQL) │ │ Modell oder API) │
└───────────────┘ └──────────────────┘ └──────────────────┘
▲ ▲
│ │
┌───────┴────────────────────┴───────┐
│ Trainings-Pipeline (Batch, z.B. │
│ täglich/wöchentlich via Cron/ │
│ systemd-timer oder Prefect) │
└──────────────────────────────────────┘
Kernidee: Deine bestehende Datenerfassung bleibt unangetastet. Du baust darauf eine Feature-Pipeline, ein trainiertes Prognosemodell, eine API und ein Frontend – alles containerisiert auf einer Linux-Maschine.
2. Daten-Grundlage (Ist-Zustand nutzen)
Du hast bereits:
- 15-Minuten-Zeitreihen seit Januar 2026 → bei Juli 2026 sind das ca. 17'000+ Datenpunkte pro Parkhaus/Sensor (35'000/Tag ×~180 Tage / 96 = ~17'280). Das reicht für saisonale Muster (Tagesgang, Wochengang), aber noch nicht für ein volles Jahr (z. B. Weihnachtsverkehr, Sommerferien) — das solltest du im Erwartungsmanagement berücksichtigen.
Empfehlung Datenhaltung:
- Falls noch nicht der Fall: PostgreSQL + TimescaleDB-Extension (Zeitreihen-optimiert, kostenlos, läuft auf deiner bestehenden Linux-Maschine, kein Vendor-Lock-in).
- Rohdaten bleiben unverändert als „Source of Truth". Für Training/Features baust du eine separate, aggregierte Tabelle (z. B.
parkhaus_features), damit die Trainings-Pipeline nicht bei jedem Lauf die Rohdaten neu transformieren muss.
Zusätzliche Datenquellen, die die Prognosequalität stark verbessern (falls verfügbar/ergänzbar):
- Wetterdaten (Regen/Schnee beeinflusst Parkverhalten stark) — z. B. Open-Meteo API (kostenlos, kein Key nötig)
- Kalenderdaten: Feiertage, Schulferien, lokale Events (Messen, Konzerte, Fussballspiele)
- Wochentag/Uhrzeit als zyklische Features (wichtiger als man denkt)
3. Feature Engineering
Für jedes Zeitfenster (15-Min-Slot) baust du Features wie:
| Kategorie | Beispiele |
|---|---|
| Zeit (zyklisch) | Stunde (sin/cos-kodiert), Wochentag, Monat, ist_Wochenende |
| Kalender | ist_Feiertag, Ferien_Kanton, Tage_bis_nächster_Feiertag |
| Lag-Features | Belegung vor 15 Min, 1h, 24h, 7 Tage |
| Rolling-Statistiken | gleitender Mittelwert/Std über letzte 4h, 24h |
| Wetter | Temperatur, Niederschlag, ggf. Schneefall |
| Events | Flag für lokale Grossveranstaltungen (manuell gepflegt oder Scraping) |
| Kapazität | Gesamtplätze, evtl. gesperrte Plätze (Wartung) |
4. Modellwahl
Statt ein einzelnes „bestes" Modell zu suchen, empfehle ich einen stufenweisen Ansatz — jede Stufe ist einsetzbar, du kannst iterativ verbessern:
Stufe 1 — Baseline (sofort umsetzbar, als Sanity-Check)
- Saisonaler Naive-Forecast: „Belegung = gleicher Zeitpunkt vor 7 Tagen"
- Dient als Vergleichsmassstab (Baseline-MAE), gegen den sich jedes ML-Modell schlagen muss.
Stufe 2 — Gradient Boosting (empfohlener Haupt-Ansatz)
- LightGBM oder XGBoost mit den Features aus Abschnitt 3.
- Vorteile: sehr gute Performance bei tabellarischen Zeitreihen-Features, schnell zu trainieren, gut interpretierbar (SHAP-Werte zeigen, was die Prognose treibt), moderate Rechenanforderungen — läuft problemlos auf einer normalen Linux-VM ohne GPU.
- In der Praxis für Belegungs-/Nachfrageprognosen mit diesem Datenvolumen meist der beste Kompromiss aus Aufwand und Genauigkeit.
Stufe 3 — Deep Learning (später, wenn mehr Daten & Bedarf an Multi-Step-Prognosen)
- Temporal Fusion Transformer (TFT) oder LSTM über die Library Darts (einheitliches Python-Interface für klassische + DL-Zeitreihenmodelle, inkl. Backtesting).
- Sinnvoll, sobald du mehrere Parkhäuser/Standorte gemeinsam modellieren willst (Cross-Learning zwischen Standorten) oder sehr lange Prognosehorizonte brauchst.
Praktischer Tipp: Starte mit Stufe 1+2 (Baseline + LightGBM). Das ist in wenigen Wochen produktiv nutzbar. Stufe 3 ist eine spätere Ausbaustufe, kein MVP-Blocker.
Die optionale LLM-Schicht
Erst on top der numerischen Prognose:
- Nutzer fragt in natürlicher Sprache: „Wird um 18 Uhr noch was frei sein?"
- Ein LLM (z. B. lokal via Ollama mit einem kleinen Modell, oder Claude/OpenAI API) bekommt über Function Calling / Tool Use Zugriff auf deine Forecast-API, ruft die Zahlen ab und formuliert die Antwort in Sprache.
- Das LLM „erfindet" also keine Zahlen, sondern liest sie aus deinem echten Prognose-Service — das ist der sichere und korrekte Einsatz von LLMs in so einem System.
5. Trainings-Pipeline
Rohdaten (DB) → Feature-Building → Train/Test-Split (zeitlich!)
→ Training (LightGBM) → Backtesting (Walk-Forward) → Metriken loggen
→ Modell versionieren → bei Verbesserung: Deployment
- Zeitlicher Split, kein Random-Split (sonst Data Leakage — du würdest mit der Zukunft die Vergangenheit vorhersagen).
- Metriken: MAE (mittlerer absoluter Fehler in „Anzahl Plätzen") ist meist am besten interpretierbar für Endnutzer; zusätzlich RMSE, MAPE.
- Retraining-Frequenz: Anfangs wöchentlich (viel neue Information bei erst 6 Monaten Historie), später monatlich reicht meist.
- Orchestrierung: Für den Start reicht ein systemd-Timer oder simpler Cronjob, der ein Python-Skript ausführt. Erst bei mehreren Pipelines/Abhängigkeiten lohnt sich Airflow/Prefect.
- Modell-Tracking: MLflow (self-hosted, leichtgewichtig) für Versionierung, Vergleich der Trainingsläufe, Rollback bei Bedarf.
6. API-Service
FastAPI (Python, asynchron, automatische OpenAPI-Doku, gut für Echtzeitanwendungen).
Beispielhafte Endpunkte:
| Endpoint | Zweck |
|---|---|
GET /parkhaeuser |
Liste aller Standorte |
GET /parkhaus/{id}/aktuell |
Aktuelle Belegung |
GET /parkhaus/{id}/prognose?horizont=4h |
Prognose für die nächsten X Stunden (15-Min-Schritte) |
GET /parkhaus/{id}/verlauf?von=...&bis=... |
Historische Daten fürs Chart |
POST /chat |
Optional: LLM-Chat-Interface mit Tool-Zugriff auf obige Endpunkte |
WS /live |
WebSocket für Live-Updates im Dashboard |
Die Modell-Inferenz selbst ist bei LightGBM sehr schnell (Millisekunden) — kein separates GPU-Serving nötig, das Modell kann direkt im API-Prozess geladen werden (z. B. via joblib/pickle).
7. Web-Frontend
Zwei realistische Wege, je nach Aufwand, den du investieren willst:
Option A — Schnell (MVP, 1–2 Wochen):
- Streamlit oder Dash (beides pure Python, kein separates JS-Frontend nötig). Gut für interne Nutzung/erste Version.
Option B — Produktreif (öffentlich nutzbares Dashboard):
- Schlankes React- oder htmx-Frontend, das die FastAPI-Endpunkte konsumiert.
- Charting mit Plotly.js oder Chart.js (Live-Belegung + Prognosekurve inkl. Konfidenzintervall).
- Für mehrere Standorte: Kartenansicht (z. B. Leaflet) mit Farbcodierung nach Auslastung.
Für den Start würde ich Option A empfehlen, um schnell mit echten Nutzern zu validieren, und später bei Bedarf auf B migrieren — die FastAPI-Backend-Schicht bleibt dabei unverändert wiederverwendbar.
8. Deployment auf der Linux-Maschine
Empfohlener Stack:
┌─────────────────────────────────────────────┐
│ nginx (Reverse Proxy, TLS via Let's Encrypt) │
├─────────────────────────────────────────────┤
│ Docker Compose: │
│ - api (FastAPI, uvicorn/gunicorn)│
│ - frontend (Streamlit/React build) │
│ - db (PostgreSQL/TimescaleDB) │
│ - mlflow (optional, Modell-Tracking)│
│ - ollama (optional, lokales LLM) │
├─────────────────────────────────────────────┤
│ systemd-timer: tägliches Retraining-Skript │
└─────────────────────────────────────────────┘
- Docker Compose hält alles reproduzierbar und einfach neu deploybar — empfehlenswert selbst bei nur einer Maschine.
- nginx als Reverse Proxy + TLS-Terminierung (Let's Encrypt/certbot), damit du HTTPS ohne Aufwand bekommst.
- gunicorn + uvicorn workers für FastAPI in Produktion (nicht den Dev-Server nutzen).
- Monitoring (optional, aber empfehlenswert): Prometheus + Grafana für Systemmetriken, plus ein einfaches Logging der Prognosegüte über Zeit (damit du siehst, wenn das Modell „driftet").
9. Projektstruktur (Vorschlag)
parkhaus-prognose/
├── data_pipeline/
│ ├── extract.py # liest aus bestehender Rohdaten-DB
│ ├── features.py # Feature Engineering
│ └── train.py # Training + Backtesting
├── api/
│ ├── main.py # FastAPI App
│ ├── routers/
│ │ ├── forecast.py
│ │ ├── history.py
│ │ └── chat.py # optionale LLM-Schicht
│ ├── models/ # Pydantic-Schemas
│ └── inference.py # lädt trainiertes Modell, macht Prognosen
├── frontend/ # Streamlit-App oder React-Build
├── models/ # versionierte, trainierte Modell-Artefakte
├── docker-compose.yml
├── nginx/
│ └── parkhaus.conf
└── deploy/
└── retrain.timer # systemd-Timer für Retraining
10. Umsetzungs-Roadmap
| Phase | Inhalt | Zeitrahmen (Richtwert) |
|---|---|---|
| 1 — MVP | Feature-Pipeline, Baseline + LightGBM, FastAPI mit /prognose, einfaches Streamlit-Dashboard |
3–4 Wochen |
| 2 — Produktivierung | Docker Compose, nginx/TLS, systemd-Retraining, MLflow-Tracking | 2 Wochen |
| 3 — Verfeinerung | Wetter-/Event-Features, Backtesting-Dashboard, produktives React-Frontend | 3–4 Wochen |
| 4 — Erweiterung (optional) | LLM-Chat-Layer mit Tool-Use, Multi-Standort-Modelle (TFT/Darts), Monitoring/Alerting | laufend |
11. Kurz zusammengefasst
- Prognose-Kern: LightGBM auf technischen Zeitreihen-Features (nicht LLM).
- LLM: nur als optionale Sprachschicht oben drauf, mit Tool-Zugriff auf die echte Prognose-API.
- Stack: PostgreSQL/TimescaleDB → FastAPI → Streamlit/React, alles containerisiert via Docker Compose auf deiner Linux-Maschine, nginx davor.
- Start klein: Baseline + LightGBM + FastAPI + Streamlit ist in ca. 4 Wochen ein funktionierendes MVP, auf dem alles Weitere aufbaut.
Bei Bedarf kann ich als nächsten Schritt ein konkretes Code-Grundgerüst (z. B. data_pipeline/features.py + train.py + api/main.py) aufsetzen.