CzechAI | Claude Code | 2026-04-17 | ← Docs
# CzechAI Cenová Mapa — Kompletní Program Dokumentace

**Verze:** 2026-04-17  
**Server:** 46.224.121.179  
**Autor:** Claude Code (CzechAI)

---

## 1. PŘEHLED SYSTÉMU

CzechAI Cenová Mapa je soustava tří nezávislých ML modelů pro odhad cen nemovitostí v ČR. Modely jsou nasazeny jako samostatné Flask API servery s sdíleným geocoderem.

```
Klient (web / API call)
        │
        ▼
┌───────────────────────────────────────────┐
│         Router Tower (router.czechai.io)   │
│  /v1/cenova/v23/estimate                  │
│  /v1/cenova/v24/estimate                  │
│  /v1/cenova/se/estimate                   │
└──────┬───────────────────────────────┬────┘
       │                               │
       ▼                               ▼
┌──────────────┐             ┌──────────────────────────┐
│  V23 :5153   │             │  Super-Ensemble v2.3 :5111│
│  V24 :5154   │             │  7+ engines kombinovaně   │
│  (shared     │             │  Výstup: konsenzus cena  │
│   geocoder)  │             └──────────────────────────┘
└──────┬───────┘
       │
       ▼
┌─────────────────────────────┐
│  czech_geocoder.py          │
│  /opt/czechai-shared/       │
│  80+ měst, fuzzy matching   │
│  diacritika, aliasy         │
└─────────────────────────────┘
       │
       ▼
┌─────────────────────────────┐
│  XGBoost + LightGBM + RF    │
│  Trénováno na 227K+ záznamů │
│  z MASTER_LIVE.db           │
└─────────────────────────────┘
```

---

## 2. MODELY — CO JSOU A JAK SE LIŠÍ

### V23 (port 5153)
- **R²:** BYT = 0.945 | DÚM = 0.918
- **Features:** 31 features (plocha, GPS lat/lon, typ, PSČ median, KNN)
- **Ensemble:** XGBoost 33.6% + LightGBM 33.6% + Random Forest 32.8%
- **Zvláštnost:** Dispozice NENÍ trénovaný feature (jen informativní)
- **Váha v SE:** 1.8

### V24 (port 5154) — PRODUKČNÍ DOPORUČENÍ
- **R²:** BYT = **0.9478** | DÚM = **0.9178** (lepší než V23)
- **Features:** 34 features — přidána `dispozice` jako trained feature
- **Ensemble:** XGBoost + LightGBM + RF (stejné váhy jako V23)
- **Novostavba:** `?condition=novostavba` aplikuje post-prediction multiplier
- **Dispozice:** `?dispozice=2` (1=1+kk, 2=2+kk, 3=3+kk, 4=4+kk)
- **Váha v SE:** 2.0 (maximum)

### Super-Ensemble v2.3 (port 5111)
- **Engines:** 7+ (V24 + V23 + AI_V8 + Oceňovač + Mapa Levon + Výnosový + Nákladový)
- **Přidáno:** Market Intel korekce + Znalecké korekce
- **Confidence:** 0.65–0.92 (záleží na dostupnosti dat v regionu)
- **Latence:** ~239 ms (vs 75–85 ms pro V23/V24)
- **Geocoding:** správné pro VŠECHNA města ČR
- **Kdy použít:** regionální města (mimo Praha/Brno/Ostrava/Plzeň)

---

## 3. GEOCODER — JAK FUNGUJE

### Soubor: `/opt/czechai-shared/czech_geocoder.py`

#### Problém který řeší
V23 a V24 původně měly inline dict se **4 městy** (Praha, Brno, Ostrava, Plzeň). Jakékoliv jiné město (Liberec, Olomouc, Hradec Králové, ...) tiše dostalo Praha souřadnice → cena 2–3× vyšší než správná.

**Před opravou:**
| Město | Výsledek | Správnost |
|-------|----------|-----------|
| Liberec | 203 293 Kč/m² (Praha!) | ❌ |
| Olomouc | 203 293 Kč/m² (Praha!) | ❌ |
| Hradec Králové | 203 293 Kč/m² (Praha!) | ❌ |
| České Budějovice | 203 293 Kč/m² (Praha!) | ❌ |

**Po opravě:**
| Město | Výsledek | Správnost |
|-------|----------|-----------|
| Liberec | 61 557 Kč/m² | ✅ |
| Olomouc | 104 678 Kč/m² | ✅ |
| Hradec Králové | 95 714 Kč/m² | ✅ |
| České Budějovice | 106 155 Kč/m² | ✅ |

#### 4-stupňový matching algoritmus

