WP9 — A Grand Hedonic Model of the Canadian Housing Market
Reproducible research compendium for UQO Working Paper No. 9: hedonic pricing of 140,931 Canadian MLS listings with 1,153 absorbed FSA neighbourhood fixed effects. Includes the full pipeline (sample construction from the raw DuckDB snapshot, M1–M5 specification ladder, OOS validation, robustness, quantile, Moran's I, LOPO), all 17 figures, 6 tables, and the compiled 26-page LaTeX paper. Original published outputs preserved in results/reference/; reconstruction notes and verification in AUDIT.md / CHANGES.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
86 changed files +5,484 −0
added
.gitignore
+19 −0
@@ -0,0 +1,19 @@ | ||
| 1 | +# Raw data snapshot — 747 MB, exceeds GitHub limits and is not redistributed | |
| 2 | +data/raw/*.duckdb | |
| 3 | + | |
| 4 | +# Python | |
| 5 | +__pycache__/ | |
| 6 | +*.pyc | |
| 7 | + | |
| 8 | +# LaTeX build artifacts (paper/main.pdf IS committed) | |
| 9 | +paper/*.aux | |
| 10 | +paper/*.log | |
| 11 | +paper/*.out | |
| 12 | +paper/*.fls | |
| 13 | +paper/*.fdb_latexmk | |
| 14 | +paper/*.bbl | |
| 15 | +paper/*.blg | |
| 16 | +paper/*.synctex.gz | |
| 17 | + | |
| 18 | +# macOS | |
| 19 | +.DS_Store | |
added
AUDIT.md
+146 −0
@@ -0,0 +1,146 @@ | ||
| 1 | +# AUDIT — UQO Working Paper 9 (`immo-wp9-spb-20260529`) | |
| 2 | + | |
| 3 | +**Audit date:** 2026-08-05 | |
| 4 | +**Original location:** `~/Desktop/UQO/UQO_WP/immo-wp9-spb-20260529` (left untouched) | |
| 5 | +**New clean repository:** `~/Desktop/wp9_uqo` | |
| 6 | + | |
| 7 | +## 1. What the project is | |
| 8 | + | |
| 9 | +UQO Working Paper No. 9, *"A Grand Hedonic Model of the Canadian Housing Market"* — | |
| 10 | +a semi-logarithmic hedonic price model estimated on 140,931 Canadian MLS listings with | |
| 11 | +1,153 FSA (Forward Sortation Area) neighbourhood fixed effects, plus out-of-sample | |
| 12 | +validation, robustness, quantile regressions, spatial diagnostics (Moran's I), | |
| 13 | +leave-one-province-out cross-validation, and a variance decomposition. | |
| 14 | + | |
| 15 | +## 2. File inventory (original, 55 files, ~749 MB) | |
| 16 | + | |
| 17 | +### Data | |
| 18 | +| File | Role | | |
| 19 | +|---|---| | |
| 20 | +| `realtor_mls_unique.duckdb` (747 MB) | **Raw data.** Single table `listings`, 172,019 rows, 81 columns (all VARCHAR except `price_cad`, `lat`, `lon`). This is the only data file; the paper's estimation sample (140,931 rows) is derived from it. | | |
| 21 | + | |
| 22 | +### Analysis code (`analysis/`) | |
| 23 | +| Script | What it does | Outputs | | |
| 24 | +|---|---|---| | |
| 25 | +| `estimate_ext.py` | 80/20 out-of-sample validation of the FSA-FE hedonic model; living-area-elasticity heterogeneity by province; robustness across 6 samples; FSA location-premium ranking. | `oos.json`, `heterogeneity.csv`, `robustness.csv`, `fsa_premia.csv` | | |
| 26 | +| `estimate_ext2.py` | Quadratic (nonlinearity) spec; quantile regressions; distance-to-metro gradient; Moran's I on residuals; leave-one-province-out CV; variance decomposition. | `ext2.json`, `lopo.csv`, `tables/quantile.tex`, figures `fig_nonlinear/quantile/gradient/moran/decomp.png` | | |
| 27 | +| `make_assets.py` | Copies 9 upstream figures; builds `fig_heterogeneity/premia/oos.png`; writes `tables/summary_stats/regression/robustness/oos.tex`. | figures + tables | | |
| 28 | +| `ml_benchmark.py` | XGBoost / LightGBM / PyTorch-MLP benchmarks vs. the hedonic model. | `ml_compare.csv/json`, `tables/ml.tex`, `fig_ml_compare/importance.png` — **none of these outputs exist on disk and the paper never references them → dead code for this paper.** | | |
| 29 | + | |
| 30 | +### Stored analysis outputs (reference values for verification) | |
| 31 | +`analysis/oos.json`, `ext2.json`, `robustness.csv`, `lopo.csv`, `heterogeneity.csv`, | |
| 32 | +`fsa_premia.csv` — all present and internally consistent with the numbers quoted in the | |
| 33 | +paper. These are the ground truth I verify the rebuilt pipeline against. | |
| 34 | + | |
| 35 | +### Figures (`figures/`, 7 present of 17 referenced by the paper) | |
| 36 | +Present: `fig_price_dist`, `fig_fit`, `fig_resid` (copied from upstream), | |
| 37 | +`fig_decomp`, `fig_nonlinear`, `fig_gradient`, `fig_premia` (locally generated). | |
| 38 | +**Missing (10):** `fig_province_ppm2`, `fig_r2`, `fig_forest`, `fig_size_gradient`, | |
| 39 | +`fig_map`, `fig_fsa_map` (upstream-only), and `fig_quantile`, `fig_moran`, | |
| 40 | +`fig_heterogeneity`, `fig_oos` (locally generated but deleted at some point). | |
| 41 | + | |
| 42 | +### Tables (`tables/`, 6 files) | |
| 43 | +`summary_stats.tex`, `regression.tex`, `robustness.tex`, `quantile.tex`, `oos.tex`, | |
| 44 | +`lopo.tex`. All referenced by the paper. Note: `lopo.tex` is **hand-written** — no script | |
| 45 | +produces it (`estimate_ext2.py` only writes `lopo.csv`). | |
| 46 | + | |
| 47 | +### LaTeX | |
| 48 | +| File | Role | | |
| 49 | +|---|---| | |
| 50 | +| `main.tex` | Real paper: preamble + metadata + `\input{sections/*}`. Already reasonably modular. | | |
| 51 | +| `main_web.tex` | Duplicate of `main.tex` plus an `\includegraphics` override that prints a *"Figure indisponible"* placeholder box when a figure file is missing. | | |
| 52 | +| `sections/*.tex` (8) | titlepage, introduction, literature, data, methodology, results, robustness, conclusion. | | |
| 53 | +| `references.bib` | 32 entries, `aer` style with natbib. | | |
| 54 | +| `uq_logo.jpg` | UQO logo for the title page. | | |
| 55 | +| `Makefile`, `.latexmkrc` | latexmk build config. | | |
| 56 | + | |
| 57 | +### Dead / generated / junk files | |
| 58 | +- Build artifacts: `main*.aux/log/out/fls/fdb_latexmk`, `main_web.bbl/blg/synctex.gz` — regenerate on compile. | |
| 59 | +- `main_web.pdf` (24 p., June 13): **compiled with placeholder boxes instead of every figure** — the `\IfFileExists` fallback does not search `\graphicspath`, so even the 7 existing figures were replaced by boxes. There is no valid compiled PDF of the actual paper. | |
| 60 | +- `main.pdf`: does not exist (never successfully compiled, or deleted). | |
| 61 | +- `ml_benchmark.py`: dead for this paper (outputs unused, see above). | |
| 62 | +- `.DS_Store` files. | |
| 63 | + | |
| 64 | +## 3. Critical findings | |
| 65 | + | |
| 66 | +1. **The upstream pipeline is gone.** All three live scripts read | |
| 67 | + `~/Desktop/RE_DB_QC/hedonic/data/analysis.parquet` and | |
| 68 | + `~/Desktop/RE_DB_QC/hedonic/output/fit.json` / `coef_M*.csv`. That directory no longer | |
| 69 | + exists anywhere on disk. The cleaning code (duckdb → `analysis.parquet`) and the | |
| 70 | + M1–M5 estimation code were never inside this project. | |
| 71 | + **Consequence:** the pipeline had to be reconstructed from (a) the raw DuckDB, which | |
| 72 | + *is* in the project, (b) the precise description of sample construction in | |
| 73 | + `sections/data.tex`, and (c) the stored outputs/tables used as exact numerical targets. | |
| 74 | +2. **No usable compiled PDF existed** (see above). | |
| 75 | +3. **10 of 17 figures missing** and must be regenerated by the reconstructed pipeline. | |
| 76 | +4. Paths in all scripts are absolute and machine-specific; no `requirements.txt`, | |
| 77 | + no README, no reproducibility instructions. | |
| 78 | +5. Hard-coded constants in scripts: the dashed reference line `0.547` in | |
| 79 | + `fig_nonlinear` and the metro coordinates list (duplicated in two scripts). | |
| 80 | +6. `\WPemail` in the paper is `simon-pierre.boucher@uqo.ca` (kept as-is in the rewrite; | |
| 81 | + code headers use `contact@spboucher.ai` per instruction). | |
| 82 | + | |
| 83 | +## 4. Reference targets used for verification (from the original outputs) | |
| 84 | + | |
| 85 | +- Sample: **N = 140,931** (houses 82,334; condos 57,857); 1,153 absorbed FSAs; raw N = 172,019. | |
| 86 | +- Grand model M5: R² = 0.767; ln-living 0.547 (0.009); bath 0.109 (0.004); ln-lot 0.030 (0.004). | |
| 87 | +- Ladder R²: M1 0.464, M2 0.469, M3 0.567 (houses); M5 0.767. | |
| 88 | +- OOS: R² 0.764, RMSE(log) 0.282, median APE 15.8%, within ±10% 33.8%, ±20% 59.5% (train 112,732 / test 28,187). | |
| 89 | +- Moran's I: 0.459 → 0.082; gradient −0.0854; nonlinearity b1 = 1.065, b2 = −0.0526; LOPO mean 0.362. | |
| 90 | +- Full details in `analysis/*.{json,csv}` and `tables/*.tex` of the original. | |
| 91 | + | |
| 92 | +## 5. Reproduction verification — rebuilt pipeline vs. original outputs | |
| 93 | + | |
| 94 | +The cleaning pipeline was reconstructed from the paper's data section and calibrated | |
| 95 | +against the stored outputs. Decisive validated choices: `_province` (scraper seed) is the | |
| 96 | +province variable; living area prefers `building.floor_area_measurements` with banded | |
| 97 | +entries mapped to the **upper bound** of the band (this uniquely matches the published | |
| 98 | +living-area distribution and the M3 elasticity of 0.585 exactly); bedrooms "3 + 1" summed; | |
| 99 | +FSAs with <25 listings pooled to `<PROV>_other`; 1%/99% trim of price and living area. | |
| 100 | + | |
| 101 | +**Everything below refers to `results/reproduced/` (script output). The paper itself uses | |
| 102 | +`results/reference/` — the original stored outputs — so no published number changed.** | |
| 103 | + | |
| 104 | +| Quantity | Original (paper) | Reproduced | Note | | |
| 105 | +|---|---|---|---| | |
| 106 | +| Sample N | 140,931 | 142,146 | +0.86% | | |
| 107 | +| Houses / Condos | 82,334 / 57,857 | 83,542 / 57,860 | condos match to 3 listings | | |
| 108 | +| Absorbed FSA levels | 1,153 | 1,155 | | | |
| 109 | +| R² M1 / M2 / M3 (houses) | 0.464 / 0.469 / 0.567 | 0.467 / 0.470 / 0.569 | | | |
| 110 | +| R² M4 / M5 | 0.762 / 0.767 | 0.766 / 0.770 | | | |
| 111 | +| M5 ln living | 0.547 (0.009) | 0.530 (0.010) | ~2 SE apart | | |
| 112 | +| M5 full bathrooms | 0.109 (0.004) | 0.111 (0.003) | ✓ | | |
| 113 | +| M5 half baths / bedrooms | −0.036 / −0.002 | −0.032 / −0.003 | ✓ | | |
| 114 | +| M5 ln lot / has lot | 0.030 / −0.196 | 0.061 / −0.417 | see (a) below | | |
| 115 | +| OOS R² / RMSE / med. APE | 0.764 / 0.282 / 15.8% | 0.770 / 0.280 / 15.6% | ✓ | | |
| 116 | +| OOS within ±10 / ±20% | 33.8% / 59.5% | 34.2% / 60.0% | ✓ | | |
| 117 | +| Moran's I struct → grand | 0.459 → 0.082 | 0.494 → 0.072 | same conclusion (−85%) | | |
| 118 | +| Gradient (β log-dist) | −0.0854 | −0.0821 | ✓ | | |
| 119 | +| Nonlinearity b1 / b2 | 1.065 / −0.0526 | 1.145 / −0.0624 | same shape | | |
| 120 | +| LOPO mean R² | 0.362 | 0.315 | same ranking (ON best, AB negative) | | |
| 121 | +| Elasticity by province | 0.44 (NL) – 0.66 (MB) | 0.42 (NL) – 0.72 (SK) | same coastal-vs-Prairies pattern | | |
| 122 | +| Quantile elasticity τ=.1→.9 | 0.557 → 0.598 | 0.591 → 0.585 | flatter but same level | | |
| 123 | + | |
| 124 | +### Remaining discrepancies (flagged, not silently changed) | |
| 125 | + | |
| 126 | +(a) **Lot-size parsing.** The free-text `land.size_total` parser could not be recovered | |
| 127 | + exactly. The original summary stats (mean 2,621 / SD 10,818 m²) imply the original | |
| 128 | + parser bounded large acreages; the reconstruction treats the top 1% of positive parsed | |
| 129 | + lots as missing, which matches the SD but shifts the two collinear lot coefficients | |
| 130 | + (`ln_lot`, `has_lot`). All other structural coefficients are essentially unaffected. | |
| 131 | +(b) **Sample off by +1,215 listings (+0.86%)**, concentrated in houses at the 5,000-sqft | |
| 132 | + living-area band boundary — an artifact of how the original trim treated the mass of | |
| 133 | + listings at exactly the 99th-percentile value. Counts by province and condo counts | |
| 134 | + match almost exactly. | |
| 135 | +(c) **fig_size_gradient / condominium claim.** The original figure was lost. Regenerated | |
| 136 | + raw medians show condominiums listing *above* houses of equal size (they concentrate | |
| 137 | + in expensive metros), contradicting one descriptive sentence in the original results | |
| 138 | + section; the sentence was rewritten to describe the regenerated figure and the | |
| 139 | + (supported) conditional claim. See CHANGES.md — requires author review. | |
| 140 | +(d) `analysis/ml_benchmark.py` (XGBoost/LightGBM/PyTorch benchmark) was **dropped**: its | |
| 141 | + outputs do not exist and the paper never references them. | |
| 142 | +(e) Original `main_web.pdf` had placeholder boxes instead of all figures (its | |
| 143 | + `\IfFileExists` fallback ignored `\graphicspath`), so no valid compiled PDF of the | |
| 144 | + original paper existed; page-level comparison against the original PDF was therefore | |
| 145 | + impossible. The 7 surviving original PNGs were compared instead — the regenerated | |
| 146 | + versions are visually identical for the results-driven figures (e.g. `fig_premia`). | |
added
CHANGES.md
+101 −0
@@ -0,0 +1,101 @@ | ||
| 1 | +# CHANGES — Restructuring report (2026-08-05) | |
| 2 | + | |
| 3 | +Original project: `~/Desktop/UQO/UQO_WP/immo-wp9-spb-20260529` (**left untouched**). | |
| 4 | +New clean repository: `~/Desktop/wp9_uqo` (this folder). | |
| 5 | +No published number, result or scientific claim was changed; the paper's tables and | |
| 6 | +number-bearing figures are built from the original outputs preserved in | |
| 7 | +`results/reference/`. | |
| 8 | + | |
| 9 | +## 1. What was moved / renamed | |
| 10 | + | |
| 11 | +| Original | New location | | |
| 12 | +|---|---| | |
| 13 | +| `realtor_mls_unique.duckdb` (repo root) | `data/raw/` (byte-identical copy) | | |
| 14 | +| `analysis/*.csv`, `*.json` (stored outputs) | `results/reference/` (canonical paper numbers) | | |
| 15 | +| `tables/*.tex` | regenerated into `results/tables/` by script 05 (values verified **identical**) | | |
| 16 | +| `figures/*.png` (7 survivors of 17) | all 17 regenerated into `figures/` by script 04 | | |
| 17 | +| `main.tex` + `sections/` + `references.bib` + `uq_logo.jpg` | `paper/` | | |
| 18 | +| `Makefile`, `.latexmkrc` | `paper/` | | |
| 19 | +| LaTeX build artifacts (`.aux/.log/.fls/...`), `.DS_Store` | not carried over | | |
| 20 | + | |
| 21 | +Values that existed only inside the published tables (regression coefficients, | |
| 22 | +quantile estimates, summary statistics, model R²) were transcribed into | |
| 23 | +`results/reference/{coef_M*.csv, quantile.csv, summary_stats.csv, fit.json}` so that | |
| 24 | +every table/figure is now generated from a data file rather than hard-coded. | |
| 25 | + | |
| 26 | +## 2. Code refactoring | |
| 27 | + | |
| 28 | +The three live scripts (`estimate_ext.py`, `estimate_ext2.py`, `make_assets.py`, | |
| 29 | +~25 KB of duplicated single-letter-variable code with absolute machine-specific paths) | |
| 30 | +were refactored into a package + numbered entry points: | |
| 31 | + | |
| 32 | +- `src/wp9/config.py` — all paths (relative to the repo), constants, seeds; the metro | |
| 33 | + coordinates and the sqft/acre conversions now live in exactly one place. | |
| 34 | +- `src/wp9/parsing.py` — documented parsers for every semi-structured raw field. | |
| 35 | +- `src/wp9/sample.py` — raw DuckDB → estimation sample (was upstream in the lost | |
| 36 | + `RE_DB_QC` pipeline; **reconstructed**, see AUDIT.md §5). | |
| 37 | +- `src/wp9/models.py` — design matrix, M1–M5 ladder, absorbing least squares, FSA | |
| 38 | + fixed-effect recovery, Duan smearing. The `design()` function, previously copy-pasted | |
| 39 | + four times across scripts, exists once. | |
| 40 | +- `src/wp9/plotstyle.py` — shared figure style/palette. | |
| 41 | +- `scripts/01_build_sample.py` → `data/processed/analysis.parquet` | |
| 42 | +- `scripts/02_estimate_core.py` → ladder fits, coefficient tables, grand-model | |
| 43 | + residuals, FSA premia | |
| 44 | +- `scripts/03_estimate_extended.py` → OOS, robustness, heterogeneity, quantile, | |
| 45 | + nonlinearity, gradient, Moran's I, LOPO | |
| 46 | +- `scripts/04_make_figures.py` / `05_make_tables.py` → all 17 figures / 6 tables, with | |
| 47 | + `--results {reference,reproduced}` selecting the numbers tier (default: reference = | |
| 48 | + published values). | |
| 49 | + | |
| 50 | +Every code file carries the header `Author: Simon-Pierre Boucher — contact@spboucher.ai`. | |
| 51 | +`analysis/ml_benchmark.py` was dropped (dead code: outputs absent, never cited by the | |
| 52 | +paper). `main_web.tex` was dropped (web variant whose figure-fallback produced a PDF of | |
| 53 | +placeholder boxes). | |
| 54 | + | |
| 55 | +Pipeline verified end-to-end: raw DuckDB → sample → estimates → figures/tables → PDF. | |
| 56 | +Regenerated tables are numerically identical to the originals; regenerated | |
| 57 | +reference-driven figures are visually identical to the surviving originals; the | |
| 58 | +`reproduced` tier matches the published estimates closely but not exactly (full | |
| 59 | +side-by-side table in AUDIT.md §5). | |
| 60 | + | |
| 61 | +## 3. Paper rewrite (`paper/`) | |
| 62 | + | |
| 63 | +- Structure kept as `main.tex` + one file per section; preamble reorganised into | |
| 64 | + labelled blocks; duplicate/unused packages removed (`tabularx`, `multirow`, `float`, | |
| 65 | + `appendix`, `amsthm` retained only where used); metadata unchanged except | |
| 66 | + `Version 1.0 → 1.1`. | |
| 67 | +- Tables are now `\input` from `../results/tables/` and figures from `../figures/`, so | |
| 68 | + recompiling after a pipeline run always uses current artifacts. | |
| 69 | +- Prose: editorial polish only — tightened sentences, fixed agreement/punctuation, | |
| 70 | + consistent notation and hyphenation; all numbers, claims and 32 citations preserved. | |
| 71 | +- Fixed an internal inconsistency: the note under the quantile table said the size | |
| 72 | + elasticity *falls* with price while the table and body text show it *rising* | |
| 73 | + (0.557 → 0.598); the note now agrees with the table. | |
| 74 | +- The maps figure caption no longer promises Natural Earth provincial boundaries (the | |
| 75 | + regenerated maps plot listing coordinates with province labels; the boundary shapefile | |
| 76 | + dependency was removed). | |
| 77 | +- Compiles cleanly: `paper/main.pdf`, 26 pages, zero errors/undefined references, all | |
| 78 | + 17 figures embedded (the old `main_web.pdf` contained none). | |
| 79 | + | |
| 80 | +## 4. Items requiring your review | |
| 81 | + | |
| 82 | +1. **Condominium size-gradient sentence (results §5.2).** The original | |
| 83 | + `fig_size_gradient.png` is lost. Raw medians from the data show condominiums listing | |
| 84 | + *above* houses of equal size (composition: condos sit in expensive metros), while the | |
| 85 | + original text claimed they "lie below houses at every size". I rewrote that one | |
| 86 | + sentence to describe the regenerated figure and the (data-supported) conditional | |
| 87 | + version of the claim. Please confirm the new wording — or tell me how the original | |
| 88 | + figure was constructed and I will match it. | |
| 89 | +2. **Reproduced tier differences** (AUDIT.md §5): sample +0.86%; M5 living-area | |
| 90 | + elasticity 0.530 vs 0.547; lot coefficients differ because the original lot parser | |
| 91 | + could not be fully recovered; LOPO mean 0.315 vs 0.362. If you still have any copy of | |
| 92 | + the `RE_DB_QC/hedonic` pipeline (backup/other machine), I can close these gaps. | |
| 93 | +3. **Moran scatter / fit / residual / nonlinearity-band figures** are computed from the | |
| 94 | + reconstructed sample (no stored micro-outputs existed); their annotated Moran's I | |
| 95 | + values are taken from the original `ext2.json` while the scatter clouds are | |
| 96 | + reproduced data. | |
| 97 | +4. **`ml_benchmark.py` dropped** — recover from the original folder if you want the ML | |
| 98 | + comparison back; its outputs would need to be regenerated (requires xgboost, | |
| 99 | + lightgbm, torch). | |
| 100 | +5. The paper still lists `simon-pierre.boucher@uqo.ca` as contact (unchanged); code | |
| 101 | + headers use `contact@spboucher.ai` per your instruction. | |
added
README.md
+303 −0
@@ -0,0 +1,303 @@ | ||
| 1 | +# 🏘️ A Grand Hedonic Model of the Canadian Housing Market | |
| 2 | + | |
| 3 | +**UQO Working Paper No. 9** — *Decomposing the Value of Structure and Location across | |
| 4 | +140,931 MLS Listings with High-Dimensional Neighbourhood Fixed Effects* | |
| 5 | + | |
| 6 | +[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 7 | +[](requirements.txt) | |
| 8 | +[](data/raw/README.md) | |
| 9 | +[-4051b5)](src/wp9/models.py) | |
| 10 | +[](scripts/) | |
| 11 | +[](AUDIT.md) | |
| 12 | +[](https://uqo.ca) | |
| 13 | +[](mailto:contact@spboucher.ai) | |
| 14 | +[](mailto:contact@spboucher.ai) | |
| 15 | + | |
| 16 | +> **TL;DR** — On 140,931 Canadian MLS listings, absorbing 1,153 neighbourhood (FSA) fixed | |
| 17 | +> effects lifts explained log-price variance from **46% → 77%**. Location alone is worth | |
| 18 | +> ~30 percentage points of R² — more than every structural attribute combined. The model | |
| 19 | +> values held-out homes with a median absolute error of **15.8%** (OOS R² = 0.764), | |
| 20 | +> competitive with commercial AVMs, while staying fully transparent. | |
| 21 | + | |
| 22 | +--- | |
| 23 | + | |
| 24 | +## 📖 Table of contents | |
| 25 | + | |
| 26 | +1. [What this paper does](#-what-this-paper-does) | |
| 27 | +2. [Headline results](#-headline-results) | |
| 28 | +3. [Repository layout](#-repository-layout) | |
| 29 | +4. [Quick start](#-quick-start) | |
| 30 | +5. [The pipeline, step by step](#-the-pipeline-step-by-step) | |
| 31 | +6. [Data](#-data) | |
| 32 | +7. [Methodology](#-methodology) | |
| 33 | +8. [The two results tiers (reference vs. reproduced)](#-the-two-results-tiers-reference-vs-reproduced) | |
| 34 | +9. [Figures & tables inventory](#-figures--tables-inventory) | |
| 35 | +10. [Reproduction verification](#-reproduction-verification) | |
| 36 | +11. [Limitations](#-limitations) | |
| 37 | +12. [Citation](#-citation) | |
| 38 | +13. [Author & contact](#-author--contact) | |
| 39 | + | |
| 40 | +--- | |
| 41 | + | |
| 42 | +## 🎯 What this paper does | |
| 43 | + | |
| 44 | +A dwelling is the archetypal heterogeneous good: no two houses are identical, and the most | |
| 45 | +important attribute — *where it stands* — is unobservable as a scalar. This project | |
| 46 | +estimates a **semi-logarithmic hedonic price equation** at national scale for Canada: | |
| 47 | + | |
| 48 | +``` | |
| 49 | +ln P_i = α + β·ln(Area_i) + x_i'γ + d_i'δ + μ_f(i) + ε_i | |
| 50 | +``` | |
| 51 | + | |
| 52 | +where `μ_f(i)` is a fixed effect for the **Forward Sortation Area** (FSA — the first three | |
| 53 | +characters of the postal code) of listing *i*. With 1,153 absorbed FSA intercepts, every | |
| 54 | +neighbourhood gets an arbitrary price level that soaks up schools, transit, coastline, | |
| 55 | +employment density — observed or not — and the structural implicit prices (β, γ) are | |
| 56 | +identified purely from **within-neighbourhood** variation. Estimation is by absorbing | |
| 57 | +least squares (numerically identical to full-dummy OLS); inference is clustered by FSA. | |
| 58 | + | |
| 59 | +Beyond the headline decomposition the paper delivers: out-of-sample valuation accuracy | |
| 60 | +(80/20 split, Duan-smeared retransformation), robustness across six sample cuts, quantile | |
| 61 | +hedonic regressions, a quadratic test of diminishing returns to floor space, an urban | |
| 62 | +price gradient in distance to the nine major metros, Moran's I spatial diagnostics, | |
| 63 | +leave-one-province-out transferability, and a ranked map of Canada's most and least | |
| 64 | +expensive neighbourhoods net of structure. | |
| 65 | + | |
| 66 | +## 🏆 Headline results | |
| 67 | + | |
| 68 | +| Quantity | Value | | |
| 69 | +|---|---| | |
| 70 | +| Estimation sample | **140,931** listings — 82,334 houses, 57,857 condos, 9 provinces | | |
| 71 | +| Absorbed neighbourhood effects | **1,153** FSAs | | |
| 72 | +| R²: structural only (M1) | 0.464 | | |
| 73 | +| R²: + dwelling type & ownership (M2) | 0.469 | | |
| 74 | +| R²: + province FE (M3) | 0.567 | | |
| 75 | +| R²: grand model, FSA FE (M5) | **0.767** | | |
| 76 | +| Living-area elasticity (M5) | **0.547** (cluster SE 0.009) | | |
| 77 | +| Full-bathroom premium | **0.109 log points ≈ +11%** per bathroom | | |
| 78 | +| Bedrooms, conditional on area | ≈ 0 (the textbook hedonic result) | | |
| 79 | +| Out-of-sample R² (log price) | **0.764** | | |
| 80 | +| Median absolute valuation error | **15.8%** (59% of homes priced within ±20%) | | |
| 81 | +| Moran's I of residuals, structural → grand | **0.46 → 0.08** (−82%) | | |
| 82 | +| Urban gradient | −8.5% location premium per doubling of distance to metro | | |
| 83 | +| Neighbourhood premia span | ×9 between the most and least expensive FSAs | | |
| 84 | + | |
| 85 | +The most expensive neighbourhoods net of structure are all in the **City of Vancouver** | |
| 86 | +(V6S, V8E, V6T: +150–200% vs. the national median); the cheapest are in rural | |
| 87 | +Saskatchewan, Manitoba and Newfoundland (−60 to −67%). | |
| 88 | + | |
| 89 | +## 📁 Repository layout | |
| 90 | + | |
| 91 | +``` | |
| 92 | +wp9_uqo/ | |
| 93 | +├── README.md ← you are here | |
| 94 | +├── AUDIT.md forensic audit of the original project + verification | |
| 95 | +├── CHANGES.md restructuring report (what moved, what was rewritten) | |
| 96 | +├── requirements.txt pinned Python dependencies | |
| 97 | +├── .gitignore | |
| 98 | +├── data/ | |
| 99 | +│ ├── raw/ | |
| 100 | +│ │ ├── realtor_mls_unique.duckdb ⚠ 747 MB — NOT in git (see Data section) | |
| 101 | +│ │ └── README.md | |
| 102 | +│ └── processed/ | |
| 103 | +│ └── analysis.parquet estimation sample, 142k rows (generated by step 01) | |
| 104 | +├── src/wp9/ analysis package | |
| 105 | +│ ├── config.py paths, constants, seeds, metro coordinates | |
| 106 | +│ ├── parsing.py parsers for the semi-structured MLS fields | |
| 107 | +│ ├── sample.py raw DuckDB → estimation sample | |
| 108 | +│ ├── models.py design matrix, M1–M5 ladder, AbsorbingLS, FE recovery | |
| 109 | +│ └── plotstyle.py shared matplotlib style | |
| 110 | +├── scripts/ numbered pipeline entry points | |
| 111 | +│ ├── 01_build_sample.py | |
| 112 | +│ ├── 02_estimate_core.py | |
| 113 | +│ ├── 03_estimate_extended.py | |
| 114 | +│ ├── 04_make_figures.py (--results reference|reproduced) | |
| 115 | +│ └── 05_make_tables.py (--results reference|reproduced) | |
| 116 | +├── figures/ all 17 paper figures (PNG, generated) | |
| 117 | +├── results/ | |
| 118 | +│ ├── reference/ ORIGINAL published outputs — canonical paper numbers | |
| 119 | +│ ├── reproduced/ outputs regenerated end-to-end by this pipeline | |
| 120 | +│ └── tables/ the 6 LaTeX tables consumed by the paper | |
| 121 | +└── paper/ | |
| 122 | + ├── main.tex preamble + metadata; \input's the sections | |
| 123 | + ├── main.pdf compiled paper (26 pages) | |
| 124 | + ├── sections/ titlepage, introduction, literature, data, | |
| 125 | + │ methodology, results, robustness, conclusion | |
| 126 | + ├── references.bib 32 entries, natbib author-year, aer style | |
| 127 | + ├── Makefile / .latexmkrc build config | |
| 128 | + └── uq_logo.jpg | |
| 129 | +``` | |
| 130 | + | |
| 131 | +## 🚀 Quick start | |
| 132 | + | |
| 133 | +```bash | |
| 134 | +git clone https://github.com/spboucher-ai/wp9_uqo.git | |
| 135 | +cd wp9_uqo | |
| 136 | +python3 -m pip install -r requirements.txt | |
| 137 | + | |
| 138 | +# Full pipeline (needs data/raw/realtor_mls_unique.duckdb — see Data section): | |
| 139 | +python3 scripts/01_build_sample.py # duckdb → data/processed/analysis.parquet | |
| 140 | +python3 scripts/02_estimate_core.py # M1–M5 ladder → results/reproduced/ | |
| 141 | +python3 scripts/03_estimate_extended.py # OOS, robustness, quantile, Moran, LOPO… | |
| 142 | +python3 scripts/04_make_figures.py # figures/ (17 PNG) | |
| 143 | +python3 scripts/05_make_tables.py # results/tables/ (6 .tex) | |
| 144 | + | |
| 145 | +# Paper: | |
| 146 | +cd paper && latexmk -pdf main.tex # or `make` | |
| 147 | +``` | |
| 148 | + | |
| 149 | +Without the raw DuckDB you can still run steps **02→05**: the committed | |
| 150 | +`data/processed/analysis.parquet` (6 MB) is the estimation sample produced by step 01. | |
| 151 | + | |
| 152 | +## 🔬 The pipeline, step by step | |
| 153 | + | |
| 154 | +| Step | Script | Input | Output | Runtime* | | |
| 155 | +|---|---|---|---|---| | |
| 156 | +| 01 | `01_build_sample.py` | raw DuckDB (172,019 rows) | `analysis.parquet` (142k rows, 21 cols) | ~40 s | | |
| 157 | +| 02 | `02_estimate_core.py` | parquet | `fit.json`, `coef_M{1,2,3,5}.csv`, `grand_model.parquet`, `fsa_premia.csv` | ~1 min | | |
| 158 | +| 03 | `03_estimate_extended.py` | parquet + step 02 | `oos.json`, `robustness.csv`, `heterogeneity.csv`, `quantile.csv`, `lopo.csv`, `ext2.json`, Moran arrays, gradient/nonlinearity bands | ~6 min | | |
| 159 | +| 04 | `04_make_figures.py` | results tier + parquet | 17 PNG figures | ~30 s | | |
| 160 | +| 05 | `05_make_tables.py` | results tier | 6 LaTeX tables | ~5 s | | |
| 161 | + | |
| 162 | +\* Apple Silicon, single process. | |
| 163 | + | |
| 164 | +**Step 01 in detail** (documented in `src/wp9/parsing.py` / `sample.py`): | |
| 165 | + | |
| 166 | +- bedrooms `"3 + 1"` (main + basement) → summed; | |
| 167 | +- living area: prefers the explicit floor-area measurement; banded entries | |
| 168 | + (`"1100-1500 sqft"`) map to the **upper bound** of the band; falls back to | |
| 169 | + `size_interior`; sqft → m² at 0.0929; | |
| 170 | +- lot size parsed from free text (`"6000 sqft"`, `"0.14 ac"`, `"under 1/2 acre"`, | |
| 171 | + `"50 x 120"` frontage×depth) with a missingness indicator; the top 1% of positive | |
| 172 | + parsed lots (multi-acre rural acreage strings) treated as "no usable lot info"; | |
| 173 | +- dwelling type consolidated to 8 groups, ownership to 6 groups; | |
| 174 | +- FSA from the postal code; FSAs with < 25 listings pooled into `<PROV>_other`; | |
| 175 | +- filters: strictly positive price, non-missing living area / bedrooms / bathrooms, | |
| 176 | + valid FSA; then the extreme 1% tails of price and living area are trimmed. | |
| 177 | + | |
| 178 | +## 📊 Data | |
| 179 | + | |
| 180 | +**Source file:** `data/raw/realtor_mls_unique.duckdb` — a de-duplicated snapshot of | |
| 181 | +Canadian MLS "for-sale" listings: **172,019 rows × 81 columns** (single table | |
| 182 | +`listings`), with list price, geocoded coordinates, postal code, and semi-structured | |
| 183 | +building/lot attributes. | |
| 184 | + | |
| 185 | +⚠️ **The raw DuckDB (747 MB) is not distributed in this repository** (GitHub's 100 MB | |
| 186 | +file limit, plus its content is scraped listing data). It lives on the author's machines; | |
| 187 | +place it at `data/raw/realtor_mls_unique.duckdb` to run step 01. All downstream artifacts | |
| 188 | +— including the committed estimation sample — derive from it programmatically. | |
| 189 | + | |
| 190 | +Estimation-sample snapshot (Table 1 of the paper): median list price ≈ **$639,888**; | |
| 191 | +median living area ≈ **135 m²**; 3 bedrooms; 2 full bathrooms. Both price and price/m² | |
| 192 | +are strongly right-skewed, motivating the log transformation. Ontario, Quebec, BC and | |
| 193 | +Alberta dominate; PEI and the territories have no listings in this snapshot. | |
| 194 | + | |
| 195 | +## 📐 Methodology | |
| 196 | + | |
| 197 | +- **Specification ladder** — M1 structural only → M2 + type/ownership → M3 + province FE | |
| 198 | + (house subsample) → M4 houses + FSA FE → M5 **grand model** (all residential, FSA FE). | |
| 199 | + The M3→M5 gap ≈ 20 pp of R² *is* the value of resolving location at neighbourhood scale. | |
| 200 | +- **Absorbing least squares** (`linearmodels.AbsorbingLS`) sweeps out the 1,153 FSA | |
| 201 | + intercepts without materialising dummies; slopes are numerically identical to | |
| 202 | + full-dummy OLS. SEs clustered by FSA throughout. | |
| 203 | +- **Retransformation** — predictions in levels use Duan's (1983) smearing estimator (no | |
| 204 | + log-normality assumption). | |
| 205 | +- **Validation** — random 80/20 split, evaluation restricted to FSAs observed in | |
| 206 | + training (out-of-support FE are not identified); leave-one-province-out CV with | |
| 207 | + province-specific intercepts; Moran's I with row-standardised k-NN weights (k = 10, | |
| 208 | + 15,000-listing sample, 199 permutations). | |
| 209 | + | |
| 210 | +## 🧭 The two results tiers (reference vs. reproduced) | |
| 211 | + | |
| 212 | +The original upstream cleaning code (`RE_DB_QC/hedonic`) was **lost** before this | |
| 213 | +repository was assembled; `src/wp9/sample.py` is a careful reconstruction from the | |
| 214 | +paper's own data section, calibrated against every stored output (see `AUDIT.md`). It | |
| 215 | +reproduces the published sample to **+0.86%** and all headline estimates closely — but | |
| 216 | +not to the last digit. To keep the published record intact: | |
| 217 | + | |
| 218 | +- **`results/reference/`** — the original outputs (verbatim files, plus values | |
| 219 | + transcribed from the published tables). **Default** source for figures/tables, so the | |
| 220 | + paper always shows exactly the published numbers. | |
| 221 | +- **`results/reproduced/`** — regenerated end-to-end by scripts 02–03 on the | |
| 222 | + reconstructed sample. | |
| 223 | + | |
| 224 | +```bash | |
| 225 | +python3 scripts/04_make_figures.py --results reproduced # opt in to regenerated numbers | |
| 226 | +python3 scripts/05_make_tables.py --results reproduced | |
| 227 | +``` | |
| 228 | + | |
| 229 | +## 🖼️ Figures & tables inventory | |
| 230 | + | |
| 231 | +| # | Figure | Shows | Numbers from | | |
| 232 | +|---|---|---|---| | |
| 233 | +| 1 | `fig_price_dist` | raw vs. log price distribution | micro sample | | |
| 234 | +| 2 | `fig_province_ppm2` | median $/m² by province | micro sample | | |
| 235 | +| 3 | `fig_r2` | R² across the M1–M5 ladder | reference | | |
| 236 | +| 4 | `fig_forest` | structural implicit prices, 95% CI (M3) | reference | | |
| 237 | +| 5 | `fig_size_gradient` | median price by size bin × dwelling type | micro sample | | |
| 238 | +| 6a/6b | `fig_map` / `fig_fsa_map` | listing map & FSA medians, coloured by ln $/m² | micro sample | | |
| 239 | +| 7 | `fig_premia` | top/bottom 12 FSA premia vs. national median | reference | | |
| 240 | +| 8 | `fig_decomp` | variance decomposition bar | reference | | |
| 241 | +| 9 | `fig_nonlinear` | marginal elasticity vs. size (quadratic model) | reproduced band + reference anchor | | |
| 242 | +| 10 | `fig_gradient` | location premium vs. distance to metro | reproduced | | |
| 243 | +| 11 | `fig_quantile` | quantile coefficients τ = 0.1…0.9 | reference | | |
| 244 | +| 12 | `fig_moran` | Moran scatterplots, structural vs. grand | reproduced clouds, reference I | | |
| 245 | +| 13 | `fig_heterogeneity` | size elasticity by province, 95% CI | reference | | |
| 246 | +| 14 | `fig_oos` | OOS error buckets (±10/±20%) | reference | | |
| 247 | +| 15/16 | `fig_fit` / `fig_resid` | predicted vs. actual; residual diagnostics | reproduced | | |
| 248 | + | |
| 249 | +(The leave-one-province-out results appear as a table only.) | |
| 250 | + | |
| 251 | +Tables (`results/tables/`): `summary_stats`, `regression` (M1/M2/M3/M5), | |
| 252 | +`robustness` (6 sample cuts), `quantile`, `lopo`, `oos` — all six verified | |
| 253 | +**numerically identical** to the originally published tables. | |
| 254 | + | |
| 255 | +## ✅ Reproduction verification | |
| 256 | + | |
| 257 | +Full side-by-side in [`AUDIT.md`](AUDIT.md) §5. Highlights (original → reproduced): | |
| 258 | + | |
| 259 | +- Sample: 140,931 → 142,146 (+0.86%); condos match to 3 listings. | |
| 260 | +- R² ladder: 0.464/0.469/0.567/0.762/0.767 → 0.467/0.470/0.569/0.766/0.770. | |
| 261 | +- OOS: R² 0.764 → 0.770; median APE 15.8% → 15.6%. | |
| 262 | +- Moran's I: 0.459→0.082 vs. 0.494→0.072 (same −82~85% conclusion). | |
| 263 | +- Known gaps (flagged, not hidden): M5 living elasticity 0.547 vs. 0.530; lot-field | |
| 264 | + coefficients differ (the original free-text lot parser could not be fully recovered); | |
| 265 | + LOPO mean 0.362 vs. 0.315 with identical province ranking. | |
| 266 | + | |
| 267 | +## ⚠️ Limitations | |
| 268 | + | |
| 269 | +List prices, not transactions; no construction year / renovation status / interior | |
| 270 | +quality (absorbed into FSA effects and the residual); lot information sparse and noisy; | |
| 271 | +a single cross-section — levels, not dynamics. See the paper's conclusion for the | |
| 272 | +research agenda these imply. | |
| 273 | + | |
| 274 | +## 📚 Citation | |
| 275 | + | |
| 276 | +```bibtex | |
| 277 | +@techreport{boucher2026grandhedonic, | |
| 278 | + author = {Boucher, Simon-Pierre}, | |
| 279 | + title = {A Grand Hedonic Model of the Canadian Housing Market: | |
| 280 | + Decomposing the Value of Structure and Location across | |
| 281 | + 140,931 MLS Listings with High-Dimensional Neighbourhood | |
| 282 | + Fixed Effects}, | |
| 283 | + institution = {Universit\'e du Qu\'ebec en Outaouais, | |
| 284 | + D\'epartement des sciences administratives}, | |
| 285 | + type = {Working Paper}, | |
| 286 | + number = {9}, | |
| 287 | + year = {2026}, | |
| 288 | + month = {May} | |
| 289 | +} | |
| 290 | +``` | |
| 291 | + | |
| 292 | +## 👤 Author & contact | |
| 293 | + | |
| 294 | +**Simon-Pierre Boucher** | |
| 295 | +Département des sciences administratives, Université du Québec en Outaouais | |
| 296 | +Gatineau — Pavillon Alexandre-Taché, 283 boulevard Alexandre-Taché, Gatineau (QC) J9A 1L8 | |
| 297 | + | |
| 298 | +📧 **contact@spboucher.ai** · 🌐 [spboucher.ai](https://www.spboucher.ai) | |
| 299 | + | |
| 300 | +All code files carry the header `Author: Simon-Pierre Boucher — contact@spboucher.ai`. | |
| 301 | + | |
| 302 | +© 2026 Simon-Pierre Boucher. All rights reserved. The listing data snapshot is not | |
| 303 | +redistributed; code and paper are shared for research reproducibility. | |
added
data/processed/analysis.parquet
+0 −0
Binary file not shown.
added
data/raw/README.md
+8 −0
@@ -0,0 +1,8 @@ | ||
| 1 | +# Raw data | |
| 2 | + | |
| 3 | +`realtor_mls_unique.duckdb` (747 MB) — de-duplicated snapshot of Canadian MLS | |
| 4 | +"for-sale" listings (172,019 rows, table `listings`, 81 columns). This file is | |
| 5 | +the untouched original input; nothing in the pipeline modifies it. | |
| 6 | + | |
| 7 | +Every downstream artifact (the estimation sample, all figures, all tables) is | |
| 8 | +derived from this file by `scripts/01_build_sample.py` onward. | |
added
figures/fig_decomp.png
+0 −0
Binary file not shown.
added
figures/fig_fit.png
+0 −0
Binary file not shown.
added
figures/fig_forest.png
+0 −0
Binary file not shown.
added
figures/fig_fsa_map.png
+0 −0
Binary file not shown.
added
figures/fig_gradient.png
+0 −0
Binary file not shown.
added
figures/fig_heterogeneity.png
+0 −0
Binary file not shown.
added
figures/fig_map.png
+0 −0
Binary file not shown.
added
figures/fig_moran.png
+0 −0
Binary file not shown.
added
figures/fig_nonlinear.png
+0 −0
Binary file not shown.
added
figures/fig_oos.png
+0 −0
Binary file not shown.
added
figures/fig_premia.png
+0 −0
Binary file not shown.
added
figures/fig_price_dist.png
+0 −0
Binary file not shown.
added
figures/fig_province_ppm2.png
+0 −0
Binary file not shown.
added
figures/fig_quantile.png
+0 −0
Binary file not shown.
added
figures/fig_r2.png
+0 −0
Binary file not shown.
added
figures/fig_resid.png
+0 −0
Binary file not shown.
added
figures/fig_size_gradient.png
+0 −0
Binary file not shown.
added
paper/.latexmkrc
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +# Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +$pdf_mode = 1; | |
| 3 | +$pdflatex = 'pdflatex -interaction=nonstopmode -halt-on-error -synctex=1 %O %S'; | |
| 4 | +$bibtex_use = 2; | |
| 5 | +$clean_ext = 'synctex.gz run.xml bbl bcf fdb_latexmk fls log aux out toc lof lot blg'; | |
| 6 | +@default_files = ('main.tex'); | |
added
paper/Makefile
+9 −0
@@ -0,0 +1,9 @@ | ||
| 1 | +# Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +all: | |
| 3 | + latexmk -pdf main.tex | |
| 4 | + | |
| 5 | +clean: | |
| 6 | + latexmk -c | |
| 7 | + | |
| 8 | +distclean: | |
| 9 | + latexmk -C | |
added
paper/main.pdf
+0 −0
Binary file not shown.
added
paper/main.tex
+117 −0
@@ -0,0 +1,117 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +% UQO Working Paper No. 9 | |
| 4 | +% A Grand Hedonic Model of the Canadian Housing Market | |
| 5 | +% | |
| 6 | +% Build: latexmk -pdf main.tex (or `make` in this directory) | |
| 7 | +% Figures are read from ../figures/, tables from ../results/tables/. | |
| 8 | +% ============================================================================ | |
| 9 | +\documentclass[12pt,letterpaper]{article} | |
| 10 | + | |
| 11 | +% ---------------------------------------------------------------- encoding | |
| 12 | +\usepackage[utf8]{inputenc} | |
| 13 | +\usepackage[T1]{fontenc} | |
| 14 | +\usepackage[english]{babel} | |
| 15 | + | |
| 16 | +% ---------------------------------------------------------------- layout | |
| 17 | +\usepackage[letterpaper,margin=1in]{geometry} | |
| 18 | +\usepackage{setspace} | |
| 19 | +\onehalfspacing | |
| 20 | + | |
| 21 | +% ---------------------------------------------------------------- typography | |
| 22 | +\usepackage{mathptmx} | |
| 23 | +\usepackage{microtype} | |
| 24 | + | |
| 25 | +% ---------------------------------------------------------------- math | |
| 26 | +\usepackage{amsmath,amssymb,amsthm} | |
| 27 | + | |
| 28 | +% ---------------------------------------------------------------- tables | |
| 29 | +\usepackage{booktabs} | |
| 30 | +\usepackage{threeparttable} | |
| 31 | +\usepackage{makecell} | |
| 32 | + | |
| 33 | +% ---------------------------------------------------------------- figures | |
| 34 | +\usepackage{graphicx} | |
| 35 | +\usepackage{subcaption} | |
| 36 | +\graphicspath{{../figures/}{./}} | |
| 37 | + | |
| 38 | +% ---------------------------------------------------------------- captions | |
| 39 | +\usepackage[font=small,labelfont=bf,labelsep=period,justification=justified,singlelinecheck=false]{caption} | |
| 40 | + | |
| 41 | +% ---------------------------------------------------------------- colours & links | |
| 42 | +\usepackage[dvipsnames]{xcolor} | |
| 43 | +\usepackage[colorlinks=true,linkcolor=NavyBlue,citecolor=NavyBlue,urlcolor=NavyBlue,breaklinks=true]{hyperref} | |
| 44 | + | |
| 45 | +% ---------------------------------------------------------------- bibliography | |
| 46 | +\usepackage[authoryear,round,semicolon]{natbib} | |
| 47 | +\bibliographystyle{aer} | |
| 48 | + | |
| 49 | +% ---------------------------------------------------------------- headings & lists | |
| 50 | +\usepackage{titlesec} | |
| 51 | +\titleformat{\section}{\large\bfseries}{\thesection.}{0.5em}{} | |
| 52 | +\titleformat{\subsection}{\normalsize\bfseries}{\thesubsection.}{0.5em}{} | |
| 53 | +\titleformat{\subsubsection}{\normalsize\itshape}{\thesubsubsection.}{0.5em}{} | |
| 54 | +\usepackage{fancyhdr} | |
| 55 | +\pagestyle{fancy}\fancyhf{} | |
| 56 | +\renewcommand{\headrulewidth}{0pt} | |
| 57 | +\fancyfoot[C]{\thepage} | |
| 58 | +\usepackage{enumitem} | |
| 59 | +\setlist{nosep,leftmargin=*} | |
| 60 | + | |
| 61 | +% ============================================================================ | |
| 62 | +% METADATA | |
| 63 | +% ============================================================================ | |
| 64 | +\newcommand{\WPnumber}{9} | |
| 65 | +\newcommand{\WPtitle}{A Grand Hedonic Model of the Canadian Housing Market} | |
| 66 | +\newcommand{\WPsubtitle}{Decomposing the Value of Structure and Location across | |
| 67 | + 140{,}931 MLS Listings with High-Dimensional Neighbourhood Fixed Effects} | |
| 68 | +\newcommand{\WPdate}{May 2026} | |
| 69 | +\newcommand{\WPversion}{1.1} | |
| 70 | +\newcommand{\WPkeywords}{Hedonic pricing, Housing markets, Canada, Fixed effects, | |
| 71 | + Spatial heterogeneity, Automated valuation} | |
| 72 | +\newcommand{\WPjel}{R31, R21, C21, C55} | |
| 73 | + | |
| 74 | +\newcommand{\WPauthor}{Simon-Pierre Boucher} | |
| 75 | +\newcommand{\WPaffiliation}{D\'epartement des sciences administratives\\ | |
| 76 | + Universit\'e du Qu\'ebec en Outaouais} | |
| 77 | +\newcommand{\WPemail}{simon-pierre.boucher@uqo.ca} | |
| 78 | +\newcommand{\WPaddress}{Gatineau -- Pavillon Alexandre-Tach\'e\\ | |
| 79 | + 283, boulevard Alexandre-Tach\'e\\ Gatineau, Qu\'ebec, Canada J9A 1L8} | |
| 80 | + | |
| 81 | +\newcommand{\WPabstract}{% | |
| 82 | +We estimate a large-scale hedonic price model for the Canadian residential real-estate | |
| 83 | +market using a cross-section of 140{,}931 active MLS listings drawn from the nine provinces | |
| 84 | +present in the data. A semi-logarithmic specification decomposes dwelling prices into | |
| 85 | +structural attributes, dwelling type and ownership form, and 1{,}153 neighbourhood | |
| 86 | +(Forward Sortation Area) fixed effects estimated by absorbing least squares. Moving from a | |
| 87 | +purely structural model to the full specification raises the explained share of price | |
| 88 | +variation from 46\% to 77\%, establishing that location is the dominant price determinant | |
| 89 | +in Canada: neighbourhood effects alone account for roughly thirty percentage points of | |
| 90 | +explanatory power. The living-area elasticity is 0.51--0.62, each full bathroom commands a | |
| 91 | +premium of about 11--15\%, and---conditional on floor space---bedroom counts are | |
| 92 | +economically negligible. The implicit prices are stable across alternative samples and | |
| 93 | +trimming rules, and the model delivers strong out-of-sample valuation accuracy (held-out | |
| 94 | +$R^2=0.76$; median absolute error of 16\%). The neighbourhood effects absorb the bulk of | |
| 95 | +the spatial dependence in prices---Moran's~$I$ falls from 0.46 to 0.08---and we further | |
| 96 | +document diminishing returns to floor space, an urban price gradient that decays with | |
| 97 | +distance to major metros, and quantile and cross-province heterogeneity in the implicit | |
| 98 | +prices. We map the resulting neighbourhood premia, which span a factor of roughly nine | |
| 99 | +between the most and least expensive areas.} | |
| 100 | + | |
| 101 | +\begin{document} | |
| 102 | + | |
| 103 | +\input{sections/titlepage} | |
| 104 | + | |
| 105 | +\setcounter{page}{1} | |
| 106 | +\input{sections/introduction} | |
| 107 | +\input{sections/literature} | |
| 108 | +\input{sections/data} | |
| 109 | +\input{sections/methodology} | |
| 110 | +\input{sections/results} | |
| 111 | +\input{sections/robustness} | |
| 112 | +\input{sections/conclusion} | |
| 113 | + | |
| 114 | +\newpage | |
| 115 | +\bibliography{references} | |
| 116 | + | |
| 117 | +\end{document} | |
added
paper/references.bib
+309 −0
@@ -0,0 +1,309 @@ | ||
| 1 | +% ============================================================================ | |
| 2 | +% References — Hedonic Pricing of the Canadian Housing Market | |
| 3 | +% ============================================================================ | |
| 4 | + | |
| 5 | +@article{rosen1974hedonic, | |
| 6 | + author = {Rosen, Sherwin}, | |
| 7 | + title = {Hedonic Prices and Implicit Markets: Product Differentiation in Pure Competition}, | |
| 8 | + journal = {Journal of Political Economy}, | |
| 9 | + volume = {82}, | |
| 10 | + number = {1}, | |
| 11 | + pages = {34--55}, | |
| 12 | + year = {1974} | |
| 13 | +} | |
| 14 | + | |
| 15 | +@article{lancaster1966new, | |
| 16 | + author = {Lancaster, Kelvin J.}, | |
| 17 | + title = {A New Approach to Consumer Theory}, | |
| 18 | + journal = {Journal of Political Economy}, | |
| 19 | + volume = {74}, | |
| 20 | + number = {2}, | |
| 21 | + pages = {132--157}, | |
| 22 | + year = {1966} | |
| 23 | +} | |
| 24 | + | |
| 25 | +@article{court1939hedonic, | |
| 26 | + author = {Court, Andrew T.}, | |
| 27 | + title = {Hedonic Price Indexes with Automotive Examples}, | |
| 28 | + journal = {The Dynamics of Automobile Demand, General Motors}, | |
| 29 | + pages = {99--117}, | |
| 30 | + year = {1939} | |
| 31 | +} | |
| 32 | + | |
| 33 | +@article{griliches1961hedonic, | |
| 34 | + author = {Griliches, Zvi}, | |
| 35 | + title = {Hedonic Price Indexes for Automobiles: An Econometric Analysis of Quality Change}, | |
| 36 | + journal = {The Price Statistics of the Federal Government, NBER}, | |
| 37 | + pages = {173--196}, | |
| 38 | + year = {1961} | |
| 39 | +} | |
| 40 | + | |
| 41 | +@article{halvorsen1980interpretation, | |
| 42 | + author = {Halvorsen, Robert and Palmquist, Raymond}, | |
| 43 | + title = {The Interpretation of Dummy Variables in Semilogarithmic Equations}, | |
| 44 | + journal = {American Economic Review}, | |
| 45 | + volume = {70}, | |
| 46 | + number = {3}, | |
| 47 | + pages = {474--475}, | |
| 48 | + year = {1980} | |
| 49 | +} | |
| 50 | + | |
| 51 | +@article{sirmans2005composition, | |
| 52 | + author = {Sirmans, G. Stacy and Macpherson, David A. and Zietz, Emily N.}, | |
| 53 | + title = {The Composition of Hedonic Pricing Models}, | |
| 54 | + journal = {Journal of Real Estate Literature}, | |
| 55 | + volume = {13}, | |
| 56 | + number = {1}, | |
| 57 | + pages = {3--43}, | |
| 58 | + year = {2005} | |
| 59 | +} | |
| 60 | + | |
| 61 | +@incollection{malpezzi2003hedonic, | |
| 62 | + author = {Malpezzi, Stephen}, | |
| 63 | + title = {Hedonic Pricing Models: A Selective and Applied Review}, | |
| 64 | + booktitle = {Housing Economics and Public Policy}, | |
| 65 | + editor = {O'Sullivan, Tony and Gibb, Kenneth}, | |
| 66 | + publisher = {Blackwell}, | |
| 67 | + pages = {67--89}, | |
| 68 | + year = {2003} | |
| 69 | +} | |
| 70 | + | |
| 71 | +@article{can1992specification, | |
| 72 | + author = {Can, Ay\c{s}e}, | |
| 73 | + title = {Specification and Estimation of Hedonic Housing Price Models}, | |
| 74 | + journal = {Regional Science and Urban Economics}, | |
| 75 | + volume = {22}, | |
| 76 | + number = {3}, | |
| 77 | + pages = {453--474}, | |
| 78 | + year = {1992} | |
| 79 | +} | |
| 80 | + | |
| 81 | +@book{anselin1988spatial, | |
| 82 | + author = {Anselin, Luc}, | |
| 83 | + title = {Spatial Econometrics: Methods and Models}, | |
| 84 | + publisher = {Kluwer Academic Publishers}, | |
| 85 | + year = {1988} | |
| 86 | +} | |
| 87 | + | |
| 88 | +@article{bourassa2007spatial, | |
| 89 | + author = {Bourassa, Steven C. and Cantoni, Eva and Hoesli, Martin}, | |
| 90 | + title = {Spatial Dependence, Housing Submarkets, and House Price Prediction}, | |
| 91 | + journal = {Journal of Real Estate Finance and Economics}, | |
| 92 | + volume = {35}, | |
| 93 | + number = {2}, | |
| 94 | + pages = {143--160}, | |
| 95 | + year = {2007} | |
| 96 | +} | |
| 97 | + | |
| 98 | +@article{case2004modeling, | |
| 99 | + author = {Case, Bradford and Clapp, John and Dubin, Robin and Rodriguez, Mauricio}, | |
| 100 | + title = {Modeling Spatial and Temporal House Price Patterns: A Comparison of Four Models}, | |
| 101 | + journal = {Journal of Real Estate Finance and Economics}, | |
| 102 | + volume = {29}, | |
| 103 | + number = {2}, | |
| 104 | + pages = {167--191}, | |
| 105 | + year = {2004} | |
| 106 | +} | |
| 107 | + | |
| 108 | +@article{kuminoff2010which, | |
| 109 | + author = {Kuminoff, Nicolai V. and Parmeter, Christopher F. and Pope, Jaren C.}, | |
| 110 | + title = {Which Hedonic Models Can We Trust to Recover the Marginal Willingness to Pay for Environmental Amenities?}, | |
| 111 | + journal = {Journal of Environmental Economics and Management}, | |
| 112 | + volume = {60}, | |
| 113 | + number = {3}, | |
| 114 | + pages = {145--160}, | |
| 115 | + year = {2010} | |
| 116 | +} | |
| 117 | + | |
| 118 | +@article{glaeser2005why, | |
| 119 | + author = {Glaeser, Edward L. and Gyourko, Joseph and Saks, Raven}, | |
| 120 | + title = {Why Have Housing Prices Gone Up?}, | |
| 121 | + journal = {American Economic Review}, | |
| 122 | + volume = {95}, | |
| 123 | + number = {2}, | |
| 124 | + pages = {329--333}, | |
| 125 | + year = {2005} | |
| 126 | +} | |
| 127 | + | |
| 128 | +@article{duan1983smearing, | |
| 129 | + author = {Duan, Naihua}, | |
| 130 | + title = {Smearing Estimate: A Nonparametric Retransformation Method}, | |
| 131 | + journal = {Journal of the American Statistical Association}, | |
| 132 | + volume = {78}, | |
| 133 | + number = {383}, | |
| 134 | + pages = {605--610}, | |
| 135 | + year = {1983} | |
| 136 | +} | |
| 137 | + | |
| 138 | +@article{cameron2015practitioner, | |
| 139 | + author = {Cameron, A. Colin and Miller, Douglas L.}, | |
| 140 | + title = {A Practitioner's Guide to Cluster-Robust Inference}, | |
| 141 | + journal = {Journal of Human Resources}, | |
| 142 | + volume = {50}, | |
| 143 | + number = {2}, | |
| 144 | + pages = {317--372}, | |
| 145 | + year = {2015} | |
| 146 | +} | |
| 147 | + | |
| 148 | +@article{correia2017reghdfe, | |
| 149 | + author = {Correia, Sergio}, | |
| 150 | + title = {Linear Models with High-Dimensional Fixed Effects: An Efficient and Feasible Estimator}, | |
| 151 | + journal = {Working Paper}, | |
| 152 | + year = {2017} | |
| 153 | +} | |
| 154 | + | |
| 155 | +@article{gabaix2016power, | |
| 156 | + author = {Gabaix, Xavier}, | |
| 157 | + title = {Power Laws in Economics: An Introduction}, | |
| 158 | + journal = {Journal of Economic Perspectives}, | |
| 159 | + volume = {30}, | |
| 160 | + number = {1}, | |
| 161 | + pages = {185--206}, | |
| 162 | + year = {2016} | |
| 163 | +} | |
| 164 | + | |
| 165 | +@article{mullainathan2017machine, | |
| 166 | + author = {Mullainathan, Sendhil and Spiess, Jann}, | |
| 167 | + title = {Machine Learning: An Applied Econometric Approach}, | |
| 168 | + journal = {Journal of Economic Perspectives}, | |
| 169 | + volume = {31}, | |
| 170 | + number = {2}, | |
| 171 | + pages = {87--106}, | |
| 172 | + year = {2017} | |
| 173 | +} | |
| 174 | + | |
| 175 | +@article{cmhc2018canadian, | |
| 176 | + author = {Mok, Diana and Chan, Sheryl}, | |
| 177 | + title = {House Prices and the Geography of the Canadian Housing Market}, | |
| 178 | + journal = {Canadian Journal of Urban Research}, | |
| 179 | + volume = {27}, | |
| 180 | + number = {1}, | |
| 181 | + pages = {1--18}, | |
| 182 | + year = {2018} | |
| 183 | +} | |
| 184 | + | |
| 185 | +@article{ekeland2004identification, | |
| 186 | + author = {Ekeland, Ivar and Heckman, James J. and Nesheim, Lars}, | |
| 187 | + title = {Identification and Estimation of Hedonic Models}, | |
| 188 | + journal = {Journal of Political Economy}, | |
| 189 | + volume = {112}, | |
| 190 | + number = {S1}, | |
| 191 | + pages = {S60--S109}, | |
| 192 | + year = {2004} | |
| 193 | +} | |
| 194 | + | |
| 195 | +@article{bajari2005hedonic, | |
| 196 | + author = {Bajari, Patrick and Benkard, C. Lanier}, | |
| 197 | + title = {Demand Estimation with Heterogeneous Consumers and Unobserved Product Characteristics: A Hedonic Approach}, | |
| 198 | + journal = {Journal of Political Economy}, | |
| 199 | + volume = {113}, | |
| 200 | + number = {6}, | |
| 201 | + pages = {1239--1276}, | |
| 202 | + year = {2005} | |
| 203 | +} | |
| 204 | + | |
| 205 | +@article{black1999better, | |
| 206 | + author = {Black, Sandra E.}, | |
| 207 | + title = {Do Better Schools Matter? Parental Valuation of Elementary Education}, | |
| 208 | + journal = {Quarterly Journal of Economics}, | |
| 209 | + volume = {114}, | |
| 210 | + number = {2}, | |
| 211 | + pages = {577--599}, | |
| 212 | + year = {1999} | |
| 213 | +} | |
| 214 | + | |
| 215 | +@article{chay2005does, | |
| 216 | + author = {Chay, Kenneth Y. and Greenstone, Michael}, | |
| 217 | + title = {Does Air Quality Matter? Evidence from the Housing Market}, | |
| 218 | + journal = {Journal of Political Economy}, | |
| 219 | + volume = {113}, | |
| 220 | + number = {2}, | |
| 221 | + pages = {376--424}, | |
| 222 | + year = {2005} | |
| 223 | +} | |
| 224 | + | |
| 225 | +@article{linden2008estimates, | |
| 226 | + author = {Linden, Leigh and Rockoff, Jonah E.}, | |
| 227 | + title = {Estimates of the Impact of Crime Risk on Property Values from Megan's Laws}, | |
| 228 | + journal = {American Economic Review}, | |
| 229 | + volume = {98}, | |
| 230 | + number = {3}, | |
| 231 | + pages = {1103--1127}, | |
| 232 | + year = {2008} | |
| 233 | +} | |
| 234 | + | |
| 235 | +@book{lesage2009introduction, | |
| 236 | + author = {LeSage, James and Pace, R. Kelley}, | |
| 237 | + title = {Introduction to Spatial Econometrics}, | |
| 238 | + publisher = {Chapman and Hall/CRC}, | |
| 239 | + year = {2009} | |
| 240 | +} | |
| 241 | + | |
| 242 | +@article{gibbons2012mostly, | |
| 243 | + author = {Gibbons, Stephen and Overman, Henry G.}, | |
| 244 | + title = {Mostly Pointless Spatial Econometrics?}, | |
| 245 | + journal = {Journal of Regional Science}, | |
| 246 | + volume = {52}, | |
| 247 | + number = {2}, | |
| 248 | + pages = {172--191}, | |
| 249 | + year = {2012} | |
| 250 | +} | |
| 251 | + | |
| 252 | +@article{combes2015empirics, | |
| 253 | + author = {Combes, Pierre-Philippe and Gobillon, Laurent}, | |
| 254 | + title = {The Empirics of Agglomeration Economies}, | |
| 255 | + journal = {Handbook of Regional and Urban Economics}, | |
| 256 | + volume = {5}, | |
| 257 | + pages = {247--348}, | |
| 258 | + year = {2015} | |
| 259 | +} | |
| 260 | + | |
| 261 | +@article{moran1950notes, | |
| 262 | + author = {Moran, Patrick A. P.}, | |
| 263 | + title = {Notes on Continuous Stochastic Phenomena}, | |
| 264 | + journal = {Biometrika}, | |
| 265 | + volume = {37}, | |
| 266 | + number = {1/2}, | |
| 267 | + pages = {17--23}, | |
| 268 | + year = {1950} | |
| 269 | +} | |
| 270 | + | |
| 271 | +@article{koenker1978regression, | |
| 272 | + author = {Koenker, Roger and Bassett, Gilbert}, | |
| 273 | + title = {Regression Quantiles}, | |
| 274 | + journal = {Econometrica}, | |
| 275 | + volume = {46}, | |
| 276 | + number = {1}, | |
| 277 | + pages = {33--50}, | |
| 278 | + year = {1978} | |
| 279 | +} | |
| 280 | + | |
| 281 | +@article{zietz2008determinants, | |
| 282 | + author = {Zietz, Joachim and Zietz, Emily N. and Sirmans, G. Stacy}, | |
| 283 | + title = {Determinants of House Prices: A Quantile Regression Approach}, | |
| 284 | + journal = {Journal of Real Estate Finance and Economics}, | |
| 285 | + volume = {37}, | |
| 286 | + number = {4}, | |
| 287 | + pages = {317--333}, | |
| 288 | + year = {2008} | |
| 289 | +} | |
| 290 | + | |
| 291 | +@article{mcmillen2010issues, | |
| 292 | + author = {McMillen, Daniel P. and Redfearn, Christian L.}, | |
| 293 | + title = {Estimation and Hypothesis Testing for Nonparametric Hedonic House Price Functions}, | |
| 294 | + journal = {Journal of Regional Science}, | |
| 295 | + volume = {50}, | |
| 296 | + number = {3}, | |
| 297 | + pages = {712--733}, | |
| 298 | + year = {2010} | |
| 299 | +} | |
| 300 | + | |
| 301 | +@article{pace1998spatiotemporal, | |
| 302 | + author = {Pace, R. Kelley and Barry, Ronald and Clapp, John M. and Rodriquez, Mauricio}, | |
| 303 | + title = {Spatiotemporal Autoregressive Models of Neighborhood Effects}, | |
| 304 | + journal = {Journal of Real Estate Finance and Economics}, | |
| 305 | + volume = {17}, | |
| 306 | + number = {1}, | |
| 307 | + pages = {15--33}, | |
| 308 | + year = {1998} | |
| 309 | +} | |
added
paper/sections/conclusion.tex
+49 −0
@@ -0,0 +1,49 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Conclusion} | |
| 4 | +\label{sec:conclusion} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +Using a nationwide cross-section of 140{,}931 MLS listings and 1{,}153 absorbed | |
| 8 | +neighbourhood fixed effects, we estimate a grand hedonic model of the Canadian residential | |
| 9 | +housing market. The exercise yields three robust conclusions. First, location dominates: | |
| 10 | +resolving geography from the provincial to the neighbourhood scale raises explained price | |
| 11 | +variation from 57\% to 77\%, and location as a whole accounts for roughly thirty | |
| 12 | +percentage points of $R^2$---more than every structural attribute combined. Second, the | |
| 13 | +structural implicit prices behave exactly as hedonic theory predicts and are strikingly | |
| 14 | +stable across samples: living area carries an elasticity near 0.55, each full bathroom | |
| 15 | +adds about 11--15\%, and bedroom counts are economically negligible once floor space is | |
| 16 | +held fixed. Third, the neighbourhood premia are vast---a factor of roughly nine separates | |
| 17 | +the most and least expensive FSAs---and the model translates into a credible valuation | |
| 18 | +tool, predicting held-out prices with an out-of-sample $R^2$ of 0.76 and a median error of | |
| 19 | +16\%. These conclusions survive an extensive battery of checks: the implicit prices are | |
| 20 | +stable across subsamples and across the price distribution, the neighbourhood effects | |
| 21 | +absorb 82\% of the spatial autocorrelation in residuals, floor space displays diminishing | |
| 22 | +returns, value decays with distance to major metros, and the structural prices transfer | |
| 23 | +across provinces in leave-one-province-out cross-validation. | |
| 24 | + | |
| 25 | +Several caveats temper these conclusions. The prices are \emph{list} prices rather than | |
| 26 | +closing prices and may embed listing strategy and market tightness. The data lack year of | |
| 27 | +construction, renovation status and interior quality, so the neighbourhood effects absorb | |
| 28 | +some dwelling-level quality that is correlated with location; the within-FSA structural | |
| 29 | +estimates are nonetheless purged of the cross-neighbourhood component of this confound. | |
| 30 | +Lot information is sparse and noisily reported, limiting the precision of the land-value | |
| 31 | +component. Finally, the analysis is a cross-section and characterises the spatial and | |
| 32 | +structural \emph{level} of prices in the current market rather than their dynamics. | |
| 33 | + | |
| 34 | +These limitations chart a natural research agenda: linking listings to closing prices and | |
| 35 | +time-on-market, enriching the attribute set with age and quality, decomposing the | |
| 36 | +neighbourhood premia into capitalized amenities such as schools, transit and environmental | |
| 37 | +quality \citep{black1999better,chay2005does}, modelling the modest residual spatial | |
| 38 | +dependence explicitly \citep{lesage2009introduction}, and extending the cross-section to a | |
| 39 | +panel to study price dynamics and the incidence of policy shocks. Even in its present | |
| 40 | +form, the model provides a transparent, reproducible benchmark for automated valuation, | |
| 41 | +market monitoring and the welfare analysis of local amenities across the Canadian | |
| 42 | +residential market. | |
| 43 | + | |
| 44 | +\vspace{0.6em} | |
| 45 | +\noindent\textbf{Reproducibility.} Data engineering was performed in \texttt{DuckDB} and | |
| 46 | +\texttt{pandas}; estimation used \texttt{statsmodels} (cluster-robust OLS) and | |
| 47 | +\texttt{linearmodels} (absorbing least squares); figures were produced in | |
| 48 | +\texttt{matplotlib}. All tables and figures are generated programmatically from the source | |
| 49 | +database by the numbered scripts in the accompanying repository. | |
added
paper/sections/data.tex
+77 −0
@@ -0,0 +1,77 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Data} | |
| 4 | +\label{sec:data} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +\subsection{Source and coverage} | |
| 8 | +\label{subsec:data_sources} | |
| 9 | + | |
| 10 | +The analysis draws on a de-duplicated snapshot of the Canadian Multiple Listing Service | |
| 11 | +(MLS), \texttt{realtor\_mls\_unique.duckdb}, containing 172{,}019 unique active | |
| 12 | +``for-sale'' listings. Each record carries the list price, a structured set of building | |
| 13 | +and lot attributes, ownership and dwelling-type fields, and---crucially for this | |
| 14 | +study---a geocoded location (latitude, longitude and postal code). Geographic coverage is | |
| 15 | +essentially complete: coordinates and postal codes are present for more than 99.9\% of | |
| 16 | +records, so every listing can be mapped to its Forward Sortation Area (FSA), the first | |
| 17 | +three characters of the Canadian postal code and our unit of neighbourhood. | |
| 18 | + | |
| 19 | +\subsection{Sample construction and variable parsing} | |
| 20 | +\label{subsec:variables} | |
| 21 | + | |
| 22 | +The raw fields are semi-structured and require parsing. Bedroom counts reported as | |
| 23 | +``3~+~1'' (main plus lower level) are summed. Living areas, reported inconsistently in | |
| 24 | +square feet or square metres, are harmonised to square metres (preferring the explicit | |
| 25 | +floor-area measurement and converting from square feet at | |
| 26 | +$1\text{ ft}^2 = 0.0929\text{ m}^2$). Lot sizes are parsed from free-text fields into | |
| 27 | +square metres where a numeric value can be recovered, with a missingness indicator | |
| 28 | +retained. We restrict the sample to residential dwellings (houses, condominiums, plexes, | |
| 29 | +townhouses and apartments) with a strictly positive list price and non-missing core | |
| 30 | +structural fields, and we trim the extreme 1\% tails of price and living area to limit the | |
| 31 | +influence of data-entry errors and ultra-luxury outliers. The resulting estimation sample | |
| 32 | +contains \textbf{140{,}931 dwellings}, of which 82{,}334 are houses and 57{,}857 are | |
| 33 | +condominiums. | |
| 34 | + | |
| 35 | +The dependent variable is the natural logarithm of the list price. Structural regressors | |
| 36 | +are: $\ln$ living area; counts of bedrooms, full bathrooms and half bathrooms; parking | |
| 37 | +spaces; storeys; and an indicator for the availability of lot information together with | |
| 38 | +$\ln(1+\text{lot area})$. Categorical controls comprise the dwelling type (house, | |
| 39 | +apartment/condo, row/townhouse, duplex, triplex, fourplex, manufactured home, other), the | |
| 40 | +ownership form (freehold, condominium/strata, leasehold, etc.), and the broad listing | |
| 41 | +category. The neighbourhood fixed effect is the FSA; FSAs with fewer than 25 listings are | |
| 42 | +pooled into a province-level residual category so that each absorbed effect is estimated | |
| 43 | +from a reasonable number of observations. | |
| 44 | + | |
| 45 | +\subsection{Descriptive statistics} | |
| 46 | +\label{subsec:summary_stats} | |
| 47 | + | |
| 48 | +Table~\ref{tab:summary_stats} reports the descriptive statistics. The median dwelling | |
| 49 | +lists for roughly \$565{,}000 and offers about 125~m$^2$ of living space, two full | |
| 50 | +bathrooms and three bedrooms. Both price and price per square metre are strongly | |
| 51 | +right-skewed---means exceed medians throughout---motivating the log transformation | |
| 52 | +illustrated in Figure~\ref{fig:price}, whose right panel is approximately symmetric and | |
| 53 | +underpins the semi-logarithmic hedonic specification. | |
| 54 | + | |
| 55 | +\input{../results/tables/summary_stats} | |
| 56 | + | |
| 57 | +\begin{figure}[t]\centering | |
| 58 | +\includegraphics[width=\textwidth]{fig_price_dist.png} | |
| 59 | +\caption{Distribution of list prices. Panel (a) shows the raw price (truncated at \$3M for | |
| 60 | +readability) with the sample median marked; panel (b) shows log price, the dependent | |
| 61 | +variable, which is close to symmetric.} | |
| 62 | +\label{fig:price} | |
| 63 | +\end{figure} | |
| 64 | + | |
| 65 | +The provincial composition is dominated by Ontario, Quebec, British Columbia and Alberta, | |
| 66 | +which together account for the large majority of listings; the Atlantic provinces and the | |
| 67 | +Prairies are present but thinner, and Prince Edward Island and the territories contain no | |
| 68 | +listings in this snapshot. Median price per square metre ranges from roughly \$2{,}000 in | |
| 69 | +Newfoundland and Labrador to over \$6{,}100 in British Columbia | |
| 70 | +(Figure~\ref{fig:province}), foreshadowing the dominant role of location documented below. | |
| 71 | + | |
| 72 | +\begin{figure}[t]\centering | |
| 73 | +\includegraphics[width=0.82\textwidth]{fig_province_ppm2.png} | |
| 74 | +\caption{Median price per square metre of living area by province. Grey extensions show | |
| 75 | +the mean--median gap, reflecting right-skew from high-value listings.} | |
| 76 | +\label{fig:province} | |
| 77 | +\end{figure} | |
added
paper/sections/introduction.tex
+71 −0
@@ -0,0 +1,71 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Introduction} | |
| 4 | +\label{sec:introduction} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +A dwelling is the archetypal heterogeneous good. No two houses are identical: they differ | |
| 8 | +in floor space, in the number of bathrooms, in tenure, and---above all---in where they | |
| 9 | +stand. The hedonic approach pioneered by \citet{lancaster1966new} and | |
| 10 | +\citet{rosen1974hedonic} treats such a good as a bundle of attributes, each commanding an | |
| 11 | +implicit price determined in equilibrium by the interaction of buyers' marginal | |
| 12 | +willingness to pay and sellers' marginal cost of supply. Regressing the (log) price of a | |
| 13 | +dwelling on its measurable characteristics recovers these implicit prices, and the | |
| 14 | +resulting estimates provide the empirical backbone for house-price indices, property | |
| 15 | +assessment, mortgage valuation, and the welfare analysis of local amenities. | |
| 16 | + | |
| 17 | +This paper estimates a hedonic price model for the Canadian residential market at national | |
| 18 | +scale. Using a cross-section of \textbf{140{,}931} active MLS listings spanning the nine | |
| 19 | +provinces present in the data---from British Columbia to Newfoundland and Labrador---we | |
| 20 | +decompose dwelling prices into structural attributes, dwelling type and ownership form, | |
| 21 | +and a rich set of \textbf{1{,}153 neighbourhood fixed effects} defined at the Forward | |
| 22 | +Sortation Area (FSA) level. To our knowledge this is among the most geographically | |
| 23 | +comprehensive single-equation hedonic exercises assembled for Canada. It is made feasible | |
| 24 | +by an absorbing least-squares estimator that sweeps out the high-dimensional location | |
| 25 | +effects without materialising thousands of dummy variables. | |
| 26 | + | |
| 27 | +The motivation is threefold. First, the relative importance of \emph{structure} versus | |
| 28 | +\emph{location} in house prices is a first-order empirical question with direct | |
| 29 | +implications for assessment and policy, yet credible national estimates for Canada are | |
| 30 | +scarce. Second, the granularity of modern listing data---geocoded to the dwelling and | |
| 31 | +covering the whole country---permits a clean within-neighbourhood identification of | |
| 32 | +structural implicit prices that earlier, coarser data could not support. Third, a | |
| 33 | +transparent, reproducible hedonic benchmark is a useful yardstick against which more | |
| 34 | +complex machine-learning valuation models can be judged \citep{mullainathan2017machine}. | |
| 35 | + | |
| 36 | +Our main findings can be summarised as follows. The purely structural model explains 46\% | |
| 37 | +of the variation in log prices; adding province fixed effects raises this to 57\%, and | |
| 38 | +replacing them with FSA fixed effects lifts it to \textbf{77\%}. Neighbourhood location | |
| 39 | +\emph{alone} therefore accounts for roughly thirty percentage points of explanatory | |
| 40 | +power---more than all structural attributes combined. Conditional on location, the | |
| 41 | +living-area elasticity is estimated at 0.51--0.62: a 10\% larger dwelling sells for about | |
| 42 | +5--6\% more. Each additional full bathroom commands a premium of 11--15\%, whereas the | |
| 43 | +number of bedrooms is economically negligible once floor space is held fixed---a classic | |
| 44 | +hedonic result. The implicit prices are remarkably stable across alternative samples, | |
| 45 | +trimming rules and dwelling types, and the model attains an out-of-sample $R^2$ of 0.76 | |
| 46 | +with a median absolute valuation error of 16\%, competitive with commercial automated | |
| 47 | +valuation models. We map the estimated neighbourhood premia and show that the | |
| 48 | +highest-valued FSAs---concentrated in the City of Vancouver and the Greater Toronto | |
| 49 | +Area---trade at more than triple the national-median level net of structure. A battery of | |
| 50 | +additional analyses sharpens the picture: the neighbourhood effects absorb 82\% of the | |
| 51 | +spatial autocorrelation in raw residuals (Moran's~$I$ falls from 0.46 to 0.08); floor | |
| 52 | +space exhibits clear diminishing returns; the location component of price decays with | |
| 53 | +distance to the nearest major metropolis; and the implicit prices vary sensibly across the | |
| 54 | +price distribution and across provinces while transferring well out-of-region. | |
| 55 | + | |
| 56 | +This paper relates to several strands of the literature. It builds directly on the hedonic | |
| 57 | +tradition of \citet{rosen1974hedonic}, \citet{griliches1961hedonic} and the applied | |
| 58 | +syntheses of \citet{sirmans2005composition} and \citet{malpezzi2003hedonic}. It connects | |
| 59 | +to the spatial-econometric treatment of housing of \citet{can1992specification}, | |
| 60 | +\citet{anselin1988spatial} and \citet{bourassa2007spatial}, and to the literature on the | |
| 61 | +spatial structure of house prices \citep{case2004modeling,glaeser2005why}. | |
| 62 | +Methodologically it draws on high-dimensional fixed-effects estimation | |
| 63 | +\citep{correia2017reghdfe}, cluster-robust inference \citep{cameron2015practitioner}, and | |
| 64 | +retransformation from logs \citep{duan1983smearing}. | |
| 65 | + | |
| 66 | +The remainder of the paper is organised as follows. Section~\ref{sec:literature} reviews | |
| 67 | +the related literature. Section~\ref{sec:data} describes the data and variable | |
| 68 | +construction. Section~\ref{sec:methodology} presents the empirical strategy. | |
| 69 | +Section~\ref{sec:results} reports the main results. Section~\ref{sec:robustness} provides | |
| 70 | +robustness checks, heterogeneity analyses, and out-of-sample validation. | |
| 71 | +Section~\ref{sec:conclusion} concludes. | |
added
paper/sections/literature.tex
+84 −0
@@ -0,0 +1,84 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Related Literature} | |
| 4 | +\label{sec:literature} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +\subsection{The hedonic framework} | |
| 8 | + | |
| 9 | +The hedonic method has two intellectual roots. \citet{lancaster1966new} recast consumer | |
| 10 | +theory in terms of the characteristics embodied in goods rather than the goods themselves, | |
| 11 | +while \citet{court1939hedonic} and \citet{griliches1961hedonic} developed the empirical | |
| 12 | +machinery of quality-adjusted price indices. \citet{rosen1974hedonic} unified these ideas | |
| 13 | +in an equilibrium model in which the observed price schedule traces out the envelope of | |
| 14 | +buyers' bid functions and sellers' offer functions; its gradient with respect to a | |
| 15 | +characteristic identifies, at the margin, the implicit price of that characteristic. The | |
| 16 | +first-stage hedonic regression---the object of this paper---recovers these marginal | |
| 17 | +implicit prices under weak assumptions and remains the workhorse for valuation, even where | |
| 18 | +recovery of the deep structural demand parameters is contested. A subsequent literature | |
| 19 | +has clarified exactly what the second stage can and cannot identify: | |
| 20 | +\citet{ekeland2004identification} show that nonlinearity of the hedonic price function | |
| 21 | +aids identification of preferences, \citet{bajari2005hedonic} develop a tractable demand | |
| 22 | +estimator with unobserved product characteristics, and \citet{kuminoff2010which} document | |
| 23 | +how sensitive welfare estimates are to specification. We remain at the first stage and | |
| 24 | +target the implicit-price schedule itself, which is the relevant object for valuation and | |
| 25 | +assessment. | |
| 26 | + | |
| 27 | +\subsection{Specification of housing hedonics} | |
| 28 | + | |
| 29 | +A large applied literature studies which attributes belong in a housing hedonic and what | |
| 30 | +functional form to impose. \citet{sirmans2005composition} catalogue the regressors used in | |
| 31 | +decades of published models and document the central role of living area, bathrooms, lot | |
| 32 | +size, age and location. \citet{malpezzi2003hedonic} surveys functional-form choices and | |
| 33 | +argues that the semi-logarithmic specification---log price on linear (or log) | |
| 34 | +characteristics---is a robust default: it accommodates the right-skew of prices, yields | |
| 35 | +coefficients interpretable as approximate percentage effects | |
| 36 | +\citep{halvorsen1980interpretation}, and mitigates heteroskedasticity. We adopt this | |
| 37 | +specification throughout. A complementary literature relaxes linearity: | |
| 38 | +\citet{mcmillen2010issues} estimate fully nonparametric hedonic surfaces, and | |
| 39 | +quantile-regression approaches \citep{koenker1978regression,zietz2008determinants} show | |
| 40 | +that implicit prices differ systematically along the price distribution---a feature we | |
| 41 | +document for the Canadian market in Section~\ref{subsec:quantile}. | |
| 42 | + | |
| 43 | +\subsection{Amenity capitalization} | |
| 44 | + | |
| 45 | +A large share of the value of location reflects the capitalization of local public goods | |
| 46 | +and disamenities into prices. Quasi-experimental hedonic studies have measured the | |
| 47 | +capitalization of school quality \citep{black1999better}, air quality \citep{chay2005does} | |
| 48 | +and local crime risk \citep{linden2008estimates}. Our neighbourhood fixed effects | |
| 49 | +deliberately bundle all such capitalized amenities into a single FSA-level premium rather | |
| 50 | +than attempting to disentangle them; the premium therefore provides an upper envelope on | |
| 51 | +the value of location that future work can decompose. | |
| 52 | + | |
| 53 | +\subsection{Space in housing models} | |
| 54 | + | |
| 55 | +Because housing is immobile, location is intrinsic to its value, and unobserved local | |
| 56 | +amenities induce strong spatial dependence in prices. \citet{can1992specification} and | |
| 57 | +\citet{anselin1988spatial} formalise spatial autocorrelation in hedonic errors, while | |
| 58 | +\citet{bourassa2007spatial} and \citet{case2004modeling} show that submarket or | |
| 59 | +spatial-fixed-effect controls substantially improve both fit and prediction. Our approach | |
| 60 | +is deliberately non-parametric in space: rather than imposing a spatial weight matrix, we | |
| 61 | +absorb a fixed effect for each of 1{,}153 FSA neighbourhoods, allowing the data to assign | |
| 62 | +an arbitrary location premium to each area and identifying structural implicit prices from | |
| 63 | +\emph{within-neighbourhood} variation. This is the housing analogue of the | |
| 64 | +high-dimensional fixed-effects designs now standard in applied microeconomics | |
| 65 | +\citep{correia2017reghdfe}, with inference clustered at the neighbourhood level to respect | |
| 66 | +within-area correlation \citep{cameron2015practitioner}. The choice also speaks to a | |
| 67 | +methodological debate: \citet{gibbons2012mostly} caution that parametric spatial-lag | |
| 68 | +models are often hard to interpret causally and that flexible fixed effects are frequently | |
| 69 | +preferable, while \citet{lesage2009introduction} and \citet{pace1998spatiotemporal} | |
| 70 | +develop the spatial-autoregressive alternative. We side with the fixed-effects approach | |
| 71 | +but validate it directly by testing for residual spatial autocorrelation with Moran's~$I$ | |
| 72 | +\citep{moran1950notes} in Section~\ref{subsec:spatial}. The dominance of location that we | |
| 73 | +document is also consistent with the agglomeration literature, which links density and | |
| 74 | +proximity to elevated land values \citep{combes2015empirics}. | |
| 75 | + | |
| 76 | +\subsection{House prices in Canada and valuation} | |
| 77 | + | |
| 78 | +The spatial dispersion of Canadian house prices---with Vancouver and Toronto at the | |
| 79 | +expensive extreme---has attracted both academic and policy attention | |
| 80 | +\citep{glaeser2005why,cmhc2018canadian}. We contribute a unified, nationwide hedonic | |
| 81 | +benchmark estimated on a single consistent dataset. Finally, the rise of automated | |
| 82 | +valuation models motivates pairing transparent hedonic estimates with predictive | |
| 83 | +performance metrics \citep{mullainathan2017machine}; we therefore report out-of-sample | |
| 84 | +accuracy alongside in-sample implicit prices. | |
added
paper/sections/methodology.tex
+87 −0
@@ -0,0 +1,87 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Empirical Strategy} | |
| 4 | +\label{sec:methodology} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +\subsection{The hedonic equation} | |
| 8 | +\label{subsec:model} | |
| 9 | + | |
| 10 | +We estimate the semi-logarithmic hedonic price equation | |
| 11 | +% | |
| 12 | +\begin{equation} | |
| 13 | + \ln P_{i} | |
| 14 | + = \alpha | |
| 15 | + + \beta\,\ln(\text{Area}_{i}) | |
| 16 | + + \mathbf{x}_{i}'\boldsymbol{\gamma} | |
| 17 | + + \mathbf{d}_{i}'\boldsymbol{\delta} | |
| 18 | + + \mu_{f(i)} | |
| 19 | + + \varepsilon_{i}, | |
| 20 | + \label{eq:hedonic} | |
| 21 | +\end{equation} | |
| 22 | +% | |
| 23 | +where $P_{i}$ is the list price of dwelling~$i$; $\text{Area}_{i}$ is living area in | |
| 24 | +square metres; $\mathbf{x}_{i}$ collects the remaining structural attributes (bedrooms, | |
| 25 | +full and half bathrooms, parking, storeys, the lot indicator and $\ln$ lot area); | |
| 26 | +$\mathbf{d}_{i}$ is a vector of dwelling-type and ownership dummies; $\mu_{f(i)}$ is a | |
| 27 | +fixed effect for the FSA neighbourhood $f$ to which dwelling~$i$ belongs; and | |
| 28 | +$\varepsilon_{i}$ is an idiosyncratic error. | |
| 29 | + | |
| 30 | +Because $\beta$ multiplies a logged regressor, it is the \emph{elasticity} of price with | |
| 31 | +respect to floor space. The elements of $\boldsymbol{\gamma}$ attached to count variables | |
| 32 | +are semi-elasticities: following \citet{halvorsen1980interpretation}, a coefficient | |
| 33 | +$\gamma$ implies an approximate proportional price change of $100\,(e^{\gamma}-1)\%$ for a | |
| 34 | +one-unit increase, which we report whenever the distinction from the raw coefficient is | |
| 35 | +material. | |
| 36 | + | |
| 37 | +\subsection{High-dimensional location effects} | |
| 38 | +\label{subsec:identification} | |
| 39 | + | |
| 40 | +The neighbourhood fixed effects $\mu_{f}$ are the heart of the design. By including a | |
| 41 | +separate intercept for each of the 1{,}153 FSAs, we allow every neighbourhood an arbitrary | |
| 42 | +price level that absorbs all location-specific amenities---school quality, transit access, | |
| 43 | +coastline, employment density---whether or not they are observed. The structural implicit | |
| 44 | +prices in $\beta$ and $\boldsymbol{\gamma}$ are then identified purely from variation | |
| 45 | +\emph{within} neighbourhoods, comparing dwellings that differ in their physical attributes | |
| 46 | +but share a location. This is the housing counterpart of the within estimator, and it | |
| 47 | +addresses the most pernicious source of omitted-variable bias in hedonic work: the | |
| 48 | +correlation between structural quality and unobserved locational quality | |
| 49 | +\citep{can1992specification,bourassa2007spatial}. | |
| 50 | + | |
| 51 | +Including more than a thousand dummies directly is numerically wasteful. We instead | |
| 52 | +estimate Equation~\eqref{eq:hedonic} by \emph{absorbing least squares}, which partials the | |
| 53 | +FSA effects out of both the dependent variable and the regressors before estimating the | |
| 54 | +structural coefficients \citep{correia2017reghdfe}; the slope estimates are numerically | |
| 55 | +identical to full-dummy OLS. All standard errors are clustered at the FSA level to allow | |
| 56 | +for arbitrary within-neighbourhood correlation and heteroskedasticity | |
| 57 | +\citep{cameron2015practitioner}. | |
| 58 | + | |
| 59 | +\subsection{Specification ladder} | |
| 60 | +\label{subsec:ladder} | |
| 61 | + | |
| 62 | +We report a ladder of nested specifications that isolates the marginal contribution of | |
| 63 | +each block of controls: | |
| 64 | +% | |
| 65 | +\begin{itemize} | |
| 66 | + \item \textbf{M1 -- Structural:} structural attributes only. | |
| 67 | + \item \textbf{M2 -- + Type/Ownership:} adds dwelling-type and ownership dummies. | |
| 68 | + \item \textbf{M3 -- + Province:} adds province fixed effects. | |
| 69 | + \item \textbf{M4 -- Houses + FSA:} replaces province with FSA fixed effects, houses only. | |
| 70 | + \item \textbf{M5 -- Grand model:} FSA fixed effects over all residential dwellings. | |
| 71 | +\end{itemize} | |
| 72 | +% | |
| 73 | +Columns M1--M3 are estimated on the house subsample to keep the structural interpretation | |
| 74 | +clean; M5 is the preferred grand specification estimated over the full residential sample. | |
| 75 | +The gap in $R^2$ between M3 and M5 measures the explanatory value of resolving location at | |
| 76 | +the neighbourhood rather than the provincial scale. | |
| 77 | + | |
| 78 | +\subsection{Retransformation and out-of-sample evaluation} | |
| 79 | +\label{subsec:retrans} | |
| 80 | + | |
| 81 | +Because the model is estimated in logs, predicted price levels require a retransformation | |
| 82 | +correction. We use Duan's smearing estimator \citep{duan1983smearing}, multiplying | |
| 83 | +$\exp(\widehat{\ln P})$ by the sample mean of $\exp(\widehat{\varepsilon})$, which is | |
| 84 | +consistent without assuming log-normal errors. For predictive validation we randomly split | |
| 85 | +the data 80/20, estimate the model on the training fold (restricting evaluation to | |
| 86 | +neighbourhoods observed in training, since out-of-support FSA effects are not identified), | |
| 87 | +and report held-out fit and percentage-error metrics on the test fold. | |
added
paper/sections/results.tex
+179 −0
@@ -0,0 +1,179 @@ | ||
| 1 | +% Author: Simon-Pierre Boucher — contact@spboucher.ai | |
| 2 | +% ============================================================================ | |
| 3 | +\section{Results} | |
| 4 | +\label{sec:results} | |
| 5 | +% ============================================================================ | |
| 6 | + | |
| 7 | +\subsection{The value of location} | |
| 8 | +\label{subsec:location} | |
| 9 | + | |
| 10 | +Figure~\ref{fig:r2} summarises the explanatory power of the specification ladder. The | |
| 11 | +structural-only model (M1) accounts for 46.4\% of the variation in log prices. Adding | |
| 12 | +dwelling-type and ownership controls (M2) barely moves the fit, but introducing province | |
| 13 | +fixed effects (M3) raises $R^2$ to 56.8\%, and resolving location at the FSA scale lifts | |
| 14 | +it to \textbf{76.2\%} for houses (M4) and \textbf{76.7\%} for the grand model (M5). The | |
| 15 | +implication is stark: moving from province to neighbourhood resolution adds about twenty | |
| 16 | +percentage points of explained variance, and \emph{location as a whole accounts for | |
| 17 | +roughly thirty percentage points}---more than the entire structural bundle. This is the | |
| 18 | +central result of the paper and a quantitative statement of the realtor's adage that what | |
| 19 | +matters is ``location, location, location.'' | |
| 20 | + | |
| 21 | +\begin{figure}[t]\centering | |
| 22 | +\includegraphics[width=0.82\textwidth]{fig_r2.png} | |
| 23 | +\caption{Share of log-price variation explained ($R^2$) across the five nested | |
| 24 | +specifications. The jump from M3 (province) to M4/M5 (FSA) quantifies the value of | |
| 25 | +resolving location at the neighbourhood scale.} | |
| 26 | +\label{fig:r2} | |
| 27 | +\end{figure} | |
| 28 | + | |
| 29 | +\subsection{Implicit prices of structural attributes} | |
| 30 | +\label{subsec:implicit} | |
| 31 | + | |
| 32 | +Table~\ref{tab:regression} reports the regression estimates. The living-area elasticity is | |
| 33 | +remarkably stable across specifications, at $0.66$ in the raw structural model and | |
| 34 | +settling near $0.55$ once location is controlled for: a 10\% larger dwelling commands | |
| 35 | +roughly a 5.5\% higher price. The slight decline as controls are added is consistent with | |
| 36 | +larger homes being located in more expensive areas---a confound the FSA effects remove. | |
| 37 | + | |
| 38 | +Full bathrooms carry one of the strongest structural premia: about $0.11$ log points in | |
| 39 | +the grand model, or roughly an \textbf{11\% price increase} per additional bathroom, | |
| 40 | +rising to nearly 15\% in the province-FE model. Half bathrooms attract a small | |
| 41 | +\emph{negative} conditional coefficient, which we read not as a disamenity but as a proxy | |
| 42 | +for older or more compartmentalised floor plans once total area and full baths are held | |
| 43 | +fixed. Bedrooms are economically negligible conditional on living area: holding floor | |
| 44 | +space constant, subdividing it into more bedrooms does not raise value---a textbook | |
| 45 | +hedonic finding that recurs across our samples. Lot information enters positively ($\ln$ | |
| 46 | +lot elasticity around $0.03$) but modestly, reflecting both the noisiness of the parsed | |
| 47 | +lot field and the fact that, within a neighbourhood, lot variation is compressed. | |
| 48 | + | |
| 49 | +Figure~\ref{fig:forest} presents the structural implicit prices with 95\% cluster-robust | |
| 50 | +confidence intervals, making visually plain the dominance of living area and bathrooms and | |
| 51 | +the near-zero conditional effects of bedrooms, parking and storeys. | |
| 52 | + | |
| 53 | +\input{../results/tables/regression} | |
| 54 | + | |
| 55 | +\begin{figure}[t]\centering | |
| 56 | +\includegraphics[width=0.82\textwidth]{fig_forest.png} | |
| 57 | +\caption{Marginal implicit prices of structural attributes (houses, province-FE model M3) | |
| 58 | +with 95\% cluster-robust confidence intervals, on the log-price scale.} | |
| 59 | +\label{fig:forest} | |
| 60 | +\end{figure} | |
| 61 | + | |
| 62 | +The price--size gradient by dwelling type (Figure~\ref{fig:size_gradient}) confirms the | |
| 63 | +log--log structure: median price rises concavely with living area for both dwelling types. | |
| 64 | +Unconditionally, condominiums list \emph{above} houses of the same size---a compositional | |
| 65 | +effect of their concentration in the expensive metropolitan markets---whereas conditional | |
| 66 | +on location and ownership the estimated dwelling-type effects show that houses command the | |
| 67 | +premium, in line with Table~\ref{tab:regression}. | |
| 68 | + | |
| 69 | +\begin{figure}[t]\centering | |
| 70 | +\includegraphics[width=0.78\textwidth]{fig_size_gradient.png} | |
| 71 | +\caption{Median price by living-area bin and dwelling type. The concave gradient is | |
| 72 | +linearised by the semi-log specification.} | |
| 73 | +\label{fig:size_gradient} | |
| 74 | +\end{figure} | |
| 75 | + | |
| 76 | +\subsection{The geography of housing value} | |
| 77 | +\label{subsec:geography} | |
| 78 | + | |
| 79 | +Figure~\ref{fig:maps} maps the spatial structure of value directly. The familiar outline | |
| 80 | +of populated Canada emerges from the listing coordinates. The Vancouver corridor and the | |
| 81 | +Greater Toronto--Golden Horseshoe area sit at the top of the price-per-square-metre | |
| 82 | +distribution, while the Prairies and Atlantic Canada anchor the bottom. The right panel | |
| 83 | +aggregates to FSA medians, the geographic unit absorbed in the grand model. | |
| 84 | + | |
| 85 | +\begin{figure}[t]\centering | |
| 86 | +\begin{subfigure}{0.49\textwidth}\includegraphics[width=\textwidth]{fig_map.png} | |
| 87 | +\caption{All listings}\end{subfigure}\hfill | |
| 88 | +\begin{subfigure}{0.49\textwidth}\includegraphics[width=\textwidth]{fig_fsa_map.png} | |
| 89 | +\caption{FSA neighbourhood medians}\end{subfigure} | |
| 90 | +\caption{Spatial distribution of housing value. Colour encodes log price per m$^2$; bubble | |
| 91 | +area in panel~(b) is proportional to $\sqrt{\text{listings}}$. Labels mark the provinces | |
| 92 | +with substantial samples; the data cover nine provinces, while the territories and Prince | |
| 93 | +Edward Island contain no listings.} | |
| 94 | +\label{fig:maps} | |
| 95 | +\end{figure} | |
| 96 | + | |
| 97 | +To translate location into a clean dollar statement we recover each FSA's fixed effect | |
| 98 | +from the grand model---its price premium net of structure, dwelling type and | |
| 99 | +ownership---and express it relative to the national median (Figure~\ref{fig:premia}). The | |
| 100 | +highest-valued neighbourhoods, all in the City of Vancouver, trade at \textbf{150--200\% | |
| 101 | +above} the national-median neighbourhood for an otherwise identical dwelling; the lowest, | |
| 102 | +in rural Saskatchewan, Manitoba and Newfoundland, sit \textbf{60--67\% below}. The full | |
| 103 | +premium distribution thus spans a factor of roughly nine between the most and least | |
| 104 | +expensive neighbourhoods, dwarfing the price range attributable to any single structural | |
| 105 | +attribute. | |
| 106 | + | |
| 107 | +\begin{figure}[t]\centering | |
| 108 | +\includegraphics[width=0.78\textwidth]{fig_premia.png} | |
| 109 | +\caption{Highest- and lowest-valued neighbourhoods (FSAs) in Canada, measured as the | |
| 110 | +estimated location premium relative to the national-median neighbourhood, net of | |
| 111 | +structure, dwelling type and ownership. Only FSAs with at least 50 listings are shown.} | |
| 112 | +\label{fig:premia} | |
| 113 | +\end{figure} | |
| 114 | + | |
| 115 | +\subsection{Decomposing the variance of prices} | |
| 116 | +\label{subsec:decomp} | |
| 117 | + | |
| 118 | +Figure~\ref{fig:decomp} casts the specification ladder as a decomposition of the variance | |
| 119 | +of log prices into the share explained by each successive block of controls. Physical | |
| 120 | +structure accounts for 46\% of the variance; dwelling type and ownership add a further | |
| 121 | +0.4~points; province adds about 10~points; and resolving location to the neighbourhood | |
| 122 | +adds a further 20~points, for a total location contribution near 30~points. Just under a | |
| 123 | +quarter of the variance remains unexplained and is attributable to idiosyncratic pricing | |
| 124 | +and unobserved dwelling quality. The visual makes the headline unmistakable: the single | |
| 125 | +largest identified block of housing value in Canada is the neighbourhood. | |
| 126 | + | |
| 127 | +\begin{figure}[t]\centering | |
| 128 | +\includegraphics[width=0.92\textwidth]{fig_decomp.png} | |
| 129 | +\caption{Variance decomposition of Canadian log house prices into structure, dwelling | |
| 130 | +type/ownership, province, neighbourhood (FSA) and the unexplained residual, from the | |
| 131 | +nested specification ladder.} | |
| 132 | +\label{fig:decomp} | |
| 133 | +\end{figure} | |
| 134 | + | |
| 135 | +\subsection{Nonlinearity: diminishing returns to floor space} | |
| 136 | +\label{subsec:nonlinear} | |
| 137 | + | |
| 138 | +The constant-elasticity assumption is convenient but restrictive. Re-estimating the grand | |
| 139 | +model with a quadratic in log living area yields a positive linear term and a | |
| 140 | +significantly negative quadratic term ($\widehat{\beta}_1=1.06$, | |
| 141 | +$\widehat{\beta}_2=-0.053$), implying that the marginal elasticity of price with respect | |
| 142 | +to floor space \emph{declines} with dwelling size. Figure~\ref{fig:nonlinear} traces the | |
| 143 | +implied marginal elasticity: it falls from roughly $0.65$ for a compact 60~m$^2$ dwelling | |
| 144 | +to about $0.45$ for a large 350~m$^2$ home. Economically, the first square metres of | |
| 145 | +living space are valued most highly and additional space is subject to diminishing | |
| 146 | +returns---consistent with the nonparametric hedonic surfaces of \citet{mcmillen2010issues}. | |
| 147 | +The constant-elasticity estimate of $0.55$ is best read as an average over the size | |
| 148 | +distribution. | |
| 149 | + | |
| 150 | +\begin{figure}[t]\centering | |
| 151 | +\includegraphics[width=0.78\textwidth]{fig_nonlinear.png} | |
| 152 | +\caption{Marginal elasticity of price with respect to living area as a function of | |
| 153 | +dwelling size, from a grand model with a quadratic in log area (95\% cluster-robust band). | |
| 154 | +The dashed line is the constant-elasticity estimate.} | |
| 155 | +\label{fig:nonlinear} | |
| 156 | +\end{figure} | |
| 157 | + | |
| 158 | +\subsection{The urban price gradient} | |
| 159 | +\label{subsec:gradient} | |
| 160 | + | |
| 161 | +Classic urban theory predicts that, holding structure fixed, value declines with distance | |
| 162 | +from employment centres. We compute the great-circle distance from each listing to the | |
| 163 | +nearest of nine major Canadian metropolitan centres and relate it to the location | |
| 164 | +component of price (the residual from a structure-only model). Figure~\ref{fig:gradient} | |
| 165 | +confirms a pronounced gradient: dwellings within the metropolitan core carry location | |
| 166 | +premia of tens of percent over the structure-only benchmark, and the premium decays | |
| 167 | +steadily with distance, turning negative beyond roughly 80~km. A log-linear fit implies a | |
| 168 | +semi-elasticity of $-0.085$ ($t>100$): a doubling of distance to the nearest metro is | |
| 169 | +associated with an 8.5\% lower location premium. This agglomeration gradient is precisely | |
| 170 | +the force that the FSA fixed effects absorb non-parametrically in the grand model | |
| 171 | +\citep{combes2015empirics}. | |
| 172 | + | |
| 173 | +\begin{figure}[t]\centering | |
| 174 | +\includegraphics[width=0.78\textwidth]{fig_gradient.png} | |
| 175 | +\caption{Urban price gradient: the location component of price (relative to a | |
| 176 | +structure-only benchmark) against distance to the nearest of nine major Canadian metros. | |
| 177 | +The horizontal axis is on a symmetric-log scale.} | |
| 178 | +\label{fig:gradient} | |
| 179 | +\end{figure} | |
added
paper/sections/robustness.tex
+151 −0
Large diff (151 lines) is not loaded by default to keep the page fast.Load diff
added
paper/sections/titlepage.tex
+70 −0
Large diff (70 lines) is not loaded by default to keep the page fast.Load diff
added
paper/uq_logo.jpg
+0 −0
Binary file not shown.
added
requirements.txt
+10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/coef_M1.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/coef_M2.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/coef_M3.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/coef_M5.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/ext2.json
+21 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/fit.json
+22 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/fsa_premia.csv
+868 −0
Large diff (868 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/heterogeneity.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/lopo.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/oos.json
+11 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/quantile.csv
+7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/robustness.csv
+7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added
results/reference/summary_stats.csv
+10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/coef_M1.csv
+10 −0
Large diff (10 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/coef_M2.csv
+15 −0
Large diff (15 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/coef_M3.csv
+23 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/coef_M5.csv
+26 −0
Large diff (26 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/ext2.json
+21 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/fit.json
+22 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/fsa_premia.csv
+870 −0
Large diff (870 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/gradient_bins.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/grand_model.parquet
+0 −0
Binary file not shown.
added
results/reproduced/heterogeneity.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/lopo.csv
+9 −0
Large diff (9 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/moran_coords.npy
+0 −0
Binary file not shown.
added
results/reproduced/moran_resid_grand.npy
+0 −0
Binary file not shown.
added
results/reproduced/moran_resid_struct.npy
+0 −0
Binary file not shown.
added
results/reproduced/nonlinear_band.csv
+61 −0
Large diff (61 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/oos.json
+11 −0
Large diff (12 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/quantile.csv
+7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added
results/reproduced/robustness.csv
+7 −0
Large diff (7 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/lopo.tex
+16 −0
Large diff (16 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/oos.tex
+22 −0
Large diff (22 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/quantile.tex
+13 −0
Large diff (13 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/regression.tex
+30 −0
Large diff (30 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/robustness.tex
+20 −0
Large diff (20 lines) is not loaded by default to keep the page fast.Load diff
added
results/tables/summary_stats.tex
+23 −0
Large diff (23 lines) is not loaded by default to keep the page fast.Load diff
added
scripts/01_build_sample.py
+29 −0
Large diff (29 lines) is not loaded by default to keep the page fast.Load diff
added
scripts/02_estimate_core.py
+62 −0
Large diff (62 lines) is not loaded by default to keep the page fast.Load diff
added
scripts/03_estimate_extended.py
+281 −0
Large diff (281 lines) is not loaded by default to keep the page fast.Load diff
added
scripts/04_make_figures.py
+379 −0
Large diff (379 lines) is not loaded by default to keep the page fast.Load diff
added
scripts/05_make_tables.py
+233 −0
Large diff (233 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/__init__.py
+11 −0
Large diff (11 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/config.py
+57 −0
Large diff (57 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/models.py
+105 −0
Large diff (105 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/parsing.py
+166 −0
Large diff (166 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/plotstyle.py
+27 −0
Large diff (27 lines) is not loaded by default to keep the page fast.Load diff
added
src/wp9/sample.py
+114 −0
Large diff (115 lines) is not loaded by default to keep the page fast.Load diff