Bolig Tracker

Model & træfsikkerhed

Hvor godt rammer model-vurderingen — og hvor gør den ikke?

Vurdér en adresse

Skriv en adresse i Region Hovedstaden — den behøver ikke være til salg. Modellen bruger boligens egne oplysninger og de nærmeste udbudte boligers lokale data (station, støj, naboolag) som stedfæstelse.

udfyldes fra BBR — tjek at det stemmer, BBR kan dække et enkelt bygningsnummer frem for hele boligen
bruges som m² pr. værelse — om fx 100 m² er 2 store eller 5 små rum
udfyldes som estimat — ret hvis du kender det faktiske tal

Estimatet er lige så usikkert som resten af modellen (se “Typisk afvigelse” ovenfor) — og det kender hverken adressens stand, renoveringer eller udsigt. Stedfæstelsen (station, støj, naboolag) er lånt fra de nærmeste udbudte boliger, ikke målt på selve adressen. Brug det som en indikation, ikke en vurdering.

Sådan skal tallene læses

Model vs. udbudspris · hver prik er en bolig

Den stiplede linje er “model = udbudspris”. Prikker over linjen er udbudt højere end modellen vurderer, prikker under er udbudt lavere. Spredningen omkring linjen er modellens usikkerhed.

Fordeling af afvigelser · udbudt vs. model

Hvor rammer modellen godt? · typisk afvigelse pr. kommune og boligtype

Beregnet på boliger modellen faktisk bruger. Få handler i et område giver et mindre pålideligt tal — se antallet.

Boliger modellen holder udenfor

Nogle boliger er ikke almindelige familieboliger — husbåde uden grund, boliger med hjemfaldspligt, andelslignende handler, nedrivningsklare huse. De trækker modellen skæv, så de udelades af beregningen, og de får ingen vurdering på forsiden: en “under vurdering”-mærkat ville her ligne et røverkøb frem for en anden slags bolig.

“Billig kommune” er ikke grunden til at havne her. Modellen har sit eget niveau for hver af de 28 kommuner, så en helt normal bolig i Halsnæs eller Gribskov til 20.000 kr/m² passer lige så godt som en i København til 80.000. Kolonnen Ift. kommunen viser hver bolig målt mod medianen for netop dens kommune og boligtype: de udeladte ligger typisk på 0,3–0,5× eller 1,5–2× det normale lokalt.

Metode & forbehold

Modellen er en hedonisk regression: den forklarer kvadratmeterprisen (log) ud fra boligens egenskaber — størrelse, antal værelser, byggeår, etage, kælder, grund, energimærke, afstand til S-tog og metro, afstand til indkøb, skole og daginstitution, afstand til motorvej, vand og natur, trafikstøj på facaden (Lden i dB fra Miljøstyrelsens støjkortlægning), boligtype, kommune samt realiserede handler i nabolaget (tinglyste salg, justeret til nutidsniveau og matchet på størrelse og byggeår). Den er ridge-regulariseret, så enkeltfaktorer ikke kan løbe løbsk.

Faktorerne overlapper. Trafikstøj er målt for hver adresse, men gør målt på hele materialet ingen forskel på træfsikkerheden — en støjplaget vej er nemlig allerede billigere i de realiserede nabolagshandler, modellen sammenligner med. Først når de handler tages væk, kan man se støjen bære sin egen vægt. Den står derfor stærkest i områder med få sammenlignelige salg — og dB-tallet på den enkelte bolig er under alle omstændigheder en oplysning, der er værd at kende, uanset hvad den gør ved modellen.

Træfsikkerheden er målt med 5-fold krydsvalidering: modellen trænes på 4/5 af boligerne og vurderer den sidste femtedel, så en bolig aldrig hjælper med at forudsige sig selv. Tallet du ser er derfor et ærligt bud på, hvor galt den typisk rammer på en ny bolig — ikke hvor godt den passer til dem, den allerede har set. Efter første kørsel gentages den uden de mest atypiske boliger (robust genberegning), så enkelte særtilfælde ikke trækker hele niveauet.

Hvad modellen ikke kan se: stand og vedligehold, renoveringer, udsigt, planløsning, støj fra naboer, lys og orientering, haven, eller hvor godt boligen er præsenteret. Det er præcis den slags, der afgør de sidste ti-tyve procent — og forklarer hvorfor afvigelsen aldrig kommer ned i nul. Brug tallet som en indikation, ikke som en vurdering: det er ikke en ejendomsmæglervurdering, og det er ikke rådgivning.

Modellen i detaljer · for de teknisk nysgerrige

Det følgende er den præcise matematik bag afsnittet ovenfor — samme model, ned til hver formel. Koden er i model.js, delt uændret mellem forsiden og denne side.

Målvariabel

Modellen fitter y = ln(kr/m²), ikke prisen direkte — så en afvigelse på 10 % vejer ens for en ejerlejlighed til 3 mio. og en villa til 15 mio., i stedet for at store boliger dominerer fejlmålet.

Features

Hver bolig bliver til en vektor x. Basisdelen er altid med; resten kun når den pågældende datakilde findes i byggets datasæt (alt-eller-intet pr. bygning, ikke pr. bolig).