```python
def geocode(city: str) -> tuple:
    # 1. Exact match (stripped diacritics, lowercase)
    #    "Hradec Králové" → strip → "hradec kralove" → hit
    
    # 2. Alias lookup
    #    "HK" → alias → "hradec kralove" → hit
    #    "CB" → "ceske budejovice"
    #    "KV" → "karlovy vary"
    
    # 3. Partial substring match
    #    "Praha 6" → contains "praha" → hit (50.1047, 14.3928)
    #    "Frýdek" → contained in "frydek mistek" → hit
    
    # 4. Word-by-word match (>4 chars)
    #    Fallback Praha se LOGUJE jako warning
    
    return (lat, lon, canonical_name, confidence)
    # confidence: 1.0=exact, 0.8=alias, 0.6=partial, 0.4=word, 0.0=fallback
```

#### Pokrytí měst
- 80+ měst nad 10 000 obyvatel
- Praha 1–13 jako samostatné záznamy
- 25 aliasů (HK, CB, KV, FM, MB, ...)
- Diakritika: automaticky stripována přes `unicodedata.NFD`

#### Jak přidat město
```python
# V souboru /opt/czechai-shared/czech_geocoder.py
# Do CITY_COORDS dict přidej:
'nove mesto na morave': (49.5606, 16.0745, 'Nové Město na Moravě', 10_000),
# Klíč = stripped lowercase (bez diakritiky, malá písmena)
# Value = (lat, lon, canonical_name, population)
```

---

## 4. API REFERENCE

### V23 — `GET http://localhost:5153/api/estimate`
```
Parametry:
  typ      = byt | dum | pozemek | komercni
  mesto    = název města (česky, s/bez diakritiky)
  plocha   = číslo m²
  lat, lon = GPS (optional, přepíše město)
  ai_comment = true | false (default true, false = rychlejší)

Příklad:
  GET /api/estimate?typ=byt&mesto=Liberec&plocha=60

Odpověď:
{
  "cena": 3693000,
  "cena_m2": 61557,
  "lat": 50.7663,
  "lon": 15.0543,
  "model": "V23",
  "plocha": 60.0,
  "typ": "byt"
}
```

### V24 — `GET http://localhost:5154/api/estimate`
```
Parametry (stejné jako V23, navíc):
  dispozice  = 1 | 2 | 3 | 4 (1+kk, 2+kk, 3+kk, 4+kk)
  condition  = novostavba (aplikuje multiplier)

Příklad:
  GET /api/estimate?typ=byt&mesto=Praha&plocha=75&dispozice=3

Odpověď:
{
  "cena": 16823100,
  "cena_m2": 224308,
  "debug": {
    "lgb": 181072, "rf": 222846, "xgb": 202362,
    "weights": {"lgb": 0.336, "rf": 0.328, "xgb": 0.336},
    "dispozice": 3,
    "condition_mult": 1.0
  },
  "lat": 50.0755,
  "lon": 14.4378,
  "model": "V24"
}
```

### Super-Ensemble — `GET http://localhost:5111/api/estimate`
```
Parametry: stejné jako V24
  ai_comment = false  ← VŽDY pro batch operace (jinak 4+ sec)

Příklad:
  GET /api/estimate?typ=byt&mesto=Olomouc&plocha=55&ai_comment=false

Odpověď:
{
  "cena": 5227086,
  "cena_m2": 95038,
  "method": "SUPER_ENSEMBLE_V2.3",
  "confidence": 0.74,
  "engines_used": 11,
  "spread_pct": 109,
  "tri_pristupy": {
    "trzni": 5100000,
    "vynosovy": 4800000,
    "nakladovy": 5800000
  }
}
```

### Router proxy endpoints
```
/v1/cenova/v23/estimate  →  localhost:5153
/v1/cenova/v24/estimate  →  localhost:5154
/v1/cenova/v24/health    →  localhost:5154/health
/v1/cenova/se/estimate   →  localhost:5111
```

---

## 5. NUMERICKÝ BENCHMARK (2026-04-17)

### Praha BYT — Kč/m²

| Case | V23 | V24 | SE v2.3 |
|------|----:|----:|--------:|
| 1+kk 25m² | 214 991 | 212 584 | 177 687 |
| 2+kk 50m² | 171 294 | 175 830 | 164 694 |
| 3+kk 75m² | 225 328 | 224 308 | 158 200 |
| 4+kk 100m² | 169 513 | 162 919 | 154 628 |
| 3+1 80m² | 163 225 | 162 497 | 154 437 |

### Regionální BYT 2+kk 55m² — Kč celkem

| Město | V23 | V24 | SE v2.3 | Nejlepší |
|-------|----:|----:|--------:|---------|
| Praha | 9 385 530 | 9 604 265 | 8 234 708 | V24 |
| Brno | 4 756 950 | 5 113 100 | 5 318 265 | SE |
| Ostrava | 2 700 775 | 2 707 815 | 3 279 377 | SE |
| Plzeň | 4 553 725 | 4 483 875 | 4 180 495 | V23 |
| Liberec | 3 693 000 ✅ | ~3 700 000 ✅ | 4 082 326 | – |
| Olomouc | ~6 280 680 ✅ | ~6 300 000 ✅ | 5 227 086 | – |
| Hradec Králové | ~5 742 840 ✅ | 5 531 000 ✅ | 4 580 972 | – |

