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.