% Author: Simon-Pierre Boucher — contact@spboucher.ai % ============================================================================ \section{The horse race} \label{sec:results} Table~\ref{tab:race_random} reports the full scoreboard under the random holdout (411{,}283 training sales, 102{,}929 test sales); Table~\ref{tab:race_temporal} repeats it under the forward-in-time split. Figures~\ref{fig:forms}--\ref{fig:methods} visualize each axis. \begin{table}[p] \centering \begin{threeparttable} \caption{The scoreboard, random 80/20 holdout} \label{tab:race_random} \small \input{../results/tables/horserace_random} \begin{tablenotes}[flushleft]\footnotesize \item \textit{Notes:} All metrics on the held-out 20\% (102{,}929 sales). MdAPE/MAPE: median/mean absolute percentage error on price levels (log models retransformed with Duan smearing; Box--Cox inverted). RMSE$_{\ln}$ and $R^2_{\ln}$: computed on log predicted vs.\ log actual prices. Backbone rows repeat across axes by construction (A5 $=$ B3 $=$ C2; B4 $=$ D1). Bold: best in axis. \end{tablenotes} \end{threeparttable} \end{table} \begin{table}[p] \centering \begin{threeparttable} \caption{The scoreboard, forward-in-time holdout} \label{tab:race_temporal} \small \input{../results/tables/horserace_temporal} \begin{tablenotes}[flushleft]\footnotesize \item \textit{Notes:} Training on sales before January 2025 (355{,}824); testing on 2025--2026 (158{,}388). Unseen time categories are priced at the last training period (carry-forward); the machine-learning models receive the same information through the clamped month counter. \end{tablenotes} \end{threeparttable} \end{table} \subsection{Axis A: functional form is second-order} Under the random split (Figure~\ref{fig:forms}), the six forms span 16.5--18.6\% MdAPE. The spline specification wins (16.5\%), the log-log is second (17.0\%) --- floor area enters multiplicatively, as intuition suggests --- and the linear, semi-log and quadratic forms cluster within half a point of each other. The Box--Cox transformation selects $\hat\lambda = 0.25$ by profile likelihood (Table~\ref{tab:boxcox}), i.e.\ the data reject both the linear ($\lambda=1$) and the log ($\lambda=0$) --- and then \emph{underperforms} the simple semi-log out of sample (18.6\%), because optimizing curvature in-sample does not survive prediction, precisely the warning of \citet{cassel1985cost} and \citet{cropper1988choice}. The ordering is preserved under the temporal split. Two free lessons: curvature in \emph{attributes} (splines) is worth more than curvature in the \emph{price} (Box--Cox); and no form choice moves the needle by more than two points. \begin{figure}[t] \centering \includegraphics[width=0.85\textwidth]{fig_forms.png} \caption{Axis A --- functional form. MdAPE on the random holdout; municipality and quarter fixed effects and the base attribute set held fixed throughout.} \label{fig:forms} \end{figure} \begin{table}[t] \centering \begin{threeparttable} \caption{Box--Cox profile likelihood} \label{tab:boxcox} \small \input{../results/tables/boxcox} \begin{tablenotes}[flushleft]\footnotesize \item \textit{Notes:} $^{\dagger}$Thousands, relative to the maximum (zero = chosen $\lambda$). Estimated on the random-split training sample with the A-axis design. \end{tablenotes} \end{threeparttable} \end{table} \subsection{Axis B: time controls --- anything beats nothing} Omitting time controls entirely costs three points (21.1\% versus 18.1\%) in a window containing a boom, a correction and a recovery (Figure~\ref{fig:time}). But the granularity ladder flattens immediately: year, quarter and month effects are indistinguishable to within a quarter point under the random split. Under the temporal split the ordering inverts at the bottom --- \emph{no} time effects (25.4\%) is the worst choice again, but month effects with carry-forward (20.3\%) beat quarter effects (20.5\%) only marginally: once the level must be extrapolated, fine within-sample time resolution has little to offer. \begin{figure}[t] \centering \includegraphics[width=0.85\textwidth]{fig_time.png} \caption{Axis B --- time effects (quadratic semi-log backbone, municipality FE). MdAPE on the random holdout.} \label{fig:time} \end{figure} \subsection{Axis C: spatial controls are first-order --- up to a point} Location dominates every other design margin (Figure~\ref{fig:space}). Stripping all spatial controls costs \emph{ten} points (27.9\% versus 17.5\%) --- five times the entire functional-form range. The granularity ladder, however, is non-monotonic: the $\sim$5.5~km grid (5{,}255 cells, 17.5\%) beats municipality effects (18.1\%), but the $\sim$1.1~km grid (30{,}548 cells, 19.4\%) \emph{overfits} --- its cells average seventeen K sales each, unseen cells in the holdout revert to the baseline, and estimated effects are noisy. The optimal spatial resolution is an interior solution, echoing \citet{goodman1998housing} on submarket definition: finer is better only while cells remain thick enough to estimate. \begin{figure}[t] \centering \includegraphics[width=0.85\textwidth]{fig_space.png} \caption{Axis C --- spatial controls (quadratic semi-log backbone, quarter FE). MdAPE on the random holdout.} \label{fig:space} \end{figure} \subsection{Axis D: the machines --- and what they actually buy} Under the random split (Figure~\ref{fig:methods}), gradient boosting posts 14.4\% and the random forest 14.6\%, against 16.5\% for the best linear model and 18.3\% for the textbook OLS: a 13--21\% error reduction, squarely in the range reported by the AVM literature \citep{mayer2019estimation, hong2020machine}. The decomposition rows identify the source. Boosting \emph{without coordinates} collapses to 23.2\% --- worse than plain OLS with municipality dummies --- so the machine's edge is overwhelmingly a flexible surface over space, not exotic structure--attribute interactions. Pure proximity without structure (the $k$-NN comparables rule, 21.2\%) fails too: it is the \emph{combination} of spatial flexibility with attribute adjustment that wins. The cross-validated ridge (16.7\%) confirms that regularizing the high-dimensional dummy design buys a little; it cannot manufacture the missing interactions. \begin{figure}[t] \centering \includegraphics[width=0.85\textwidth]{fig_methods.png} \caption{Axis D --- estimation methods on the identical attribute set. MdAPE on the random holdout.} \label{fig:methods} \end{figure} \subsection{The generalization gap: when the test set is the future} Table~\ref{tab:generalization} and Figure~\ref{fig:generalization} contain the paper's central result. Moving from the random to the forward-in-time split degrades every model --- the price level of 2025--26 must be carried forward, not interpolated --- but the degradation is systematically larger for the flexible methods. Gradient boosting loses 6.8 points of MdAPE (14.4 $\to$ 21.2) and the random forest 6.7, while the spline hedonic loses 2.6 (16.5 $\to$ 19.1) and the log-log 2.2. The ranking \emph{reverses}: the best linear models beat the machines on the median error in the deployment scenario, and tie them exactly on $R^2_{\ln}$ ($\approx 0.52$). The machines remain better on MAPE (29.7 versus 30.5), i.e.\ in the tails, but the headline random-validation gap --- the number the ML-valuation literature reports --- overstates their deployable advantage entirely. The lesson is methodological and general: for models whose job is to price the future, random cross-validation is the wrong experiment \citep{mullainathan2017machine, clapp2002predicting}. \begin{table}[t] \centering \begin{threeparttable} \caption{Random versus forward-in-time evaluation} \label{tab:generalization} \small \input{../results/tables/generalization} \begin{tablenotes}[flushleft]\footnotesize \item \textit{Notes:} Selected models (the backbone and the full D axis) under both splits. \end{tablenotes} \end{threeparttable} \end{table} \begin{figure}[t] \centering \includegraphics[width=0.85\textwidth]{fig_generalization.png} \caption{The generalization gap. MdAPE under the random holdout (filled circles) and the forward-in-time holdout (open squares); the grey segment joins the two evaluations of the same model.} \label{fig:generalization} \end{figure}