FeatureFormelBetingelse
Konstant1altid
Arealln(a)altid
Areal²ln(a)²altid — fanger ikke-lineær kr/m²-effekt af størrelse
Værelserraltid, 0 hvis ukendt
Værelsesstørrelsea / (40·r)altid, 0 hvis a eller r mangler
Byggeår(år − 1970) / 50altid, 1970 (dvs. 0) hvis ukendt
Etageetage / 5kun ejerlejlighed (villa = 0); medianetagen hvis ukendt
Kælder1[kælder > 0]altid
Grundln(grund + 1) / 10kun villa (en lejligheds »grund« er hele matriklen); mediangrunden hvis ukendt
Energimærkerang(e) / 7altid — A=7…G=1, D-niveau (4) hvis ukendt
Afstand til S-togln(dS-tog + 1) / 10altid
Tæt på S-tog1[nær S-togsstation]altid
Boligtype1[villa]altid — ejerlejlighed er basislinjen
Altan/terrasse1[altan]altid
Afstand til metroln(dmetro + 1) / 10kun hvis byggets datasæt har metrodata
Tæt på metro1[≤ 500 m fra metro]samme betingelse som ovenfor
Lokalt benchmarkln(comp) / 12kun hvis realiserede handler findes — se “Lokalt benchmark” nedenfor
Afstand til indkøb/skole/institutionln(d + 1) / 10 ×3kun hvis POI-data findes (#7)
Afstand til motorvej/vand/sø/naturln(d + 1) / 10 ×4kun hvis geo-data findes (#8)
Vandkant-effektexp(−dkyst / 150)samme betingelse — et fald over ~150 m, ikke en lige linje: forskellen på første og anden række til vandet er et spring, ikke en gradient
Vandkant × villaexp(−dkyst / 150) · 1[villa]samme — en villa med have til vandet er mere værd end en lejlighed med udsigt
Trafikstøj(dB − 55) / 10kun hvis støjdata findes — se forbeholdet ovenfor
Kommune1[kommune = k] × (antal kommuner − 1)altid — én kommune er basislinjen, for ikke at kollidere med konstanten

Lokalt benchmark er ikke en rå gennemsnitspris i området: hvert salg er tidsjusteret til i dag med regionens eget kvartalsindeks, matchet på boligtype, størrelse og byggeår, og de nærmeste salg vægtes efter afstand frem for en hård radius — så et tyndt datagrundlag falder gradvist tilbage på kommune-/typemedianen i stedet for at springe til en 2 km-median. Konkret er det en vægtet median af de K nærmeste tidsjusterede salg, med vægt w aftagende i afstand d (halveret ved 500 m):

comp=vægtet median( {(vj,wj)} ,j=1…K) wj= 11+dj/500
Ridge-regression
β^ = arg minβ ∑in (yi−xi⋅β)2 +λ ∑jp βj2
// løses som de normale ligninger, ikke ved iterativ optimering:
(XTX+λI) β=XTy ,λ=1
// I er identitetsmatricen med et 0 i første celle — konstantledet straffes ikke

Løses direkte ved Gauss-elimination med delvis pivotering (partial pivoting), ikke gradient descent — designmatricen er lille nok (typisk 15–55 kolonner) til at det er både hurtigere og eksakt. Ridge-leddet λΣβⱼ² trækker koefficienterne mod 0, så en enkelt, tyndt repræsenteret feature ikke kan få et vilkårligt stort udslag på et lille datagrundlag.

Krydsvalidering — den ærlige træfsikkerhed

Boligerne deles i 5 lige store, faste grupper. For hver gruppe trænes modellen uden den gruppe og forudsiger så netop de udeladte boliger — en bolig er derfor aldrig med til at forudsige sig selv:

fold(i)=i mod 5

“Typisk afvigelse” er medianen af den absolutte procentfejl på tværs af alle fem grupper (hver bolig scoret af den model, der ikke så den under træning); usikkerhedsspændet er 10. og 90. percentil af de samme residualer:

typisk afvigelse= mediani∈test | eyi−y^i −1 |

Forklaringsgraden (R²) nedenfor er ikke beregnet krydsvalideret — se forbeholdet nederst.

Robust genberegning

Modellen fittes først på alle boliger; residualerne y − Xβ₀ giver en median m₀ og en MAD (median absolut afvigelse fra medianen). Faktoren 1,4826 skalerer MAD til at svare til én standardafvigelse under en normalfordeling:

m0=median(ri) MAD=median(|ri−m0|) |ri−m0| >3⋅1.4826⋅MAD ⇒udelades

Modellen genberegnes på resten. Det er præcis de boliger, der vises i “Boliger modellen holder udenfor” ovenfor.

Om R² — en vigtig forskel

R² beregnes på det endelige, robuste fit — altså hvor godt modellen rammer boliger, den selv har trænet på (mængden keep), ikke nye boliger den ikke har set:

R2=1− ∑i∈keep (yi−y^i)2 ∑i∈keep (yi−y‾)2

Det er derfor et andet tal end “typisk afvigelse” (som er krydsvalideret) og kan ikke bruges som et mål for reel træfsikkerhed alene. Flere features vil næsten altid løfte R² lidt, selv når de reelt intet bidrager med — jo flere frihedsgrader, jo bedre kan modellen tilpasse sig data den allerede kender. Det er præcis derfor krydsvalideret “typisk afvigelse”, ikke R², er det tal der afgør om en ny feature bliver i modellen eller fjernes igen.