% Author: Simon-Pierre Boucher — contact@spboucher.ai
% ============================================================================
\section{Methodology: the design of the horse race}
\label{sec:method}

The comparison is organised so that each design choice varies while
everything else is held fixed. All models price the same sales from the
same attribute set; only the functional mapping changes.

\subsection{The four axes}

\paragraph{A. Functional form.} With municipality and quarter fixed
effects and the base attributes (floor area, lot area, building age,
storeys, units, property class, physical configuration), we estimate:
(A1) fully linear in levels; (A2) semi-log, $\ln P$ on levels
\citep{malpezzi2003hedonic}; (A3) log-log, $\ln P$ on logged areas;
(A4) Box--Cox on the price, with $\lambda$ chosen by profile likelihood
on the training set over a grid \citep{box1964analysis,
halvorsen1981choice}; (A5) semi-log with quadratics in area and age; and
(A6) semi-log with cubic $B$-splines (six knots) in area, age and lot.

\paragraph{B. Time effects.} On the A5 backbone: no time controls,
year fixed effects, quarter fixed effects, month fixed effects ---
the granularity ladder of the time-dummy index literature
\citep{hill2013hedonic}.

\paragraph{C. Spatial controls.} On the A5 backbone with quarter FE:
no spatial controls, municipality FE (1{,}115), a $\sim$5.5~km grid
(5{,}255 cells), and a $\sim$1.1~km grid (30{,}548 cells) --- a
granularity ladder that brackets the bias--variance trade-off in
absorbing location \citep{case2004modeling, bourassa2010predicting}.

\paragraph{D. Estimation method.} Holding the attribute set fixed:
(D1) OLS with municipality and month FE; (D2) cross-validated ridge on
the same standardized design; (D3) a random forest
\citep{breiman2001random} and (D4) gradient boosting
\citep{friedman2001greedy} on the attributes plus raw coordinates and a
continuous month counter; (D5) gradient boosting \emph{without}
coordinates, to price what spatial flexibility is worth to the machine;
and (D6) a spatial $k$-nearest-neighbour comparables rule --- the
distance-weighted price per square metre of the ten nearest training
sales --- as the na\"ive appraiser benchmark.

\subsection{One scoreboard: price levels}

Comparing forms whose dependent variables differ requires care. Every
model is scored on \emph{predicted price levels}: log models are
retransformed with Duan's smearing factor estimated on training
residuals \citep{duan1983smearing}; Box--Cox predictions are analytically
inverted; level predictions are floored at \$20{,}000. We report the
median and mean absolute percentage errors (MdAPE, MAPE) --- the
automated-valuation industry's standards \citep{steurer2021metrics,
iaao2013standard} --- together with the RMSE and $R^2$ of log predicted
versus log actual prices, which are well-defined for every model.

\subsection{Two holdouts}

Each model is evaluated under two splits. The \emph{random} split holds
out 20\% of sales (seeded). The \emph{forward-in-time} split trains on
sales before January 2025 (355{,}824) and tests on 2025--2026
(158{,}388) --- the deployment situation of any valuation model. Static
models carry no forecast of the price level, so we apply the standard
carry-forward rule: unseen time categories in the test period are priced
at the last level observed in training; the machine-learning models
receive the same information through the clamped month counter. Random
cross-validation lets every model interpolate the price level of its own
test period --- the forward split reveals how much of measured accuracy
is such leakage \citep{mullainathan2017machine, clapp2002predicting}.

\subsection{Estimation details}

All linear models are estimated as sparse ridge regressions with a
vanishing penalty ($\alpha = 10^{-6}$) --- numerically OLS, but robust to
collinear dummies, and unseen categories at prediction time are priced at
the reference level. Dummies are one-hot with a dropped reference; the
ridge (D2) standardizes columns and cross-validates
$\alpha \in [10^{-6}, 10^{2}]$. The forest uses 120 trees
(minimum leaf 5, half the features per split); the boosting machine uses
600 trees of at most 63 leaves (learning rate 0.08, minimum leaf 20).
Hyper-parameters were fixed a priori at library-conventional values ---
the exercise compares model \emph{classes} as used in practice, not tuned
frontier performance.
