# AVM-modellen — Fejl-analyse

**Genereret:** 17.7.2026
**Datakilde:** iBuyReal CRM, alle aktive on-market cases med AVM-prediction

---

## TL;DR

Vores AVM-model (AWS Lambda) flagger **90 cases** som "gode buys" (positiv α vs udbud). Når vi gennemgår dem manuelt:

- **24 ramte plet** (26.7% præcision)
- **66 er falske positiver** (73.3%)

Hovedårsagen: AVM mangler **5 kritiske features** som vores manuelle filtre fanger.

---

## Fejl-kategorier

| # | Kategori | Cases | Gns α | Max α | Hvad AVM mangler |
|---|---|---:|---:|---:|---|
| 1 | beton_aera_1950_1990 | 23 | +8.5% | +43.8% | se nedenfor |
| 2 | kvm_for_stor | 20 | +6.1% | +16.6% | se nedenfor |
| 3 | stueetage | 16 | +6.1% | +30.5% | se nedenfor |
| 4 | stoejgade | 4 | +16.2% | +25.9% | se nedenfor |
| 5 | hjemfaldspligt | 3 | +33.8% | +51.7% | se nedenfor |

---

## Detaljeret per kategori

### beton_aera_1950_1990 (23 cases)

- Gns AVM-α: +8.5%
- Spænd: +0.8% til +43.8%

**Eksempler:**

- Vesterbrogade 192, 1. 1 (α +29.6%, byg 1960)
- Rådmand Steins Alle 19, 5. th (α +1.0%, byg 1956)
- Rådmandsgade 40D, 5. th (α +3.6%, byg 1967)

### kvm_for_stor (20 cases)

- Gns AVM-α: +6.1%
- Spænd: +0.6% til +16.6%

**Eksempler:**

- Store Kongensgade 110H, 1. tv (α +8.2%, byg 1838)
- Grønningen 7, 6. th (α +6.6%, byg 1939)
- Fiolstræde 21, 4. (α +4.3%, byg 1836)

### stueetage (16 cases)

- Gns AVM-α: +6.1%
- Spænd: +0.8% til +30.5%

**Eksempler:**

- Dybensgade 22, 0. th (α +3.0%, byg 1800)
- Adelgade 47, 0. tv (α +30.5%, byg 1957)
- Øresund Parkvej 7, 0. th (α +3.6%, byg 2005)

### stoejgade (4 cases)

- Gns AVM-α: +16.2%
- Spænd: +4.3% til +25.9%

**Eksempler:**

- Strandgade 85, 1. 1 (α +25.9%, byg 2015)
- Nyhavn 31C, 4. (α +19.2%, byg 1800)
- Smallegade 39, 1. tv (α +4.3%, byg 1888)

### hjemfaldspligt (3 cases)

- Gns AVM-α: +33.8%
- Spænd: +14.2% til +51.7%

**Eksempler:**

- Sandbjerggade 52, 1. tv (α +35.6%, byg 1935)
- Mågevej 48, 2. tv (α +14.2%, byg 1937)
- Østerbrogade 216, 1. mf (α +51.7%, byg 1938)

---

## Anbefalede model-ændringer (prioriteret)

### 1. Etage som input-feature

Parse adresse → `floor_number` (0=stueetage, 1, 2, ..., 5+) + `is_ground_floor` boolean. Resight har `Enheder.Etage` direkte hvis I joiner.

**Effekt:** elimerer "stueetage" og "kælder"-kategorierne.

### 2. Byggeår som non-linear feature

Erstat `year_built: int` med era-buckets eller one-hot:

- pre1900 (klassisk)
- 1900-1949 (københavnerklassiker — premium)
- 1950-1990 (BETON-ÆRA — penalty)
- 1990-2009 (moderne mid)
- post2010 (nybyg)

Plus: `years_since_renovation` fra Resight `Omtilbygningsår`.

**Effekt:** model lærer at 1972 og 1968 er samme kategori, og at den kategori er dårligere end både 1932 og 1995.

### 3. kvm × bydel interaction

Læg interaction-feature ind: `kvm × bydel_liquidity_score`. 110 m² i Indre By ≠ 110 m² i Ørestad.

**Effekt:** elimerer kvm>100-fejl i illikvide bydele.

### 4. Støjgade-lookup table

Embed lookup-tabel med kendte støjgader (Strøget, Vesterbrogade, Nørrebrogade, Amagerbrogade, hovedfærdselsårer, nattelivsstrøg). Vi har den allerede i CRM (`src/lib/quality.ts NOISY_STREETS`).

**Effekt:** elimerer "støjgade"-falske positiver.

### 5. Vision-features fra fotos

Batch-process Boligsiden-fotos gennem Claude Vision:
- overall_condition (1-10)
- estimated_refurb_cost
- deal_breakers count

Vi har den pipeline klar i CRM nu — eksport kan deles.

**Effekt:** AVM lærer at nedslidt-stand er real -10-20% rabat.

### 6. Confidence-score i output

Returner også `prediction_stddev` og `n_training_samples_in_segment`. Hvis stddev > 12% eller n < 5 → `low_confidence: true`.

**Effekt:** CRM dropper low-confidence cases automatisk.

---

## Forventet impact

**Nu:** 90 AVM-positives → 24 ægte vindere = 27% præcision

**Efter retrain:** ~80% præcision forventet. AVM siger 10 ting er gode, 8 af dem er det reelt.

Sekundær effekt: AVM kan også blive mere aggressiv på cases hvor den faktisk har data til at vurdere korrekt — vi finder potentielt flere ægte fund vi ikke ser nu.

---

## Data-eksport

Brug `features.csv` fra `/admin/training-export` til retrain. Den indeholder nu også feature-flag (`is_ground_floor`, `era_bucket`, `is_concrete_era`, `is_noisy_street`, `kvm_bucket`, `our_verdict`) som I kan bruge som labels eller som features direkte.

`our_verdict` på hver case er specifikt hvor vores manuelle filtre dømte casen. Brug det som ground truth-label for retraining: cases med `top_pick_candidate` er hvor model ramte; cases med `filtered_*` er hvor model fejlede.