### Výkon

| Metrika | V23 | V24 | SE v2.3 |
|---------|-----|-----|---------|
| Avg latence | **75 ms** | **85 ms** | 239 ms |
| V23 vs V24 odchylka | — | 2.2% | — |
| SE vs V24 odchylka | — | — | 8.1% |
| R² BYT | 0.945 | **0.9478** | composite |
| R² DÚM | 0.918 | **0.9178** | composite |
| Geocoding pokrytí | 80+ měst ✅ | 80+ měst ✅ | 80+ měst ✅ |

---

## 6. DOPORUČENÁ STRATEGIE PRO PRODUKCI

```
IF město IN (Praha, Brno, Ostrava, Plzeň):
    → Použij V24 (85ms, R²=0.9478, nejpřesnější ML)
    → Pro batch/reporty: ai_comment=false

ELIF potřebuješ více jistoty OR regionální město:
    → Použij SE v2.3 (239ms, správný geocoding, konsenzus)
    → ai_comment=false VŽDY pro batch

ELIF top příležitost (>100K Kč podhodnocení):
    → Znalecký Panel :5112 (4min, 3 AI znalci, nejvyšší přesnost)

Pro real-time web UI:
    → V24 primary + SE jako confidence check
    → Zobraz: V24 cena + SE confidence score
```

---

## 7. SOUBORY A UMÍSTĚNÍ

```
Server: 46.224.121.179

/opt/czechai-shared/
├── czech_geocoder.py        # Geocoder modul (sdílený)
└── GEOCODER_README.md       # Tato dokumentace

/opt/cenova_mapa/
├── v23_serve_5153.py        # V23 API server
├── v23_serve_5153.py.bak    # Záloha před opravou
├── v24_serve_5154.py        # V24 API server
└── v24_serve_5154.py.bak    # Záloha před opravou

/opt/super-ensemble-v2/
└── ensemble_server.py       # SE v2.3 API server

PM2:
  cenova-mapa-v23  → id=67, port 5153
  cenova-mapa-v24  → id=73, port 5154
  super-ensemble-v2 → id=37, port 5111
```

---

## 8. TESTING

```bash
# Rychlý smoke test všech 3 modelů
ssh root@46.224.121.179 "
echo '=== V23 Liberec ===' && curl -s 'http://localhost:5153/api/estimate?typ=byt&mesto=Liberec&plocha=60' | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d[\"cena_m2\"], \"Kc/m2\")'
echo '=== V24 Hradec ===' && curl -s 'http://localhost:5154/api/estimate?typ=byt&mesto=Hradec+Kralove&plocha=60' | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d[\"cena_m2\"], \"Kc/m2\")'
echo '=== SE Olomouc ===' && curl -s 'http://localhost:5111/api/estimate?typ=byt&mesto=Olomouc&plocha=60&ai_comment=false' | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d[\"cena_m2\"], \"Kc/m2\")'
"
# Očekávané výsledky: V23~61k, V24~95k, SE~95k — NE 203k (Praha fallback)
```

---

## 9. ZNÁMÉ LIMITY A TODO

| Priorita | Issue | Řešení |
|----------|-------|--------|
| HIGH | Praha 3+kk: SE vrací 158k/m² vs V23/V24 225k/m² — rozdíl 30% | Backtest proti ČÚZK transakcím |
| MEDIUM | Dispozice v V24 přidává jen +2-7% (slabý signal) | Přidat etáž (floor) + stav (condition) jako trained features |
| MEDIUM | Geocoder: ~60 menších měst 5-10K obyvatel chybí | Přidat do CITY_COORDS + PSČ lookup |
| LOW | V23 vs V24 odchylka 2.2% — marginální rozdíl | Sloučit do jediného V25 modelu |
| LOW | SE latence 239ms | Cache frequently-requested city+type combos |

---

## 10. CHANGELOG

| Datum | Verze | Změna |
|-------|-------|-------|
| 2026-04-17 | V24 geocoder fix | Nahrazen 4-city dict sdíleným czech_geocoder.py (80+ měst) |
| 2026-04-17 | V23 geocoder fix | Stejná oprava jako V24 |
| 2026-04-15 | SE v2.3 | Přidány znalecké korekce + Market Intel |
| 2026-03-04 | V24 launch | Dispozice jako trained feature, R²=0.9478 |
| 2026-01-15 | V23 launch | Základní model, R²=0.945 |

---

*Generováno: Claude Code — CzechAI, 2026-04-17*