SPB Git

spb/wp9_uqo Public

UQO Working Paper No. 9 — A grand hedonic model of the Canadian housing market: decomposing structure and location value.

TeX 60.1% Python 39.8%

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>
simon-pierre boucher committed 5 days ago (Aug 5, 2026)

Showing 86 changed files with +5,484 and −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 +[![Paper](https://img.shields.io/badge/paper-PDF%20(26%20p.)-b31b1b?logo=latex&logoColor=white)](paper/main.pdf)
7 +[![Python](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)](requirements.txt)
8 +[![DuckDB](https://img.shields.io/badge/data-DuckDB%20·%20172%2C019%20listings-FFF000?logo=duckdb&logoColor=black)](data/raw/README.md)
9 +[![Estimation](https://img.shields.io/badge/estimation-statsmodels%20·%20linearmodels%20(AbsorbingLS)-4051b5)](src/wp9/models.py)
10 +[![Reproducible](https://img.shields.io/badge/reproducible-end--to--end%20pipeline-2e7d32)](scripts/)
11 +[![Tables verified](https://img.shields.io/badge/tables-identical%20to%20published-2e7d32)](AUDIT.md)
12 +[![Institution](https://img.shields.io/badge/UQO-D%C3%A9pt.%20des%20sciences%20administratives-16365c)](https://uqo.ca)
13 +[![Author](https://img.shields.io/badge/author-Simon--Pierre%20Boucher-16365c)](mailto:contact@spboucher.ai)
14 +[![Contact](https://img.shields.io/badge/contact-contact%40spboucher.ai-a02020?logo=maildotru&logoColor=white)](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
@@ -0,0 +1,151 @@
1 +% Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +% ============================================================================
3 +\section{Robustness, Heterogeneity, and Validation}
4 +\label{sec:robustness}
5 +% ============================================================================
6 +
7 +\subsection{Stability of the implicit prices}
8 +\label{subsec:stability}
9 +
10 +Table~\ref{tab:robustness} re-estimates the grand FSA-fixed-effects model on six
11 +alternative samples and specifications. The size elasticity stays within the narrow band
12 +$0.51$--$0.62$ and the bathroom premium within $0.10$--$0.12$ log points across every cut:
13 +restricting to houses, restricting to condominiums, tightening the price trim to the
14 +0.5/99.5 percentiles, dropping FSAs with fewer than fifty listings, and limiting the
15 +sample to the three largest provinces. The condominium subsample exhibits both the highest
16 +fit ($R^2=0.81$) and the largest size elasticity, consistent with condominium prices being
17 +more tightly pinned down by floor area and location and less by idiosyncratic lot and
18 +structure features. The overall picture is one of striking parameter stability: the
19 +headline implicit prices are not artefacts of a particular sample definition.
20 +
21 +\input{../results/tables/robustness}
22 +
23 +\subsection{Implicit prices along the price distribution}
24 +\label{subsec:quantile}
25 +
26 +OLS recovers the implicit price at the conditional mean, but buyers at the bottom and top
27 +of the market may value attributes differently \citep{zietz2008determinants}. We estimate
28 +quantile hedonic regressions \citep{koenker1978regression} at the 10th through 90th
29 +percentiles of price (Table~\ref{tab:quantile}, Figure~\ref{fig:quantile}). Two patterns
30 +stand out. The living-area elasticity is roughly flat-to-rising, climbing from $0.56$ at
31 +the bottom to $0.60$ at the top, indicating that floor space is valued slightly more in
32 +expensive segments. The lot elasticity rises more steeply across the distribution,
33 +consistent with land being a luxury component of value. The bathroom premium is stable
34 +around $0.10$--$0.13$ throughout. The mean-based estimates in Table~\ref{tab:regression}
35 +are thus representative, but they mask economically sensible distributional variation.
36 +
37 +\input{../results/tables/quantile}
38 +
39 +\begin{figure}[t]\centering
40 +\includegraphics[width=\textwidth]{fig_quantile.png}
41 +\caption{Implicit prices across the conditional price distribution. Quantile estimates
42 +(with 95\% confidence intervals) of the living-area elasticity (left) and the
43 +full-bathroom premium (right); the dashed line is the OLS estimate.}
44 +\label{fig:quantile}
45 +\end{figure}
46 +
47 +\subsection{Residual spatial autocorrelation}
48 +\label{subsec:spatial}
49 +
50 +A central justification for the neighbourhood fixed effects is that they should absorb the
51 +spatial dependence that pervades raw housing residuals \citep{anselin1988spatial}. We test
52 +this directly by computing Moran's~$I$ \citep{moran1950notes} on the residuals, using
53 +row-standardised $k$-nearest-neighbour spatial weights ($k=10$) on a random sample of
54 +15{,}000 listings. The structure-only model leaves enormous spatial autocorrelation in its
55 +residuals, $I=0.46$ ($z=145$, $p<0.01$): nearby dwellings are mispriced in the same
56 +direction---the signature of omitted location. The grand model with FSA fixed effects cuts
57 +this to $I=0.08$ ($z=23$), an 82\% reduction, confirming that the neighbourhood effects
58 +absorb the overwhelming majority of the spatial signal. Figure~\ref{fig:moran} contrasts
59 +the two Moran scatterplots. The small residual autocorrelation that remains is
60 +within-neighbourhood and could be addressed by finer geographies or an explicit spatial
61 +model \citep{lesage2009introduction}, but it is an order of magnitude smaller than the
62 +dependence the fixed effects remove, vindicating the design over a parametric spatial-lag
63 +alternative \citep{gibbons2012mostly}.
64 +
65 +\begin{figure}[t]\centering
66 +\includegraphics[width=\textwidth]{fig_moran.png}
67 +\caption{Moran scatterplots of model residuals against their spatial lag ($k=10$ nearest
68 +neighbours, 15{,}000-listing sample). Left: structure-only model. Right: grand model with
69 +FSA fixed effects. The slope is Moran's~$I$; it collapses from 0.46 to 0.08.}
70 +\label{fig:moran}
71 +\end{figure}
72 +
73 +\subsection{Do structural prices transfer across space?}
74 +\label{subsec:lopo}
75 +
76 +As a demanding test of external validity we perform leave-one-province-out
77 +cross-validation: the structural model is estimated on all provinces but one and used to
78 +predict the held-out province, allowing only a province-specific intercept (the price
79 +\emph{level} is not identified out of region). Table~\ref{tab:lopo} reports the
80 +within-province $R^2$. The structural implicit prices transfer well to most of the
81 +country, with a mean held-out $R^2$ of $0.36$ and values above $0.40$ for the large
82 +central and western markets; transfer is weaker for the small Atlantic samples, where
83 +idiosyncratic stock and thin data dominate. That structural prices generalise across
84 +provinces---even as price \emph{levels} differ by a factor of nine---reinforces the
85 +paper's central decomposition: structure is broadly priced the same everywhere, and it is
86 +location that varies.
87 +
88 +\input{../results/tables/lopo}
89 +
90 +\subsection{Heterogeneity across provinces}
91 +\label{subsec:heterogeneity}
92 +
93 +Estimating the within-FSA model province by province reveals economically meaningful
94 +heterogeneity in the size elasticity (Figure~\ref{fig:heterogeneity}). The elasticity is
95 +lowest in the high-price coastal markets---about $0.49$ in British Columbia and $0.50$ in
96 +Ontario---and highest in the Prairies, reaching $0.65$--$0.66$ in Saskatchewan and
97 +Manitoba. The pattern is intuitive: where land and location dominate value (Vancouver,
98 +Toronto), an extra square metre of structure adds proportionally less, whereas in
99 +lower-priced markets the building itself is a larger share of value and floor space
100 +carries more weight. The bathroom premium shows the mirror pattern, larger in the Prairies
101 +and Atlantic provinces than in the coastal metros.
102 +
103 +\begin{figure}[t]\centering
104 +\includegraphics[width=0.8\textwidth]{fig_heterogeneity.png}
105 +\caption{Living-area elasticity of price by province, estimated within FSAs, with 95\%
106 +cluster-robust confidence intervals. The elasticity is smallest in the expensive coastal
107 +markets and largest in the Prairies.}
108 +\label{fig:heterogeneity}
109 +\end{figure}
110 +
111 +\subsection{Out-of-sample valuation accuracy}
112 +\label{subsec:oos}
113 +
114 +A hedonic model that fits in-sample need not predict well. Table~\ref{tab:oos} and
115 +Figure~\ref{fig:oos} report performance on a randomly held-out 20\% of listings. The model
116 +attains an out-of-sample $R^2$ of \textbf{0.764} on log price---essentially identical to
117 +its in-sample fit, indicating negligible over-fitting despite the thousand-plus location
118 +effects. In price levels, after Duan smearing, the \textbf{median absolute valuation error
119 +is 15.8\%}, the mean is 22.5\%, and \textbf{59\% of held-out dwellings are priced within
120 +$\pm$20\%} of their actual list price (34\% within $\pm$10\%). These figures are
121 +competitive with commercial automated valuation models and establish the transparent
122 +hedonic specification as a credible valuation benchmark \citep{mullainathan2017machine}.
123 +
124 +\input{../results/tables/oos}
125 +
126 +\begin{figure}[t]\centering
127 +\includegraphics[width=0.7\textwidth]{fig_oos.png}
128 +\caption{Out-of-sample valuation accuracy on the held-out test fold: the share of listings
129 +priced within $\pm$10\%, between 10 and 20\%, and beyond 20\% of the actual list price.
130 +The out-of-sample $R^2$ is reported in the title.}
131 +\label{fig:oos}
132 +\end{figure}
133 +
134 +\subsection{Model fit and residual behaviour}
135 +\label{subsec:fit}
136 +
137 +Panel~(a) of Figure~\ref{fig:fit} plots predicted against actual log prices for the grand
138 +model; the cloud hugs the 45-degree line. The residuals (panel~(b)) are approximately
139 +Gaussian and centred on zero, with only mild heavy tails---typical of housing data and
140 +accommodated by the cluster-robust inference. We interpret the remaining dispersion as a
141 +combination of genuine idiosyncratic pricing, listing strategy, and dwelling-level quality
142 +(age, renovations, finish) that the data do not record.
143 +
144 +\begin{figure}[t]\centering
145 +\begin{subfigure}{0.46\textwidth}\includegraphics[width=\textwidth]{fig_fit.png}
146 +\caption{Predicted vs.\ actual}\end{subfigure}\hfill
147 +\begin{subfigure}{0.52\textwidth}\includegraphics[width=\textwidth]{fig_resid.png}
148 +\caption{Residual diagnostics}\end{subfigure}
149 +\caption{Grand-model (M5) goodness of fit and residual behaviour.}
150 +\label{fig:fit}
151 +\end{figure}
added paper/sections/titlepage.tex +70 −0
@@ -0,0 +1,70 @@
1 +% Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +% ============================================================================
3 +% Title and abstract pages
4 +% ============================================================================
5 +\thispagestyle{empty}
6 +
7 +\begin{center}
8 +
9 +\includegraphics[width=4cm]{uq_logo.jpg}
10 +
11 +\vspace{0.6cm}
12 +
13 +{\footnotesize\textsc{Universit\'e du Qu\'ebec en Outaouais}}\\[0.15cm]
14 +{\footnotesize\textsc{D\'epartement des sciences administratives}}
15 +
16 +\vspace{0.8cm}
17 +
18 +{\footnotesize\textsc{Working Paper No.~\WPnumber}}
19 +
20 +\vspace{1.2cm}
21 +
22 +{\LARGE\bfseries \WPtitle\par}
23 +
24 +\vspace{0.4cm}
25 +{\large\itshape \WPsubtitle\par}
26 +
27 +\vspace{1.2cm}
28 +
29 +{\large \WPauthor}\\[0.3cm]
30 +{\normalsize \WPaffiliation}\\[0.15cm]
31 +{\normalsize \href{mailto:\WPemail}{\WPemail}}\\[0.15cm]
32 +{\small \WPaddress}
33 +
34 +\vspace{0.8cm}
35 +
36 +{\normalsize \WPdate}\\[0.1cm]
37 +{\small Version~\WPversion}
38 +
39 +\end{center}
40 +
41 +\vfill
42 +
43 +\newpage
44 +
45 +% ---------------------------------------------------------------- abstract
46 +\thispagestyle{empty}
47 +
48 +\vspace*{1cm}
49 +
50 +\noindent\rule{\textwidth}{0.4pt}
51 +\vspace{0.3cm}
52 +
53 +\noindent\textbf{Abstract}
54 +
55 +\vspace{0.15cm}
56 +
57 +\noindent\WPabstract
58 +
59 +\vspace{0.4cm}
60 +
61 +\noindent\textbf{Keywords:} \WPkeywords
62 +
63 +\vspace{0.15cm}
64 +
65 +\noindent\textbf{JEL Classification:} \WPjel
66 +
67 +\vspace{0.3cm}
68 +\noindent\rule{\textwidth}{0.4pt}
69 +
70 +\newpage
added paper/uq_logo.jpg +0 −0

Binary file not shown.

added requirements.txt +10 −0
@@ -0,0 +1,10 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +# Python >= 3.11. Versions pinned to the environment used for the 2026 rebuild.
3 +duckdb==1.5.2
4 +numpy==2.4.4
5 +pandas==3.0.2
6 +pyarrow>=16.0
7 +statsmodels==0.14.6
8 +linearmodels==7.0
9 +scikit-learn==1.6.1
10 +matplotlib==3.10.9
added results/reference/coef_M1.csv +9 −0
@@ -0,0 +1,9 @@
1 +,coef,se,p
2 +ln_living,0.657,0.022,0.001
3 +bathrooms,0.136,0.01,0.001
4 +half_baths,-0.035,0.009,0.001
5 +bedrooms,0.005,0.004,0.5
6 +parking_n,0.002,0.002,0.5
7 +stories_n,0.001,0.004,0.5
8 +has_lot,-0.212,0.038,0.001
9 +ln_lot,0.026,0.004,0.001
added results/reference/coef_M2.csv +9 −0
@@ -0,0 +1,9 @@
1 +,coef,se,p
2 +ln_living,0.65,0.022,0.001
3 +bathrooms,0.141,0.01,0.001
4 +half_baths,-0.039,0.009,0.001
5 +bedrooms,0.003,0.004,0.5
6 +parking_n,0.002,0.002,0.5
7 +stories_n,0.0,0.004,0.5
8 +has_lot,-0.221,0.038,0.001
9 +ln_lot,0.027,0.004,0.001
added results/reference/coef_M3.csv +9 −0
@@ -0,0 +1,9 @@
1 +,coef,se,p
2 +ln_living,0.585,0.016,0.001
3 +bathrooms,0.138,0.006,0.001
4 +half_baths,-0.026,0.009,0.001
5 +bedrooms,-0.003,0.003,0.5
6 +parking_n,0.001,0.001,0.5
7 +stories_n,-0.01,0.007,0.5
8 +has_lot,-0.034,0.039,0.5
9 +ln_lot,0.008,0.005,0.08
added results/reference/coef_M5.csv +9 −0
@@ -0,0 +1,9 @@
1 +,coef,se,p
2 +ln_living,0.547,0.009,0.001
3 +bathrooms,0.109,0.004,0.001
4 +half_baths,-0.036,0.009,0.001
5 +bedrooms,-0.002,0.003,0.5
6 +parking_n,0.001,0.001,0.5
7 +stories_n,0.001,0.0,0.001
8 +has_lot,-0.196,0.028,0.001
9 +ln_lot,0.03,0.004,0.001
added results/reference/ext2.json +21 −0
@@ -0,0 +1,21 @@
1 +{
2 + "nonlin": {
3 + "b1": 1.0649807666478583,
4 + "b2": -0.052590207607884756,
5 + "r2": 0.7680395097065289
6 + },
7 + "gradient": {
8 + "beta_logdist": -0.08536082624754465,
9 + "se": 0.0007873744041395624,
10 + "r2": 0.09474892883301556
11 + },
12 + "moran": {
13 + "struct_I": 0.45902667195055774,
14 + "struct_z": 145.24659997144295,
15 + "struct_p": 0.005,
16 + "grand_I": 0.08238138255845767,
17 + "grand_z": 23.425820155845653,
18 + "grand_p": 0.005
19 + },
20 + "lopo_mean": 0.3623228305498737
21 +}
\ No newline at end of file
added results/reference/fit.json +22 −0
@@ -0,0 +1,22 @@
1 +{
2 + "M1": {
3 + "r2": 0.464,
4 + "n": 82334
5 + },
6 + "M2": {
7 + "r2": 0.469,
8 + "n": 82334
9 + },
10 + "M3": {
11 + "r2": 0.567,
12 + "n": 82334
13 + },
14 + "M4": {
15 + "r2": 0.762,
16 + "n": 82334
17 + },
18 + "M5": {
19 + "r2": 0.767,
20 + "n": 140931
21 + }
22 +}
\ No newline at end of file
added results/reference/fsa_premia.csv +868 −0
@@ -0,0 +1,868 @@
1 +fsa_c,fe,n,prov,lat,lon,premium_pct
2 +V6S,1.0925336838666688,107,BC,49.25335851214953,-123.2259642411215,200.6447092235185
3 +V8E,1.0401767273939797,132,BC,50.10202857348485,-122.97235536969697,185.30884011338605
4 +V6T,1.0168535611547742,61,BC,49.26204722459016,-123.24006857868852,178.73153455348123
5 +V6G,0.9969262409686382,138,BC,49.289252171739136,-123.13348826014492,173.2321381173812
6 +V7T,0.9725536836139383,54,BC,49.32848744444445,-123.14147361111111,166.6532697459004
7 +V5Y,0.9612125334200508,114,BC,49.254106732456144,-123.11079856754387,163.6461990155594
8 +V5Z,0.9412597452265452,174,BC,49.24777875402299,-123.11981959022988,158.43785552742756
9 +V6M,0.935150065028788,64,BC,49.23410638125,-123.1465720203125,156.86369657974208
10 +V6Z,0.9310187062832944,235,BC,49.27605226255319,-123.12563951702128,155.80468957567302
11 +V6K,0.9171123320328061,86,BC,49.26588249186047,-123.16110177790698,152.27199425039134
12 +V6E,0.901259209447455,147,BC,49.28400365578232,-123.12564494761905,148.30422923167657
13 +V6J,0.8764868799439702,97,BC,49.26358798969073,-123.14441420103093,142.22871802336434
14 +M5R,0.8735551490871547,117,ON,43.67220532820513,-79.39600831538462,141.51960858324384
15 +V6P,0.8677284178636656,180,BC,49.21633932722222,-123.13091813777777,140.11643067899547
16 +H3Z,0.7869861583505781,80,QC,45.483907550875,-73.59167753325,121.49093741021395
17 +V5V,0.7813136522988866,66,BC,49.2510103469697,-123.09044469545454,120.23808549185419
18 +V6B,0.7790237215196855,317,BC,49.27784318264984,-123.11714510694007,119.73433252098155
19 +M4V,0.7781521366583772,79,ON,43.686205711392404,-79.40124440632911,119.54289884071416
20 +V7L,0.7718154860848888,194,BC,49.31319002010309,-123.07022435515464,118.1561305780785
21 +M4G,0.7665865086320841,57,ON,43.7090933877193,-79.36629159649122,117.01837433336566
22 +V6H,0.7492605280398154,53,BC,49.259071949056604,-123.1211127018868,113.29070421177536
23 +V5T,0.7364354489630449,146,BC,49.26285982212329,-123.09317585157534,110.57270062465517
24 +M5M,0.7351244797519351,62,ON,43.7304442483871,-79.41810049838709,110.29682716775069
25 +M5S,0.7326884872713249,81,ON,43.66527621395062,-79.39243932530864,109.78516912865919
26 +M4W,0.7279863210868173,116,ON,43.672825213793104,-79.38232881551724,108.80103998305341
27 +V7P,0.715874487564562,103,BC,49.324985714563105,-123.11346022427185,106.28733009464817
28 +T1W,0.7050424054218435,144,BC,51.07958369780555,-115.3408182382014,104.0648674697442
29 +V5X,0.704367658941362,113,BC,49.214213138053104,-123.10437581681416,103.9272218617961
30 +V7J,0.7028063001324015,110,BC,49.31863358181818,-123.03439226363635,103.60906673934119
31 +V5N,0.6991040510050799,170,BC,49.25667369235294,-123.06651573941177,102.85664892821002
32 +V6A,0.6936862639874061,87,BC,49.27844599885057,-123.0969782275862,101.76058660631217
33 +M5E,0.6917919732126959,136,ON,43.64484033602941,-79.37409938382353,101.37875515248228
34 +M6J,0.6866895632885915,103,ON,43.64523133038835,-79.42044304563106,100.3538551472372
35 +M4S,0.6853032714079192,113,ON,43.703525412389375,-79.39309123097345,100.07629865619099
36 +H2V,0.6794815467618405,167,QC,45.51882259209581,-73.61069515143713,98.91489350793552
37 +M5T,0.6683017752540151,88,ON,43.653551057045455,-79.39621801784091,96.70345517009966
38 +M5P,0.6663404614592622,53,ON,43.69288705283019,-79.41585144528301,96.31803605746111
39 +V7M,0.6661303354534387,143,BC,49.317949494405596,-123.07715153076923,96.27678886637878
40 +M5J,0.6648279268545991,136,ON,43.64255669529412,-79.37989593058823,96.02132268559347
41 +V5C,0.6647428082984759,334,BC,49.266616878443116,-123.00446478353294,96.00463834372073
42 +M4L,0.6626806325935446,80,ON,43.66916659525,-79.31544520050001,95.60085881573251
43 +L6J,0.6579969732385992,70,ON,43.48274887828571,-79.65925323399999,94.68687309321058
44 +M5V,0.6521113356960514,608,ON,43.642139918141446,-79.39927199338815,93.54438216569744
45 +M4M,0.6489954285242762,80,ON,43.661866098625,-79.344496877875,92.94225441150965
46 +M4P,0.6450975493494587,113,ON,43.70969964955753,-79.39240470619468,92.19165264394891
47 +V5H,0.6444005500389198,406,BC,49.22717825960591,-123.000975341133,92.0577418678453
48 +V5K,0.635153006101534,88,BC,49.28709072545455,-123.00190307215908,90.28986631344986
49 +XBC,0.6323795089250491,178,BC,49.3558738771904,-122.44415465176056,89.76282911245363
50 +M6P,0.6316000024652962,65,ON,43.660300795384615,-79.46310644461538,89.61496539918654
51 +M5G,0.620307614951655,56,ON,43.656454582142864,-79.38556616964286,87.48580401471766
52 +V5P,0.6196112695758039,50,BC,49.221308523999994,-123.066947012,87.35529458714612
53 +M4Y,0.6146638499443928,207,ON,43.6664629410628,-79.3819039231884,86.43065849206393
54 +M6G,0.5995281064543195,55,ON,43.667948712727274,-79.42046832545455,83.63013930071384
55 +V5R,0.5958217803307846,195,BC,49.23825596102564,-123.04046092461539,82.95080581174214
56 +V5L,0.5934412615108324,58,BC,49.2797864724138,-123.0641884862069,82.51580594349237
57 +V7C,0.5877055960451602,190,BC,49.167680536842106,-123.15963086684211,81.47195279633613
58 +L5H,0.5836202913474252,108,ON,43.54206136083334,-79.60503051175927,80.73209687250915
59 +M6K,0.5834824102877814,165,ON,43.63956636872727,-79.41825212878788,80.70717905736755
60 +V8S,0.5818264115209356,51,BC,48.45529912882353,-123.24218735,80.40817583450306
61 +V7E,0.5803645743549077,134,BC,49.131808500000005,-123.17006823358209,80.14464112735804
62 +M5A,0.5802887487492234,300,ON,43.654056123900006,-79.36410062996667,80.13098206869354
63 +M6S,0.5799669391281688,103,ON,43.642857884951454,-79.47543324786407,80.07302351192457
64 +H3J,0.5799016914434617,140,QC,45.48786321028572,-73.56970971307142,80.06127454736276
65 +H3B,0.5771792823821454,142,QC,45.49276104415493,-73.59793923485915,79.57174075990099
66 +L6L,0.5771740347483933,193,ON,43.40267265564767,-79.71022984000001,79.57079843564574
67 +V5S,0.5712482872990146,138,BC,49.20814695144927,-123.03039088768115,78.50985378440507
68 +H2Z,0.5631776219242789,59,QC,45.504079639322036,-73.56302240915254,77.07495855659361
69 +M8V,0.5620564416063119,266,ON,43.62014299,-79.4852561931579,76.87653685229532
70 +H3G,0.5593983181859262,354,QC,45.4970781629096,-73.57571249483051,76.40700150508626
71 +H2Y,0.5553362709436979,113,QC,45.504820934690265,-73.55542577486726,75.69188134036276
72 +V3J,0.5527962286147142,417,BC,49.25901872844433,-122.88441025418952,75.24618281109497
73 +L5G,0.5515107276262697,132,ON,43.56012846212121,-79.58319322666668,75.02104840612336
74 +H2J,0.5472874048860794,91,QC,45.529258230329674,-73.58201836043956,74.28343671485689
75 +L6K,0.5465255613266519,88,ON,43.44116892454545,-79.6831973075,74.15071056578128
76 +H2T,0.544744199267747,55,QC,45.52445799363637,-73.594340012,73.84076124539007
77 +L7R,0.5380722527207478,160,ON,43.333123727625,-79.798798251625,72.68476563737023
78 +V6X,0.5345959647083416,480,BC,49.181608957689804,-123.1269859278566,72.08550585993353
79 +V5A,0.5340154732387689,121,BC,49.27571034876033,-122.91564597190082,71.98564067999158
80 +M8Y,0.5319070086386273,95,ON,43.627862064842105,-79.49140403652632,71.62339706800125
81 +H3K,0.5284167765512905,101,QC,45.48020237792079,-73.56505899425743,71.02543569961061
82 +V0V,0.5265722254153604,158,BC,49.32322952981797,-122.99079027931727,70.71026130492346
83 +V3H,0.5225357916294232,256,BC,49.28109370378906,-122.84500172046874,70.02258944322881
84 +V8B,0.5205162055862118,171,BC,49.70227148058479,-123.14849389748538,69.67956069918395
85 +M6H,0.5184254585077012,90,ON,43.665936627444445,-79.440062647,69.32517424867906
86 +M5B,0.5169931201592706,165,ON,43.657262665393944,-79.37669975890908,69.08281691853186
87 +V8Y,0.5144937662617938,61,BC,48.519147915081966,-123.37316194868853,68.66074679209248
88 +V8W,0.5131903377429542,101,BC,48.42692640128713,-123.36505527742574,68.44105277354315
89 +V5B,0.5106367919432621,69,BC,49.27002504927536,-122.97860230869564,68.0114795316341
90 +H3E,0.5089350229367406,312,QC,45.463389512019226,-73.54601841179488,67.7258059471963
91 +V6Y,0.5085363150544935,466,BC,49.16321200064378,-123.13240907210302,67.65894567605318
92 +V5J,0.5068258205933809,87,BC,49.21711755287357,-122.98784176551725,67.37241110587762
93 +H2S,0.5063681537312418,74,QC,45.534869613513514,-73.60592596283783,67.29582782582962
94 +L7B,0.5041408016136611,88,ON,43.937223164772725,-79.55951417727273,66.92361578697748
95 +M2N,0.5039923522694439,508,ON,43.768244577165355,-79.40971892173228,66.89883792485374
96 +M2K,0.5001137359847031,169,ON,43.77005613668639,-79.37893308011834,66.25275513773796
97 +H3A,0.4931157575925549,99,QC,45.50463486888889,-73.57192755505051,65.0933833105104
98 +H3C,0.491009045962742,659,QC,45.49481268691957,-73.56064805188164,64.74594526427224
99 +V3N,0.49091878295468494,238,BC,49.220909621512604,-122.93663795228778,64.73107547079373
100 +L6G,0.48962249939169666,100,ON,43.854794586999994,-79.33263630100001,64.51767562858367
101 +V7A,0.4893481092541994,102,BC,49.13961574607843,-123.11682765980393,64.47253979364437
102 +M8Z,0.486211200566897,105,ON,43.62729407685714,-79.51700381647619,63.95741283027869
103 +M6B,0.485601207226043,72,ON,43.707824917500005,-79.44787965944444,63.85743039767784
104 +M9A,0.48472479410007413,108,ON,43.65755771944445,-79.5263898787037,63.71388650595322
105 +V3K,0.4758558170850861,222,BC,49.24278744994002,-122.86744199414414,62.26833158164629
106 +M8W,0.4738857263283052,59,ON,43.599655339322034,-79.53986481135594,61.948962937382035
107 +V9A,0.46746961915961877,269,BC,48.43592613301115,-123.39741033691449,60.9132073479437
108 +V5E,0.46445987891404544,103,BC,49.2210851446602,-122.96103201747573,60.429628480177435
109 +M4J,0.46070249719527306,53,ON,43.68624149056603,-79.33681994716981,59.82796417605887
110 +H1Y,0.4584934944797613,50,QC,45.5469413234,-73.5762097886,59.47529343789879
111 +V8V,0.45102264699481653,140,BC,48.421299179142856,-123.36135712042856,58.28831722291839
112 +M9B,0.44338717523884086,134,ON,43.642383943358205,-79.55127546089551,57.084313664531926
113 +H4A,0.4420023636261152,111,QC,45.4729043845045,-73.61696003018018,56.86693203383497
114 +V4L,0.441144626108056,56,BC,49.01915098571429,-123.05950948571429,56.732439068963345
115 +L3T,0.43935272870387343,209,ON,43.8155042723445,-79.40845262038277,56.451842093820815
116 +M2M,0.43404274903038875,133,ON,43.78746035263158,-79.41528160977444,55.623287742622615
117 +L5J,0.43219622710357286,108,ON,43.51483070259259,-79.6303898437963,55.33619107620229
118 +M1N,0.4306201096619401,72,ON,43.69452649861111,-79.26598770416666,55.091555833709016
119 +L3R,0.42997659432110963,176,ON,43.855311036931816,-79.32248972954545,54.991784144046264
120 +V8R,0.42946944212282206,83,BC,48.433864826385545,-123.32675938771084,54.91319964883519
121 +M3H,0.42918690747421057,130,ON,43.74061505453846,-79.44508818569231,54.86943748486206
122 +H2H,0.4274649942494293,72,QC,45.53300684277778,-73.57666343305556,54.60299521341096
123 +V4B,0.42642006875956273,247,BC,49.02796160186308,-122.80140418079172,54.441530976642596
124 +L5E,0.4261993861380483,76,ON,43.5830920156579,-79.56751400013158,54.40745217515391
125 +H4C,0.42612200499063496,115,QC,45.47649434634782,-73.5859912552174,54.395504411607206
126 +H2L,0.4258025054001636,252,QC,45.517315464920635,-73.55602448519842,54.34618299068352
127 +L4K,0.422754188772535,235,ON,43.809756358808514,-79.52441011289362,53.87640333700201
128 +L7N,0.41479765671137414,80,ON,43.3461326945,-79.77773671474999,52.656938588898285
129 +M2J,0.4136743669295089,195,ON,43.778135812820516,-79.34705057076923,52.48555688333036
130 +V6V,0.4130612275447491,78,BC,49.17682761794872,-122.98094028076922,52.3920906396439
131 +H3H,0.41250495943556853,198,QC,45.49211574984848,-73.58344043858585,52.30734335282152
132 +V8M,0.40558802473681793,68,BC,48.58669803220589,-123.42030706867648,51.25747851378344
133 +V4M,0.4052893446616825,155,BC,49.02987598774193,-123.08553847548387,51.21230766488822
134 +V3B,0.40421375196549625,385,BC,49.27628869674761,-122.77632486068681,51.04975224857136
135 +V8L,0.4034386609946147,116,BC,48.65562943827587,-123.41203305137932,50.932720310507904
136 +M6E,0.4021828881037992,56,ON,43.68869573928571,-79.44732337857144,50.74330205005537
137 +H2X,0.39941800612474593,158,QC,45.5102038413924,-73.56781236512658,50.327090264134085
138 +L7S,0.3993159143707598,107,ON,43.323556469439254,-79.80677573831775,50.31174389119979
139 +H3X,0.39815801094479325,62,QC,45.48277969854839,-73.63506315354839,50.13779813361416
140 +V3L,0.39621100724961567,187,BC,49.216944285026734,-122.9022059106952,49.84576367420224
141 +L4J,0.3861695713542717,299,ON,43.80784435979933,-79.45008760247492,48.34862632815198
142 +V3E,0.38564860240829013,159,BC,49.29629804591195,-122.77784996603772,48.271361428710115
143 +H3S,0.3848509689929908,66,QC,45.51107112287879,-73.62704547499999,48.15314239029811
144 +L4L,0.3842370038360322,160,ON,43.7952306431875,-79.586533165625,48.06220944066435
145 +L4C,0.38170822136929966,327,ON,43.86483785409786,-79.44059626987767,47.688265332370335
146 +V3M,0.3816444896167805,368,BC,49.20012438967392,-122.92354608970108,47.67885320032321
147 +M3A,0.38159903180672544,52,ON,43.75777056538462,-79.32943425384616,47.672140195645696
148 +L4B,0.3806192416660238,138,ON,43.851870642753624,-79.41356529130435,47.527523347276016
149 +H3W,0.37964197013971224,66,QC,45.49156095515151,-73.63825344560605,47.38341932520924
150 +M3C,0.3763712314382755,137,ON,43.72279223510949,-79.3353165359124,46.902154147031226
151 +V8N,0.3758032734017775,80,BC,48.476387493124996,-123.32230179749999,46.8187435770985
152 +V4K,0.3684604232009751,142,BC,49.09987876711268,-123.0508074506338,45.74462391238474
153 +H4P,0.365402137404464,80,QC,45.500320964875,-73.653716276875,45.299576087757856
154 +L6C,0.3638677077808315,104,ON,43.89060367115384,-79.34802891634617,45.07679507850864
155 +M6N,0.36340746865913787,94,ON,43.674688193617015,-79.4755747137234,45.01004042449359
156 +H4G,0.3570821311383095,63,QC,45.46368533269841,-73.57123447873015,44.095697786358336
157 +L6M,0.3564489737470572,339,ON,43.44442814038348,-79.75053074053096,44.00449140730072
158 +M6A,0.35573062827663987,87,ON,43.713655064252876,-79.45583717068966,43.90108357889781
159 +M4C,0.3544468653032337,82,ON,43.6912887792683,-79.30571371341463,43.71646722314182
160 +L6H,0.35424852452987327,349,ON,43.4823293595702,-79.71531387776504,43.687965214536796
161 +V3C,0.3528863547771747,237,BC,49.25601562869198,-122.78413112869198,43.49237106095851
162 +L3P,0.35241163540864895,71,ON,43.88302646619718,-79.26442122816901,43.42426861923321
163 +V4A,0.3491799299813591,237,BC,49.03986656741906,-122.79532274247883,42.961511781572796
164 +L7K,0.3477104838588983,54,ON,43.87572501925926,-80.01473003537038,42.75159181323882
165 +M3M,0.34259923281218846,63,ON,43.73017160603175,-79.48714938396826,42.02381410188358
166 +L6A,0.338715044855174,168,ON,43.85975963309524,-79.50502111107143,41.473236878459296
167 +M9C,0.33224927456046,126,ON,43.63645783349206,-79.57141387119047,40.56145429084908
168 +H9S,0.3306331538117244,98,QC,45.44487940408163,-73.7666272044898,40.33447347170611
169 +H4B,0.32817393660429844,61,QC,45.4668393847541,-73.63225761721311,39.98978452595874
170 +K1S,0.3267703551732366,117,QC,45.40150051025641,-75.6921106,39.79343529216371
171 +V3T,0.32526759017576495,566,BC,49.18861408988866,-122.84397303988108,39.58351637963238
172 +L6E,0.32502526481430116,73,ON,43.89922047534247,-79.2700620630137,39.54969585152266
173 +V8P,0.32466345219477344,93,BC,48.47469091193548,-123.33396282354839,39.49921414352253
174 +V4P,0.3243870330738044,111,BC,49.068367194721446,-122.77679525598691,39.46065922227731
175 +M1M,0.32364607032864456,95,ON,43.728766697894734,-79.22684345610526,39.3573623436736
176 +L7P,0.320211230085214,166,ON,43.360644596024095,-79.84873890680723,38.879513204813755
177 +L4E,0.3165597487616398,198,ON,43.935920685252526,-79.45423850530302,38.373321992432196
178 +L5B,0.3137982512155193,419,ON,43.58468133002386,-79.63852984818617,37.991731526365925
179 +L7L,0.3132144249699318,185,ON,43.38163338286487,-79.76723394394594,37.91119184470444
180 +V8T,0.3115921328317856,88,BC,48.43808258875001,-123.35765040897728,37.68764098384345
181 +T2L,0.30919438984632935,55,BC,51.07511494178182,-114.1220316057091,37.357896887267295
182 +H4R,0.30426799329696214,241,QC,45.51329138576764,-73.70988624414939,36.68288147998353
183 +L4G,0.30392847012178076,225,ON,43.998765813333335,-79.46276066222222,36.636482351305986
184 +V1M,0.3038060331525727,131,BC,49.16789236829544,-122.63967426788602,36.61975401862772
185 +V4E,0.30165298227945714,74,BC,49.12691328971437,-122.90216997681118,36.325921169997024
186 +M6M,0.30080329198562283,85,ON,43.6942619417647,-79.48466584176471,36.210135555903264
187 +V2Y,0.29970853058282376,494,BC,49.14544117938051,-122.63097306337444,36.06109955114445
188 +L4S,0.29507650564550325,75,ON,43.91031441333333,-79.4261700016,35.43231853394217
189 +V8Z,0.2918088649842146,116,BC,48.48143344051724,-123.39820000551724,34.99049663377956
190 +M2R,0.29095671002578033,107,ON,43.780080790186915,-79.44509874121495,34.87551281170678
191 +M2H,0.2896247507366127,57,ON,43.802804316666666,-79.35995885684211,34.695983708806224
192 +K2A,0.28716031466837655,51,QC,45.38773149607843,-75.7896050764706,34.36444276683508
193 +H2K,0.28639460188080595,152,QC,45.53025866802631,-73.55666822355263,34.261597574778044
194 +L5R,0.2862904607454754,118,ON,43.60354915847458,-79.65688163381357,34.24761614760878
195 +V3Z,0.2854937289859485,239,BC,49.04730085529476,-122.77752989349919,34.140699405820854
196 +L5M,0.28414236490897465,288,ON,43.560154465555556,-79.71829526427084,33.959548911087076
197 +L4A,0.283138121428284,164,ON,43.98619014451219,-79.26611118292683,33.825088434245856
198 +M1T,0.2814466611687961,108,ON,43.78121283768519,-79.29809576240741,33.59891994686408
199 +V8K,0.28143165385943053,86,BC,48.85732078,-123.51460901755814,33.59691500158599
200 +L7T,0.2794099667735544,136,ON,43.31194977764706,-79.84213952720587,33.327096679823256
201 +V4C,0.27748642544184543,207,BC,49.15516404004479,-122.90830273705352,33.0708829965271
202 +V1Y,0.27572832113823625,522,BC,49.878937206226055,-119.49267727406131,32.837136040418535
203 +H9R,0.2755978354894675,101,QC,45.45726239059406,-73.8144499291089,32.819803831368574
204 +H3L,0.2721894498432689,52,QC,45.5472493025,-73.66891250807693,32.36787333268103
205 +L1W,0.2715149924117964,86,ON,43.82465718953488,-79.09300978372093,32.27862693665424
206 +L7M,0.268875997742644,240,ON,43.388448761625,-79.81267451354167,31.930004553956024
207 +H1X,0.26879333417859075,52,QC,45.554701448653844,-73.57006875423077,31.919099200317945
208 +H9X,0.26515439398575463,66,QC,45.41710128727273,-73.9327119471212,31.439925858364948
209 +L5C,0.2645409635353689,75,ON,43.56143002253333,-79.64395328426667,31.359321330610477
210 +V9B,0.2637358306811238,498,BC,48.45441336427711,-123.50507767174699,31.25360218998352
211 +V3Y,0.26197424870702707,124,BC,49.21945656048387,-122.68549274919356,31.022591741989626
212 +L9E,0.2613231837797864,81,ON,43.50156401320987,-79.84531200876543,30.93731529109569
213 +V8X,0.2608904540734823,133,BC,48.46558333045113,-123.36953724759398,30.880667082670787
214 +M1P,0.26065195932423463,143,ON,43.76638952783217,-79.26548178083917,30.849456452727164
215 +V4N,0.25928649464665415,391,BC,49.1533318688766,-122.73194988090775,30.670908070356905
216 +L3Y,0.25590721628515295,161,ON,44.06078280124223,-79.46152809341615,30.230079958191112
217 +H4M,0.25479135260793795,77,QC,45.50154046558441,-73.67926745493506,30.084841990241728
218 +L5L,0.25461760623645124,108,ON,43.539662820740745,-79.69211816796296,30.062242184334487
219 +H7T,0.2540912028379323,141,QC,45.56247171503546,-73.76089263929077,29.993794995026768
220 +M9M,0.25266512157987064,59,ON,43.73781486355932,-79.54368708474576,29.808545402201545
221 +L4H,0.247825951266435,162,ON,43.885418864314815,-79.81617704042593,29.181897194443927
222 +G1R,0.24542246714392393,66,QC,46.81043285166666,-71.21550812030303,28.871783381720874
223 +L0B,0.24422199106640136,59,QC,44.10786907118644,-78.80066791694915,28.717168712877527
224 +V3A,0.2433360113325592,317,BC,49.09596835659738,-122.65821511368323,28.60317841400417
225 +L9P,0.23721779099440873,69,ON,44.10615449478261,-79.14831631014492,27.818757907935797
226 +T2M,0.2368172390511088,88,BC,51.06505927036364,-114.07836954055682,27.767570108436267
227 +T2N,0.23656798399161996,136,BC,51.058159152882354,-114.10323192552205,27.735727363795615
228 +L7G,0.23537324759705625,146,ON,43.64541310575343,-79.9094244139726,27.583207969805578
229 +H1V,0.23428800688846343,73,QC,45.55560602027398,-73.53918237863013,27.444824582008522
230 +P0C,0.23327393522220113,56,QC,45.08990898928572,-79.69903599285715,27.3156519026347
231 +V4W,0.23254058967151603,92,BC,49.055138149307716,-122.4773074040243,27.22231976231706
232 +L5V,0.23184552762826874,67,ON,43.59289476850746,-79.68674291238807,27.13392308094418
233 +V3V,0.23168328231291718,174,BC,49.17875063774303,-122.85778090112797,27.113297870719144
234 +V3R,0.22981543283414582,329,BC,49.1922467408193,-122.81123769578242,26.87609096590833
235 +J4Z,0.2275824428668562,221,QC,45.45574204900452,-73.43254233108597,26.593094009965213
236 +P0E,0.22444801492962219,56,ON,44.86133528,-79.53497559285714,26.196918295909466
237 +L9T,0.2233465020107409,260,ON,43.51167025334615,-79.86946104176923,26.057987291279172
238 +L5A,0.22321274330706914,134,ON,43.59328066985074,-79.61504483873135,26.041127065937687
239 +M1S,0.21762576992599478,97,ON,43.787444254948454,-79.27613653587629,25.338902126740148
240 +H1W,0.21758614822307132,87,QC,45.54510330011494,-73.54502566551724,25.333936084377505
241 +H9W,0.21618893675836787,55,QC,45.43171237272727,-73.86369415963637,25.15894035345365
242 +V1W,0.2148789375238987,370,BC,49.832129482891894,-119.47655952902703,24.995089583027564
243 +L4Y,0.21375304392698594,64,ON,43.6208864684375,-79.6047929059375,24.854437606458358
244 +M1H,0.213231721208216,63,ON,43.77534122857143,-79.24616266031745,24.789365114952734
245 +V2X,0.2123179361224913,419,BC,49.222562085966594,-122.59707398639618,24.67538653814647
246 +H8N,0.21197253770387203,184,QC,45.44214373027174,-73.61254208,24.63233129283031
247 +K1Z,0.2111930215543933,69,QC,45.38943826086957,-75.7428131942029,24.535216234136282
248 +L6B,0.20992123624795384,65,ON,43.881371161384614,-79.23594610692308,24.37693484730068
249 +V3S,0.20764192186898414,454,BC,49.1192701284593,-122.76601217607927,24.09376355208952
250 +L9H,0.2073759521137184,138,ON,43.27693399231884,-79.96257145007247,24.06076275296933
251 +B3K,0.20707565796527388,57,NS,44.65699289578948,-63.59714011035088,24.023513624990557
252 +H4L,0.20680819668218978,74,QC,45.517496101486486,-73.67814538121623,23.990346572552745
253 +M9W,0.20657768570881282,95,ON,43.72228922073684,-79.58006120947368,23.961768730954546
254 +V0N,0.205498332954429,579,BC,49.565122564162344,-123.82249293699482,23.828042436341335
255 +V9J,0.2051937989978249,54,BC,49.776672143703706,-125.12482071407406,23.790338334020777
256 +L5N,0.2048912478192124,189,ON,43.58572167037037,-79.75834428010582,23.752891086397064
257 +K2P,0.201842849686115,104,QC,45.41479849423077,-75.6930021576923,23.376217421586066
258 +V9C,0.2005424760276715,209,BC,48.416148858660286,-123.51049595956938,23.21588650601518
259 +L9G,0.19999483913213653,186,ON,43.2115801744086,-79.97991405752688,23.148427413678352
260 +L7E,0.19965181708583501,113,ON,43.89710461008849,-79.76053293628318,23.106192032355686
261 +M1J,0.1994113032354513,59,ON,43.74670331694915,-79.22795723220338,23.076586848475
262 +L1N,0.1979113740997207,121,ON,43.87736059090909,-78.93659660826447,22.892119068817784
263 +M1W,0.1973116601960216,78,ON,43.80231812564103,-79.31967673461538,22.818441051431115
264 +L4Z,0.19598357503397565,136,ON,43.6058992894853,-79.64538685147058,22.655435968520244
265 +M3J,0.19457462313435342,65,ON,43.758571288,-79.4905736956923,22.482742046296835
266 +M1K,0.19356493322412854,61,ON,43.728040239016394,-79.25964839704918,22.35913487043635
267 +L7C,0.19115512118885383,122,ON,43.78323749393442,-79.85447295311475,22.064627351004027
268 +V3X,0.1870449104159916,183,BC,49.11450359978964,-122.8427320581033,21.563945663183226
269 +L9L,0.18696866518034022,85,ON,44.09736780988235,-78.95684246905883,21.55467734483647
270 +L3M,0.18560835190593405,193,ON,43.200406903886005,-79.57671737792747,21.389437318259663
271 +P1P,0.18513020460935947,89,ON,44.92191506213483,-79.37435194438201,21.33140916108203
272 +V4S,0.18374033795565586,60,BC,49.174902812223884,-122.34484167250189,21.16289181688831
273 +V3W,0.18241886670240584,468,BC,49.13638065208122,-122.85442025145565,21.00288428435382
274 +L9Y,0.18125712753564432,434,ON,44.50307130580645,-80.25702647205068,20.862392117816952
275 +J2L,0.18096923916332475,114,QC,45.30858490666667,-72.6717706204386,20.82760224851521
276 +M1B,0.18045061820217836,149,ON,43.803317,-79.2149676771812,20.76495476785656
277 +V9P,0.17698152967275632,223,BC,49.31774374699551,-124.29305313959641,20.34673628640702
278 +L3S,0.1762439829182505,74,ON,43.84829711351351,-79.25293174594594,20.25800766641863
279 +P0G,0.1762005715261164,52,QC,45.485341,-80.18743134076924,20.252787212204982
280 +V4V,0.17575616488210688,176,BC,50.050945243548064,-119.43456814102274,20.199357947646646
281 +M9R,0.1755027534425772,62,ON,43.68725427096774,-79.5586979032258,20.168901914435168
282 +L8B,0.17488172909214117,174,ON,43.342240413390805,-79.90926895304598,20.094297268229866
283 +J8E,0.17334649770207267,310,QC,46.18479280074194,-74.59726172512903,19.910066188149102
284 +T3Z,0.17167820748350054,57,BC,51.07982419124561,-114.37972288145613,19.710188171247566
285 +L0G,0.16990190125982638,187,ON,44.04926515272727,-79.68264438893048,19.497734965799474
286 +M1E,0.1694362939930749,132,ON,43.768366069772725,-79.19072617977272,19.442108902993517
287 +G1S,0.16909780414059797,51,QC,46.793530874313724,-71.24401846627451,19.401685802961953
288 +H7N,0.16730454495953578,81,QC,45.56311512506173,-73.7109016574074,19.187759503639956
289 +H4N,0.1671471827652985,78,QC,45.53066907051282,-73.67492530307693,19.169005331915745
290 +N9V,0.16679448327718502,66,ON,42.13733066590909,-83.0547252059091,19.12698189599398
291 +V4R,0.1623802330797287,107,BC,49.237776287850465,-122.57068483551403,18.602284517394295
292 +K1R,0.16219561748521286,106,QC,45.4142082745283,-75.70626637358491,18.580390707158756
293 +N0B,0.16028231641132495,468,ON,43.57956518574786,-80.35989711604701,18.353727624782024
294 +J4K,0.15851387056131916,81,QC,45.520879472345676,-73.51744505432099,18.144610427050935
295 +M1V,0.15841765255091964,65,ON,43.81505365076923,-79.28574184923077,18.133243334564497
296 +N1L,0.15506147482273241,174,ON,43.51140324293104,-80.18756699591954,17.737431752866772
297 +L0L,0.15380837064393152,271,ON,44.47236001715867,-79.70855509298893,17.58998688631919
298 +V9K,0.15202170283531044,106,BC,49.34103003575472,-124.49989882075472,17.380080214718063
299 +V9M,0.15085884977258715,71,BC,49.67281577788732,-124.91141238014085,17.243663760455675
300 +L9W,0.15034695239645474,216,ON,43.92215520041667,-80.14084045694445,17.183662395189494
301 +J3E,0.15014112531481524,66,QC,45.59116374333334,-73.3089478730303,17.159545306003054
302 +J4Y,0.1497109897784618,138,QC,45.43730300688406,-73.45070323681159,17.109161658819303
303 +T3B,0.14925101102470292,166,BC,51.09102969589759,-114.1887421325,17.055306319691166
304 +V2W,0.14737783631174217,152,BC,49.19990025657895,-122.54076818157895,16.836246512573695
305 +L1V,0.14429624374184405,112,ON,43.833086972589285,-79.10519722794642,16.476758984953598
306 +L4T,0.14024203612535074,72,ON,43.704407573611114,-79.66491500694445,16.005493970137906
307 +L3X,0.1401793726441067,104,ON,44.04138856153846,-79.46753677980769,15.99822488979763
308 +J4X,0.1368577424162718,84,QC,45.445137734642856,-73.48965533154762,15.613560889088362
309 +M9V,0.13567287598913785,74,ON,43.74569663621621,-79.58294284554054,15.476655385653725
310 +H8S,0.13565186404361335,64,QC,45.438862841562496,-73.67310251359375,15.474229021952812
311 +H9H,0.1355440431851148,81,QC,45.485777092469135,-73.83807338049382,15.461779162634537
312 +H4W,0.13506869997513254,120,QC,45.472802090916666,-73.66415563333334,15.406908232192373
313 +J5R,0.12666155371570859,195,QC,45.39404981748718,-73.49770819610256,14.440732556223246
314 +K1N,0.12344067005818996,179,QC,45.428573260893856,-75.68628930670391,14.072725243493235
315 +L1C,0.12271808560915892,134,ON,43.915190494402985,-78.6954183938806,13.99032783930032
316 +P1H,0.12231376502235235,237,QC,45.34340467274262,-79.16968316902954,13.944248519094682
317 +H1N,0.12154969782784437,71,QC,45.63860454507043,-73.30701558352114,13.8572207085798
318 +N1E,0.1205615436937798,230,ON,43.5642440233913,-80.24256048813044,13.744767794799696
319 +V7Z,0.11738977328344857,161,BC,49.48020777018633,-123.78973111801243,13.384567044990249
320 +L8E,0.11655814318287229,275,ON,43.23034738985454,-79.70964620578182,13.290312224100198
321 +H7R,0.11607427147094831,52,QC,45.55126828365384,-73.85937917384615,13.23550750707534
322 +H7W,0.11602322687577411,92,QC,45.53145113597826,-73.75233587967391,13.2297275939532
323 +N1G,0.1131566320799406,142,ON,43.51916822739437,-80.22523459260563,12.905608626921117
324 +H7P,0.11093379843779971,68,QC,45.57778821426471,-73.7929977160294,12.654916967827678
325 +V1Z,0.1107827407309159,206,BC,49.9142771546602,-119.54923195999999,12.637900859640826
326 +L1X,0.11044163211406136,99,ON,43.87296507060606,-79.09863644959596,12.599485653324628
327 +N1H,0.10978472496947542,173,ON,43.5493190243643,-80.26000513831913,12.525542536262236
328 +K4P,0.10822670476913371,52,QC,45.25140277692307,-75.57621766153846,12.35036197080268
329 +J7J,0.10809130560850408,71,QC,45.669819523802815,-73.91754450943662,12.33515085590473
330 +L6W,0.10802169043402395,68,ON,43.682876894705885,-79.74447497970588,12.327330896974708
331 +V0R,0.10784530532387449,437,SK,49.06612451256293,-124.17702642073226,12.307519775586417
332 +V9V,0.10740318844204412,67,BC,49.22770787626866,-124.01844621567164,12.257877699745645
333 +K7L,0.10571328394417276,103,ON,44.249325569902915,-76.48586946893204,12.068332808789407
334 +V0M,0.10489436428234947,168,BC,49.2799258399177,-121.87038038850376,11.9765954154889
335 +J1X,0.10341027907396311,188,QC,45.26411309260638,-72.16765168441489,11.810535860291061
336 +T2J,0.10299325898322022,105,AB,50.946966696733334,-114.04238945461904,11.763918341377156
337 +L9K,0.10108997596271503,89,ON,43.22972317078652,-79.94180702674157,11.551402276554823
338 +L9B,0.099157666149348,130,ON,43.20781327438462,-79.906366351,11.33605852966324
339 +L9N,0.09785671406501326,94,ON,44.097383976276596,-79.48576089297872,11.191309828235196
340 +J7C,0.09718103713960011,85,QC,45.674720692,-73.85670615941176,11.116205801763957
341 +L1B,0.09684046286941332,61,ON,43.904745081967214,-78.59676506721311,11.07836892456624
342 +T3E,0.09412797313437787,180,BC,51.02094003887222,-114.13436668295,10.777478254986272
343 +V9Z,0.09145427615563924,193,BC,48.3795976538342,-123.7358888427461,10.481688448427962
344 +N3C,0.09027262157736786,83,ON,43.42923438530121,-80.30735017566265,10.351214358292538
345 +P2A,0.0890673355209443,109,ON,45.34618277211009,-79.95370655504587,10.218289700527162
346 +V1V,0.08877193908548679,318,BC,49.92333347330189,-119.47242695264151,10.185736418925773
347 +N4L,0.08833186318993488,66,ON,44.601919372727274,-80.60180030151515,10.137257000388345
348 +T2P,0.08816673351924506,142,AB,51.089312576154924,-114.04637674989436,10.119071572927329
349 +L0R,0.0867470222661411,369,ON,43.18068441943089,-79.74119497777778,9.962845212235605
350 +L1S,0.08565157213439956,77,ON,43.83910035454546,-79.01866184935065,9.842452353187237
351 +L6P,0.08435759394273651,168,ON,43.77936111619048,-79.70181926464286,9.700410534650494
352 +V1P,0.08128629059780718,146,BC,49.820497558150684,-119.1847251269178,9.364004164281292
353 +N2L,0.08047452066525874,340,ON,43.469219171823525,-80.53441638308823,9.275261778071297
354 +L0S,0.07991998062936842,561,ON,43.038250565133694,-79.13247795926917,9.21468106924963
355 +L6T,0.07797343557710923,132,ON,43.712688483560605,-79.71501677265152,9.002296547261523
356 +T3H,0.07320529153184674,333,BC,51.04475090209009,-114.19409437124023,8.483795023389028
357 +L6Y,0.0718266775370714,239,ON,43.65304793025105,-79.75833926945607,8.334340788883843
358 +L6V,0.07126513382407385,126,ON,43.71161605730158,-79.77140255039681,8.273523398321903
359 +L8J,0.07011656216191543,93,ON,43.19060619204301,-79.77367471967742,8.149234888378398
360 +V1L,0.06980931917983586,115,BC,49.52982259582608,-117.24265021756523,8.116011898968178
361 +L3Z,0.06881084911552486,142,ON,44.10803914197183,-79.57151869929577,8.008115172404029
362 +P0B,0.06682479402015448,144,QC,45.18158140625,-79.33690264736111,7.793817978381323
363 +J3L,0.06555426741439745,83,QC,45.450346099156626,-73.29606788987952,7.656950030299869
364 +V2V,0.06221519771608675,287,BC,49.14825194761137,-122.30213873650396,7.298075457682485
365 +L1L,0.0617956377390873,97,ON,44.00525680927835,-79.35818542134021,7.253066922161677
366 +K4M,0.05970054233592118,77,QC,45.231127353246755,-75.68617097350649,7.028596740008886
367 +V1B,0.059368439190817204,169,BC,50.2676479476923,-119.2166205147929,6.993058107987848
368 +V3G,0.059300426982440146,133,BC,49.0617366123704,-122.23524791544733,6.985781521276069
369 +T2K,0.05905650314955598,94,AB,51.08990296297872,-114.03468307115958,6.959688321889268
370 +V9N,0.05752244861494111,211,BC,49.68736416042654,-124.98150034459717,6.795732118030573
371 +L7A,0.05624848061637882,229,ON,43.69588395563319,-79.83145152152838,6.659764400579182
372 +N2K,0.054422422833163654,80,ON,43.5008907105,-80.501320989875,6.465175227248121
373 +L6S,0.052472917728911876,148,ON,43.72892907324324,-79.74147481925677,6.257823007494312
374 +H7V,0.049926192011619186,54,QC,45.54451400981481,-73.73801037277778,5.98755776876867
375 +L6X,0.04860020094965519,163,ON,43.67325457944786,-79.79315870331288,5.84711234975126
376 +V9H,0.048132211807544255,71,BC,49.95499467873239,-125.23089622943664,5.797588639630957
377 +L9S,0.04753589419243558,263,ON,44.35055366034221,-79.55901073551331,5.73451848068145
378 +T2C,0.04708922641472902,63,AB,50.97791365350794,-114.01982215649207,5.687300824372654
379 +L1R,0.0470086689152667,60,ON,43.91527840183333,-78.9355045855,5.678787262613549
380 +H1L,0.04588764040883928,76,QC,45.60282324578947,-73.51671064736843,5.560384708286548
381 +L4P,0.043113937901849156,144,ON,44.23172684027778,-79.46346597333334,5.267997289895088
382 +L6Z,0.04207841308389284,65,ON,43.727775798461536,-79.79614451523078,5.1590460867380505
383 +T2T,0.041962100287413116,178,BC,51.02869754205618,-114.09959106601123,5.146815455315834
384 +J9B,0.04083864281229918,59,QC,45.53487765661017,-75.82994977644067,5.028753810544484
385 +L0A,0.04083552733618678,63,ON,44.14905197777777,-78.49255766507936,5.028426596480595
386 +L8R,0.0404974560976078,63,ON,43.25899366063492,-79.86772430587301,4.992925507501811
387 +J0E,0.03984701601270023,167,QC,45.25886040568862,-72.51332161203594,4.924656105104863
388 +N1S,0.038799957700131685,133,ON,43.35720466518797,-80.33013079112781,4.814851367749973
389 +L1P,0.03796827263266107,54,ON,43.90063765185185,-78.97610719259258,4.727714661189819
390 +N2G,0.03762369435782907,223,ON,43.44972541690583,-80.49608713085202,4.691633982610766
391 +T2G,0.0372610900469591,175,AB,51.04185611505714,-114.04932871784,4.653679226511587
392 +L1H,0.03719996625787301,89,ON,43.90661308831461,-78.85097706157303,4.647282592590707
393 +T2S,0.036524527749601514,83,AB,51.03134312391566,-114.06967831022892,4.576623653712164
394 +K0M,0.03645902537885506,610,QC,44.717258379409834,-78.67093729931148,4.569773861279458
395 +L0K,0.03636484910473301,380,ON,44.67102180942105,-79.49566958026315,4.559926333300446
396 +N9H,0.03435296316249966,52,ON,42.23368632788462,-83.0283619396154,4.349775158372293
397 +J0R,0.033538508498136256,156,QC,45.883205409807694,-74.14659746628205,4.264821597377355
398 +J0P,0.03256545317555936,154,QC,45.349266413636364,-74.25233347571428,4.163415502635859
399 +V2S,0.030062098547178246,472,BC,49.05290787267465,-122.27883282912707,3.9029836469808066
400 +G1K,0.0286929836198444,55,QC,46.81410239781819,-71.21762357163637,3.760825858456296
401 +V2R,0.028425974812614517,483,BC,49.11624082002071,-121.96894404327122,3.73312450252421
402 +L0E,0.028370725275784863,166,ON,44.37025722319277,-79.35119676939759,3.727393453761918
403 +T3L,0.02777163244717242,92,BC,51.120225515065215,-114.23180294525001,3.665269727010778
404 +V9G,0.02759163980239745,118,BC,48.98843013449152,-123.8094584461017,3.646612420080686
405 +J3Y,0.027295974576283397,127,QC,45.4884242543307,-73.40272128346457,3.6159722508230407
406 +N3W,0.02622621774158242,102,ON,43.08584570460785,-79.9505342035294,3.5051876231948054
407 +L6R,0.020171019413476696,152,ON,43.7481342406579,-79.76458317111842,2.880336890903701
408 +M3N,0.018922689775631073,78,ON,43.75969713846154,-79.5147439974359,2.7519884444634712
409 +L1Z,0.01649713362442314,54,ON,43.87696430925926,-79.01385894444445,2.5030597441572544
410 +V9T,0.015562608627774732,217,BC,49.21972360341014,-124.00877634557604,2.407312818509366
411 +L1E,0.015446020557976293,55,ON,43.90557605454545,-78.79400623090909,2.3953740435474824
412 +K9A,0.014852401091860281,170,ON,43.97189674352941,-78.17209838558823,2.3346081939550123
413 +L8P,0.013329542881032,185,ON,43.25269047291892,-79.87207854156757,2.178885697350874
414 +T2E,0.012650109227645246,190,BC,51.062121287763155,-114.0495289422737,2.109485502826147
415 +L3V,0.012626682909646948,256,ON,44.614962160898436,-79.41487704164062,2.107093481566369
416 +L9C,0.012002552255822849,137,ON,43.22866266240876,-79.90474021832117,2.0433851977661233
417 +K1L,0.01111314125960024,77,QC,45.429657666233766,-75.69417856233767,1.9526670377242317
418 +V4T,0.009739903962271293,303,BC,49.83898614834983,-119.62138801613861,1.8127579189823884
419 +J4W,0.008646442671557833,57,QC,45.46804607070175,-73.48594258982456,1.7014904537167919
420 +L9J,0.00540751181167418,86,ON,44.33197742732558,-79.65344772069767,1.3726192408568538
421 +V2T,0.00463040178042235,371,BC,49.061333793978804,-122.3374954819645,1.2938721630854966
422 +L0M,0.004563096644250362,166,ON,44.357367298493976,-80.03980115957832,1.2870547946506994
423 +V9X,0.0031914171996912915,59,BC,49.10567828254237,-123.88313378559322,1.1482166660612192
424 +L9M,0.002749178945983515,151,ON,44.77829628536424,-79.99003007086093,1.1034949449139742
425 +L9A,0.002209680580656375,93,ON,43.230498331182794,-79.87018009010752,1.0489644855318003
426 +J7V,0.002178557723348109,188,QC,45.39879618202127,-74.02428400989362,1.045819601968101
427 +P0A,0.0014548885966199038,228,QC,45.59952052644737,-79.36710141035087,0.9727223142524721
428 +L9R,0.0009750579295401826,150,ON,44.1619079018,-79.8326968886,0.9242841275406422
429 +N3A,-9.505403992517467e-05,65,ON,43.388550998153846,-80.69892163446154,0.8163416086775399
430 +L8N,-0.000755207374424885,113,ON,43.264319636991154,-79.87410375672566,0.7498093277622964
431 +L9X,-0.004508719527408569,75,ON,44.424218324799995,-79.76259478026667,0.37235253153669046
432 +J2W,-0.006581739915656439,57,QC,45.35475680017544,-73.29383549403508,0.16449412012258247
433 +L8S,-0.007488632104560088,97,ON,43.25532786824742,-79.92338233494844,0.07369690066714174
434 +L2N,-0.007859082433593154,143,ON,43.19328054608392,-79.25154262377623,0.03663143260403956
435 +J7W,-0.008225329682921096,71,QC,45.37554612774648,-73.96327079619718,0.0
436 +J8B,-0.008691097404927347,62,QC,45.95257746709677,-74.19567357370968,-0.0465659269059393
437 +V4Z,-0.010172165649341425,56,BC,49.13533029107143,-121.83477772375,-0.19449421104885678
438 +L1G,-0.010264348917057227,113,ON,43.91715984070797,-78.86290392743362,-0.20369418466018585
439 +L2T,-0.011581796416454055,70,ON,43.13641252942857,-79.23093479585714,-0.33508400960339246
440 +V0E,-0.011837760146117047,676,BC,50.900376668284025,-119.29177117681952,-0.36059134860076947
441 +L4N,-0.013397037309152012,442,ON,44.36620336079186,-79.69138822572398,-0.5158357370799838
442 +N2Z,-0.013515536035589632,93,ON,44.14918018989247,-81.66158505344086,-0.5276237853977017
443 +N3L,-0.016377741204855932,138,ON,43.19271493210145,-80.3778949355797,-0.8119270735383322
444 +V1H,-0.016661019188389355,246,BC,50.2300024850813,-119.36592375154471,-0.8400208914595919
445 +P1L,-0.017289309360638015,136,QC,45.04587141117647,-79.30217837845588,-0.9023025642835969
446 +J7K,-0.018700672483773155,97,QC,45.73135646350516,-73.6164832056701,-1.042066747824455
447 +V9R,-0.019734738892150903,179,BC,49.1598357326257,-123.9549141860894,-1.1443429331456145
448 +N0H,-0.02080296436796066,648,ON,44.66405022523148,-81.12221700833334,-1.249886682155199
449 +K1G,-0.020874868238535817,76,QC,45.39126694078947,-75.63062015657894,-1.256986942251337
450 +T3C,-0.021026369135230195,133,BC,51.043106818428576,-114.11852290539849,-1.2719454641285433
451 +L8G,-0.02192952095070247,114,ON,43.21632603912281,-79.76009607842104,-1.3610716325320404
452 +N1R,-0.0233395834735858,200,ON,43.36199487845,-80.3075270712,-1.5000606740720457
453 +N2P,-0.024350385431881966,131,ON,43.38935885572519,-80.42833258458015,-1.5995743028763831
454 +H1E,-0.024351820115961372,61,QC,45.639319499016395,-73.59184662836066,-1.5997154762992682
455 +N2V,-0.0257843907318185,83,ON,43.47464735530121,-80.58455511361446,-1.7405799092852892
456 +L8W,-0.026884805956499513,102,ON,43.202362101176476,-79.84451420960784,-1.8486466011000124
457 +V9S,-0.029977265718908866,104,BC,49.17739737269231,-123.9608011451923,-2.1517068697474384
458 +K7G,-0.03193895518778473,84,ON,44.320400526190475,-76.22708617857143,-2.3434666878261123
459 +N2J,-0.0319916622301145,138,ON,43.471584916666664,-80.51553577275362,-2.3486137392170536
460 +N0E,-0.03349852733127469,256,ON,42.82389647394531,-80.392183576875,-2.495650395228266
461 +T3A,-0.03845778191598226,155,BC,51.112874849587094,-114.14530373469677,-2.978002246631406
462 +N2H,-0.038558375156289,147,ON,43.45354730836734,-80.4863982244898,-2.987761512900111
463 +V1X,-0.03882885488326346,249,BC,49.88835567522089,-119.40594159975903,-3.0139978083263297
464 +V2A,-0.0395866104208234,375,BC,49.478745628186665,-119.59137499122667,-3.0874616512207798
465 +L4R,-0.03963340896244126,93,ON,44.741758260107524,-79.87705481580645,-3.091996910557393
466 +L1K,-0.03970559794620243,107,ON,43.93721370897197,-78.84509529841122,-3.0989923483189408
467 +L8V,-0.040229621410942086,80,ON,43.230778243375,-79.84859842224999,-3.1497574478719814
468 +K2B,-0.04103800807244324,83,QC,45.36093364722892,-75.7876555366265,-3.2280182553559467
469 +L1J,-0.04132970404618388,92,ON,43.8850832026087,-78.87201904434782,-3.256242136205434
470 +L2H,-0.04239947640819587,180,ON,43.09176563638889,-79.13382590288889,-3.3596805968974075
471 +L9V,-0.04240910280536864,98,ON,44.11246399418367,-80.18414234969387,-3.3606108905171905
472 +T1S,-0.04430899086650147,192,AB,50.73949727529166,-113.97656087067189,-3.5440406089801146
473 +L2S,-0.04479174130220248,99,ON,43.145723185858586,-79.26472465969697,-3.590593527777086
474 +V9W,-0.045098875872239035,199,BC,49.99335749145729,-125.23855869517587,-3.620199642617994
475 +N5A,-0.04523562839745207,152,ON,43.3782347431579,-80.97541295197368,-3.633378922525954
476 +L1A,-0.04528294122019791,69,ON,43.95316646289855,-78.33302727217391,-3.6379381915308207
477 +K2C,-0.046741167879725966,90,QC,45.356755594444444,-75.73311679333334,-3.778353515460753
478 +N1M,-0.04688650178587422,112,ON,43.70785489848214,-80.38943517116071,-3.7923367670554597
479 +L4M,-0.0474256895358487,224,ON,44.4154272565625,-79.66992436656251,-3.844196778126585
480 +V0H,-0.04800341774736505,836,BC,49.31234457748804,-119.40439778284689,-3.8997326544829347
481 +N2A,-0.0483225246562832,164,ON,43.44052803140244,-80.42939044335367,-3.9303940213545774
482 +N6K,-0.04858183627149308,164,ON,42.955415254268296,-81.33900317396342,-3.955302756351753
483 +J6A,-0.04940935416309681,57,QC,45.7380557854386,-73.45582268017543,-4.0347485857582965
484 +N2R,-0.05154981699842791,95,ON,43.38452937810526,-80.47648910189474,-4.239938960366818
485 +K1K,-0.05183412418844671,116,QC,45.441081695689654,-75.64392926293102,-4.2671603644332095
486 +T3M,-0.052753196283341824,428,BC,50.886853350981305,-113.94985476746496,-4.355105325836828
487 +K7H,-0.05288933899213886,91,ON,44.89014917362638,-76.25615456263736,-4.368125794539324
488 +N3H,-0.053126299814900454,75,ON,43.397092169333334,-80.36282241453333,-4.3907841174598445
489 +XON,-0.0549546953803615,707,ON,43.985401740959034,-81.44498062762437,-4.565435868897271
490 +V2P,-0.05622076132670648,354,BC,49.169235317655364,-121.94796330166668,-4.686185865788984
491 +J0L,-0.05638065940649639,140,QC,45.509503744928566,-73.37814894292858,-4.701425143248416
492 +K0L,-0.05848705004729609,625,QC,44.63665311275176,-78.0392507290915,-4.901949903527036
493 +V2H,-0.05999652469180887,50,BC,50.712199501200004,-120.219862567,-5.045389712277315
494 +J7N,-0.060379514860688516,60,QC,45.68818441733333,-74.04742859633333,-5.081749431355387
495 +N2E,-0.061077934152372663,165,ON,43.412239487878786,-80.50482639951515,-5.148019024010663
496 +N1A,-0.062437093003263805,109,QC,42.91547041688074,-79.59687777100918,-5.276850362519081
497 +N2C,-0.06250616432789563,53,ON,43.423936110943394,-80.45844726301887,-5.283392789988173
498 +T4C,-0.06363089569984633,267,BC,51.19104134085768,-114.48006859438202,-5.389863642783855
499 +V9L,-0.06405952040056105,209,BC,48.79673454985646,-123.69628812631579,-5.430407194559949
500 +N3T,-0.06682005040503562,219,ON,43.1281793856621,-80.28706193716896,-5.691109389337557
501 +N6A,-0.0682769715025601,69,ON,42.99502053405797,-81.25506155231884,-5.8284099594173355
502 +L2J,-0.0708641752501119,75,ON,43.12737035826667,-79.1056206624,-6.071736147143058
503 +N0A,-0.07569091285087738,342,ON,42.852358558538015,-80.01172909736842,-6.5240108463398006
504 +K2G,-0.07593171378540493,118,QC,45.32112633220339,-75.73968497627119,-6.546517241994588
505 +N0J,-0.07761426262484461,159,ON,42.96986504591195,-80.67774994188679,-6.703625083078846
506 +T2W,-0.07914493046949896,106,BC,50.946770699132074,-114.09871725133962,-6.846321605836703
507 +T2V,-0.08185370829860666,126,BC,50.98247552287301,-114.08486332539682,-7.098312776441007
508 +J0N,-0.08390565164332968,69,QC,45.5494614284058,-73.98656197521738,-7.2887463290046135
509 +T2R,-0.08404290271588931,175,BC,51.04224406318286,-114.07805922938859,-7.301470174808589
510 +N6G,-0.08734020578304502,345,ON,43.01455851704348,-81.30882160739131,-7.606621956097081
511 +J0J,-0.08753108228422145,59,QC,45.12998289186441,-73.20860397288136,-7.624255997814333
512 +N0R,-0.08827930292212856,62,ON,42.1817883416129,-82.8326099501613,-7.693347584819832
513 +N5L,-0.088896683042962,61,ON,42.67305212491803,-81.2187676752459,-7.750318288941971
514 +V1S,-0.090262856678915,123,BC,50.65291599463415,-120.44123575430895,-7.876261322406042
515 +T3G,-0.09122739476516706,197,BC,51.13917428569035,-114.2030954104467,-7.965075337872706
516 +T7Y,-0.09130909019328741,50,AB,53.497357249,-114.0056010524,-7.972593863326239
517 +H1A,-0.09233560417991718,78,QC,45.6763038924359,-73.49814576371796,-8.067012813401353
518 +J5Z,-0.0942685800224906,62,QC,45.75228943532258,-73.47918886193548,-8.24454541837265
519 +J5Y,-0.09516026121798499,62,QC,45.77274464854839,-73.4220271016129,-8.326325565478875
520 +K9J,-0.09594314453490069,162,ON,44.29701072901235,-78.34100930987654,-8.398067269438203
521 +V0X,-0.09711908607915128,258,BC,49.343928061550386,-120.84517905930232,-8.505722477148304
522 +L8K,-0.0985857962339431,160,ON,43.224434025250005,-79.796427981625,-8.639819698178908
523 +K2S,-0.09876299077538672,141,QC,45.26353293262411,-75.91119835957446,-8.656006789259251
524 +K1V,-0.10148754568995098,144,QC,45.344846499305554,-75.67010186944444,-8.904539790230404
525 +J0T,-0.1018281286608586,353,QC,46.145980231983,-74.43938748019829,-8.935560069915482
526 +N3R,-0.10276858990216038,133,ON,43.165602426315786,-80.26691915759399,-9.021162386990522
527 +K2K,-0.10309105789120195,57,QC,45.34002822719298,-75.90601469,-9.050495420064653
528 +N2T,-0.10322301245004753,55,ON,43.45487761618182,-80.56768615909091,-9.062495830046903
529 +L8H,-0.10770849264017616,209,ON,43.24916308555024,-79.79444441272727,-9.46948075975903
530 +N6P,-0.10827049024535189,142,ON,42.922160668309864,-81.30056109366197,-9.520344400806401
531 +V2C,-0.10827501120853783,171,BC,50.672322440175435,-120.27881909380116,-9.520753455073772
532 +L2M,-0.10925965198576319,130,ON,43.19073289946154,-79.21866114753847,-9.609799164501986
533 +L9Z,-0.11068196616223573,268,ON,44.495073397276116,-80.03551005559702,-9.738271043219349
534 +N2N,-0.11150704953262142,64,ON,43.42809295953125,-80.54164111375,-9.812713779808691
535 +T2Y,-0.11195177553369186,242,BC,50.91409439144628,-114.10573004583472,-9.852813493603197
536 +K0G,-0.11265871214295027,251,QC,44.858354955776896,-76.0508847812749,-9.91651931932288
537 +T4S,-0.11307276572255047,141,BC,52.30142235089362,-114.07134656192198,-9.953810986054734
538 +K0A,-0.11358750074723141,634,QC,45.309589969716086,-75.6305609522082,-10.000148986460244
539 +T1V,-0.11567732375597548,57,AB,50.58292484452632,-113.86776337435089,-10.18803635184129
540 +N1T,-0.11596089306903501,59,ON,43.3885720081356,-80.28538220050848,-10.213500658058972
541 +T3S,-0.11611685446080638,68,AB,50.89733853780882,-113.90858358629411,-10.227502793533972
542 +T3R,-0.11612877491723869,212,BC,51.176205910367926,-114.15519126550943,-10.228572916297551
543 +V1E,-0.11763132872347234,178,BC,50.69437032151685,-119.27548974921349,-10.363358029452463
544 +N4X,-0.11788027820783495,56,ON,43.26144080285714,-81.14235964982143,-10.38567024782816
545 +T2X,-0.12128795759855832,308,AB,50.873968733237014,-114.03810157447401,-10.690527429663144
546 +N6H,-0.12186404754243056,108,ON,42.97997429722222,-81.30905698805556,-10.74196290155186
547 +V0B,-0.12285649699226737,373,BC,49.539457891509386,-115.97048450114745,-10.830503048286422
548 +V0G,-0.12475541926776267,219,BC,49.61504372155251,-117.59178397415526,-10.99966832565319
549 +N2M,-0.12490864725357081,125,ON,43.4365857704,-80.51066402056,-11.01330462245408
550 +V4Y,-0.12537194836251056,50,BC,50.5001484804,-119.1672021784,-11.054522708173685
551 +T6G,-0.12617946991318896,85,AB,53.521995021882354,-113.52217228999999,-11.1263191054517
552 +J8V,-0.12752606267229852,145,QC,45.53350748572414,-75.72872859531034,-11.245915218917425
553 +N7A,-0.12997229642063793,81,ON,43.778789525061725,-81.71038210395061,-11.462763117951557
554 +N0C,-0.1308217741937545,136,QC,44.25985965220588,-80.48662909014706,-11.53794159703171
555 +J9J,-0.1316133210470902,205,QC,45.42411272809756,-75.8202948869756,-11.607935755517683
556 +T3P,-0.13246207964041717,253,BC,51.17833795156522,-114.09156757443874,-11.682927450202495
557 +J8X,-0.13288305645214143,56,QC,45.43907190696429,-75.70541064946428,-11.720099065082412
558 +N0M,-0.13462309195124908,438,ON,43.25042025431507,-81.55762272180365,-11.873575660481016
559 +N0N,-0.1367757795048745,99,ON,43.32343934687965,-84.15408674902397,-12.06308027201154
560 +S7T,-0.14009209519021631,51,SK,52.07849445098039,-106.62304235294118,-12.354223829421251
561 +V1A,-0.14050064817571695,60,BC,49.66129267016667,-116.11226016966665,-12.390024459217198
562 +K7K,-0.14089203426416735,99,ON,44.24960937777777,-76.48077874444445,-12.42430707554616
563 +T1Y,-0.14117601860483928,117,AB,51.082419657683765,-113.95306329388035,-12.449173669931369
564 +L2P,-0.14237047980355064,90,ON,43.155465055,-79.21607653588889,-12.553687303731476
565 +L2G,-0.1464219147307054,154,ON,43.071450003831174,-79.08829508045454,-12.907253640114524
566 +K1J,-0.14669215294009516,93,QC,45.44147644408602,-75.60722332365592,-12.930786248093519
567 +N5X,-0.14712415481134583,134,ON,43.03566094470149,-81.25201826664178,-12.968392187859635
568 +T1X,-0.14822057726077217,280,AB,51.033251305803574,-113.83611824495357,-13.063763303404352
569 +K9H,-0.14831662528484538,95,ON,44.32140996105263,-78.32272694842105,-13.072112956169168
570 +T2B,-0.1501640046614046,70,BC,51.06845201591428,-114.00161875937142,-13.232553499037358
571 +K1C,-0.1517953703262385,107,QC,45.466917899252344,-75.53161265093458,-13.373987535401788
572 +N0L,-0.1519566345316969,284,ON,42.81975386362676,-81.43166366359155,-13.387956084130192
573 +K4A,-0.15326029515426967,154,QC,45.46647758246753,-75.47618535584415,-13.500795227268924
574 +K7C,-0.15328406300675723,113,QC,45.12565942300885,-76.13882549911504,-13.502851103176283
575 +T0L,-0.15540114687884804,194,BC,50.39077414182474,-113.75221648034535,-13.68577911678961
576 +J1N,-0.156123041157075,70,QC,45.35772506128572,-71.993409861,-13.748066373862589
577 +V2E,-0.15704440296693906,96,BC,50.65609850531251,-120.32967717645833,-13.827499012813405
578 +XNS,-0.15978993253493065,257,NS,44.670621341322956,-63.57441999957199,-14.063763677997198
579 +K0K,-0.1626839250699075,918,ON,44.17489644401961,-77.48949551738562,-14.312102985022634
580 +T4A,-0.16392494889840536,92,AB,51.26673251702174,-113.98727289956523,-14.418377748635258
581 +K0H,-0.16479961982272956,355,ON,44.54264030141274,-76.7025487660702,-14.493200777740734
582 +N4S,-0.16517027579511995,136,ON,43.12736227455883,-80.75056849772058,-14.524888510565948
583 +K2H,-0.16538824113597653,75,QC,45.33028508133333,-75.81309203333333,-14.54351709211018
584 +J8Z,-0.16578365560663502,58,QC,45.470742276034485,-75.76220811758621,-14.577301142272203
585 +T2A,-0.16594394219441927,173,AB,51.048503691647404,-113.94861355354335,-14.590992157919025
586 +R4A,-0.16642887420663494,64,MB,49.97712428125,-97.082911921875,-14.632399679225472
587 +J8R,-0.16868713384193915,122,QC,45.508486319344264,-75.6364396490164,-14.824964372819538
588 +V0A,-0.16908899055428292,210,BC,50.70924912738096,-116.29329925642858,-14.859185656123708
589 +T1P,-0.16912780754721587,109,QC,50.99779113333945,-113.0543200177156,-14.862490502369885
590 +T5J,-0.16945431181497783,132,AB,53.50722204999243,-113.51211324997728,-14.890283725017673
591 +T4G,-0.17030940832869151,63,BC,52.022418880936506,-114.12682222425397,-14.9630296398659
592 +K4K,-0.17139965318305247,128,QC,45.54606594609375,-75.27635540078126,-15.05569023868265
593 +T3K,-0.17263263981218813,281,BC,51.15350566254804,-114.07426258329538,-15.160360894819258
594 +T4H,-0.17372210310653619,50,BC,51.81011986958001,-114.09135746152,-15.252740236441841
595 +B4B,-0.1738380927829539,62,NS,44.727949188870966,-63.73745066274193,-15.262569473623067
596 +N5H,-0.17581523665244586,69,ON,42.74981467246376,-80.97083539362319,-15.429942050549617
597 +K2M,-0.17694816630525512,50,QC,45.284702838,-75.85338759999999,-15.525699723344532
598 +K7M,-0.17723775808452,162,ON,44.23766259814815,-76.55549595740742,-15.550159244454754
599 +S7V,-0.17775404893179125,134,SK,52.111473000000004,-106.55478086567165,-15.593748670911145
600 +L3C,-0.17873123229471505,180,ON,43.00941052244444,-79.2677785815,-15.676188769330302
601 +J9H,-0.17974711188244058,146,QC,45.398076996712334,-75.82984558938355,-15.761808111084608
602 +R3X,-0.17977844397162018,72,MB,49.827297,-97.05047131944444,-15.764447428277329
603 +B3Z,-0.1808311159429399,69,NS,44.673411889130435,-63.87824647086956,-15.853073178352705
604 +N0K,-0.18168849231320017,99,ON,43.52132209191919,-81.13522282737374,-15.925187845916057
605 +J9A,-0.18170030969927384,109,QC,45.43871744880734,-75.76881452467889,-15.926181384559824
606 +K0J,-0.18179348175870785,276,QC,45.61109034347826,-77.29700143115943,-15.934014350472259
607 +B4A,-0.18214409459194542,64,NS,44.719498523125,-63.67272478703125,-15.963483797394717
608 +K2J,-0.1847770625662308,219,QC,45.26246168082192,-75.74210132922374,-16.184458216283538
609 +V8A,-0.1861746118360466,125,BC,49.8330482188,-124.51024824992,-16.301512751710302
610 +T4B,-0.1891003404398586,345,AB,51.281747189539125,-114.02892400357682,-16.546033934216663
611 +T3J,-0.19052556008056232,362,BC,51.1217798170442,-113.94565146154143,-16.66488944802311
612 +T2Z,-0.19090669948749264,231,BC,50.92037550117316,-113.95398472974892,-16.696645690473233
613 +N4K,-0.19138524597858353,126,ON,44.573266249999996,-80.94166637468254,-16.73650068138055
614 +S7N,-0.19181803386701762,64,SK,52.130339984375,-106.61524309375,-16.77252831870939
615 +L2V,-0.19285570576521108,132,ON,43.10173325136364,-79.2118617298485,-16.85884633459572
616 +J8N,-0.1934646778167024,135,QC,45.664694764222226,-75.67041990125927,-16.909461560313577
617 +N6M,-0.1937037574516192,88,ON,42.959287870454546,-81.16822283977272,-16.929324441408976
618 +L3K,-0.1944378403185264,128,ON,42.88885752054688,-79.255781013125,-16.990282824089363
619 +N5P,-0.19663059361910282,90,ON,42.79123807211111,-81.19585381155555,-17.172103238897517
620 +K1T,-0.19858291921266213,105,QC,45.34646260666666,-75.6276648504762,-17.333652511901654
621 +L8M,-0.19900985778550895,59,ON,43.249179032033894,-79.83511479627118,-17.368938431324654
622 +V9Y,-0.19923795211500234,182,BC,49.25749696203297,-124.81564689582419,-17.387783958547832
623 +N3S,-0.19931220640256395,167,ON,43.14179010778443,-80.23639869502993,-17.39391804205006
624 +N4W,-0.19978498241104015,87,ON,43.735207721494255,-80.95589748678161,-17.432962985270528
625 +N3Y,-0.19991306767467662,166,ON,42.83041825006024,-80.31463582951808,-17.443537928712573
626 +K9V,-0.2018941735437021,157,ON,44.361563230573246,-78.73968830770701,-17.606929119185246
627 +R3Y,-0.20247702547435775,160,MB,49.791164625,-97.19153735,-17.65493808720181
628 +G0A,-0.20705457364226715,251,QC,47.04669310326693,-71.08397035792828,-18.0310151623426
629 +J0B,-0.20714009430932154,167,QC,45.36384582844311,-71.83504599047905,-18.038024904860485
630 +R2N,-0.20919621774099556,51,MB,49.81483982352941,-97.09690437254902,-18.20637570803372
631 +B2T,-0.21009313325171594,73,NS,44.86450270068493,-63.59958094958904,-18.279704788428575
632 +P0H,-0.2117010953544831,170,QC,46.24868565235294,-79.52294354647059,-18.41100233712487
633 +K8V,-0.21177190685521213,158,ON,44.10843447949367,-77.59376858829114,-18.41677957194261
634 +L2R,-0.2123738132917358,112,ON,43.16434000366071,-79.24555078178571,-18.465870261947348
635 +K7P,-0.213542436009876,111,ON,44.2642552018018,-76.5895731882883,-18.56109724521755
636 +V1T,-0.21355724287407588,206,BC,50.26094373674757,-119.2783588988835,-18.562303091063814
637 +N4G,-0.2146568318086828,153,ON,42.86826820352941,-80.73447648411765,-18.651801866495475
638 +B3M,-0.21472669848789908,62,NS,44.67639700096774,-63.6608700383871,-18.657485196419287
639 +T5R,-0.21641357911779985,90,AB,53.51974478922222,-113.58348787433333,-18.79458464131941
640 +N9A,-0.22076259870338766,59,ON,42.31471389,-83.03816794762712,-19.146981736799496
641 +J8T,-0.22261784280431318,138,QC,45.48932907355072,-75.6714575634058,-19.29684476274206
642 +L2E,-0.22567097146419107,156,ON,43.10226510269231,-79.09245250358974,-19.542866120401257
643 +N6C,-0.22688921600657488,83,ON,42.96059596638554,-81.24031825506025,-19.640822904871914
644 +V2B,-0.2271804633274,204,BC,50.70316767102941,-120.36667059338237,-19.664223892001765
645 +B4E,-0.22723191990803915,60,NS,44.79974237333333,-63.74819542533333,-19.668357589989384
646 +N4T,-0.2280335834782312,77,ON,43.15392157220779,-80.74144718467532,-19.73273073499303
647 +N5C,-0.22813306084498983,65,ON,43.03590883015384,-80.88003193200001,-19.740715114437315
648 +L2A,-0.22911778975670583,138,ON,42.909871753550725,-78.94049532369564,-19.819709852113377
649 +N5V,-0.22982645225535953,122,ON,43.0037213902459,-81.16917359540983,-19.876510488254873
650 +N0G,-0.23086869306415758,533,ON,43.97435579108818,-80.96882121232646,-19.959974956174655
651 +T4L,-0.2328075976933469,68,AB,52.47947012829412,-113.75273277383823,-20.115014579160505
652 +N6E,-0.23436411948452082,112,ON,42.90485753526786,-81.30831719205356,-20.23926057886779
653 +T6C,-0.23472569917123787,77,AB,53.52104868753247,-113.45856809337663,-20.268095228714024
654 +T3N,-0.23669349012295382,254,BC,51.16187492814961,-113.95376577783071,-20.4248366817017
655 +J0H,-0.23790355294520915,63,QC,45.62615276698413,-72.96024870301588,-20.52106939285263
656 +K8N,-0.24209394077049678,166,ON,44.176505319277105,-77.36605229819277,-20.853420110513454
657 +N4B,-0.24487184270235224,57,ON,42.83890541912281,-80.49430862491228,-21.072976453505298
658 +N4N,-0.2497676561987362,67,ON,44.153042675522386,-81.01724840850746,-21.458444081866134
659 +T0M,-0.25085512172380103,262,BC,51.753515652793894,-113.99252183890076,-21.54380889215537
660 +J8P,-0.2513492023982474,142,QC,45.495513789507044,-75.61699411866196,-21.58256300535486
661 +T1B,-0.25411808560304,73,AB,49.99926503386301,-110.6613434139726,-21.799391404825307
662 +N5W,-0.2557646740447551,101,ON,42.989466964950495,-81.1944702339604,-21.928049670397943
663 +T8W,-0.2573184461190654,57,AB,55.1382759208772,-118.81776772747368,-22.049261494447492
664 +J8L,-0.258095507806502,132,QC,45.601648478030306,-75.42771841962121,-22.10981049864511
665 +K0B,-0.26188872920975015,104,QC,45.540244885576925,-74.78767181057692,-22.4047055778096
666 +T5N,-0.2666862649697249,113,AB,53.54539032336283,-113.54715079973451,-22.776080223726648
667 +J8M,-0.26799487220772295,70,QC,45.546715387285715,-75.47510518428571,-22.877069911762426
668 +S7W,-0.26866181223228436,85,SK,52.16807815294118,-106.55190171764707,-22.92848913197575
669 +L3B,-0.2703390803116194,149,ON,42.9907458352349,-79.24110785503356,-23.057650367691927
670 +G1C,-0.27166261728128205,51,QC,46.87777760215686,-71.19809814490196,-23.159419049800334
671 +K7A,-0.27204212756158713,97,ON,44.916652739175255,-76.02354016907216,-23.188575307315872
672 +K0E,-0.2750318792409312,189,ON,44.67720233730159,-75.70744528502645,-23.417879441268763
673 +S7K,-0.2768231381351945,101,SK,52.13704782178218,-106.65168176237624,-23.554935058168258
674 +S4V,-0.27721529956969293,105,SK,50.426380095238095,-104.52712035238096,-23.584907986998658
675 +R3W,-0.2772474642381075,61,MB,49.910494032786886,-97.04974427868852,-23.58736581356733
676 +N5Y,-0.2775971568875551,129,ON,43.01132080697674,-81.2252868851938,-23.614082078554254
677 +N6J,-0.27880819708729,85,ON,42.95495317964706,-81.27103536564705,-23.70653250396083
678 +K7S,-0.278851767693477,81,QC,45.440441574691356,-76.38358890851852,-23.709856584171117
679 +G1B,-0.2790641293968378,80,QC,46.913393748375,-71.211540741,-23.7260559688512
680 +T8N,-0.28003290578677476,197,AB,53.644245822131985,-113.62609420614214,-23.799912583947112
681 +N0P,-0.282175402417035,77,ON,42.417148973896104,-82.20011915571429,-23.962996248976687
682 +N7G,-0.28551267208455927,91,ON,42.95676877362637,-81.62438841868132,-24.216329279762782
683 +J9P,-0.2884441482744097,61,QC,48.0283209347541,-77.73347803672131,-24.438161998531115
684 +T1J,-0.29349386623617213,123,AB,49.68018809100813,-112.87858156254472,-24.818766188431386
685 +R2M,-0.29366321536753154,55,MB,49.84438450909091,-97.1110911090909,-24.831496987066636
686 +T1H,-0.29367455864565956,76,AB,49.72202186397368,-112.82291102501316,-24.832349639466834
687 +T8X,-0.29439609172001274,110,BC,55.18361406446364,-118.76795371426364,-24.886566023514114
688 +V1N,-0.2944451943275077,99,BC,49.3180719179798,-117.70564845454545,-24.890254198430007
689 +K7R,-0.2958808224486256,93,ON,44.23564724236559,-76.93827796591398,-24.99800649705104
690 +R3T,-0.2964426301544287,69,MB,49.80754247826087,-97.15994439130435,-25.040131360807084
691 +N5R,-0.2967466157938104,163,ON,42.7606403997546,-81.17169572,-25.062914621335874
692 +T8A,-0.29799140647826583,74,AB,53.52932092121621,-113.29140752783783,-25.156137573566784
693 +J0S,-0.29883706731399146,94,QC,45.16434777244681,-74.06699474765956,-25.219403342353463
694 +T1K,-0.29899595951082714,130,AB,49.66959209143846,-112.83947596396922,-25.231284451704305
695 +B3T,-0.2990777366748986,75,NS,44.62445100986667,-63.699295172666666,-25.23739857522186
696 +B0J,-0.2998075615959705,243,NS,44.55937870386832,-63.871530113086415,-25.29194227880771
697 +V0P,-0.30011656196298014,74,BC,50.09331618310811,-125.73371992756758,-25.31502352982097
698 +T0K,-0.3018875503244712,212,BC,49.580316502976416,-113.1784907588302,-25.44717270206549
699 +XMB,-0.3041727531107709,313,MB,49.992634025559106,-97.55886350159744,-25.617346515840435
700 +R3M,-0.30475312108665564,56,MB,49.868542375,-97.1621845,-25.660503301264516
701 +L8L,-0.3147417093361539,192,ON,43.25814974713541,-79.84467488057292,-26.39935374500069
702 +XAB,-0.317357322195928,165,AB,53.32925624539394,-112.85180036555758,-26.591612994339776
703 +K0C,-0.3178116596056092,264,QC,45.136660081439395,-74.91270679659091,-26.6249575953174
704 +J0V,-0.3194414271532626,193,QC,45.80604833362694,-74.96202015310881,-26.744444463878025
705 +N5Z,-0.3214614765598045,108,ON,42.969390956018515,-81.20588223074074,-26.892274942659455
706 +K7V,-0.3218423006385396,55,QC,45.466312472727274,-76.69068969636363,-26.92011082407947
707 +T4J,-0.3240884021948401,57,AB,52.6656679124386,-113.6356559595614,-27.084071471827333
708 +R2V,-0.324550052640084,112,MB,49.9582585625,-97.11326158928571,-27.11772537393059
709 +V1C,-0.32619489500365334,175,BC,49.5154496476,-115.76506632982857,-27.237506689092317
710 +T4R,-0.3274938034704268,113,AB,52.24614668221239,-113.77067537485841,-27.331957153184206
711 +J0K,-0.329815242094497,252,QC,46.155021434563494,-73.61839989380952,-27.500455899164823
712 +V8G,-0.3303484037344929,71,BC,54.51653568943662,-128.57427450760562,-27.53909957241907
713 +R2P,-0.33783862752330873,80,MB,49.9607538625,-97.16705175,-28.079820344741957
714 +K8P,-0.3421340962459447,109,ON,44.16714637706422,-77.4026878385321,-28.38808867450372
715 +V1K,-0.342356238932824,82,BC,50.105113010243905,-120.77938258109755,-28.4039949700991
716 +T4P,-0.3425309716103768,118,AB,52.28910296960169,-113.79569321624575,-28.416504038856694
717 +R2C,-0.3425669755305209,54,MB,49.89991798148148,-96.99823859259259,-28.419081278933255
718 +R2G,-0.3435538215377228,52,MB,49.93583401923077,-97.06944544230768,-28.489685779150477
719 +T6H,-0.34406732000565654,100,AB,53.492754182549994,-113.52884051841,-28.526396789613873
720 +T0C,-0.3447305197071985,276,BC,52.80252767751812,-113.75659845791667,-28.5737823471505
721 +B0N,-0.350980717098438,158,NS,45.046690522658224,-63.714486888797474,-29.01881807703689
722 +V0K,-0.3530732787697957,379,BC,51.30321830622692,-121.2660775001583,-29.16719527935031
723 +J0W,-0.3550086055775147,78,QC,46.457720865384616,-75.4674183874359,-29.304147338949903
724 +T6E,-0.35595121305694877,141,AB,53.51888027510638,-113.4976996296454,-29.370754381353258
725 +P1B,-0.3594989434988532,58,QC,46.327072705,-79.45718005120689,-29.620883947632592
726 +K6A,-0.365389731899887,51,QC,45.57832674333333,-74.61039429431372,-30.03425369591499
727 +J0X,-0.3725982625634802,526,QC,45.86524752268061,-76.06801666218631,-30.536790471566334
728 +R0E,-0.3729770472956287,197,MB,50.286459715736044,-96.24152891878173,-30.56309709219408
729 +K6V,-0.37316851255752137,172,ON,44.60570267383721,-75.70346338604651,-30.57639057433371
730 +T5S,-0.3733593181187978,94,AB,53.56806994067021,-113.68405186848936,-30.58963572143196
731 +T8H,-0.37485912975129254,91,AB,53.55821312362637,-113.27576578582418,-30.69366016515759
732 +XQC,-0.37640418237770723,3512,QC,46.461070644114464,-70.21826299513383,-30.8006594265161
733 +T6M,-0.3901291389507512,324,AB,53.46811515964815,-113.66421756104629,-31.743929393819215
734 +T6W,-0.39249630905556177,748,BC,53.41624393383289,-113.60160719538904,-31.905312038185528
735 +T4X,-0.3928055492240649,184,AB,53.34517286553804,-113.43271852319022,-31.926366395370753
736 +T5P,-0.3974325879582188,71,AB,53.54041232887324,-113.59272009281689,-32.240618146657354
737 +R3L,-0.4002708249351153,56,MB,49.873883178571425,-97.14393655357142,-32.432662666916556
738 +T7X,-0.400313523824951,238,AB,53.55860306415967,-113.89861515407563,-32.43554765561649
739 +T1R,-0.40165172101543917,51,AB,50.56000350454902,-111.89459957015686,-32.52590174664161
740 +S7H,-0.401836957914107,71,SK,52.11500907042254,-106.61225757746479,-32.53839928180441
741 +V2K,-0.40374790593220133,96,BC,53.888187045,-122.78422279395834,-32.66719179690071
742 +T8L,-0.4058106855753759,135,AB,53.68476113185185,-113.22869478911112,-32.80594138886396
743 +XSK,-0.4062494392897253,122,SK,51.940120991803276,-105.97954095901639,-32.835416565017454
744 +T8V,-0.4086098936759509,82,BC,55.177866820402436,-118.79659785619512,-32.993768535758896
745 +B4N,-0.41454096766221593,53,QC,45.07236364735849,-64.49812433264151,-33.39001121820824
746 +T6R,-0.41910738711478973,202,AB,53.44882881371287,-113.57414020029702,-33.69348694065177
747 +T7Z,-0.42111916395666266,83,AB,53.525670301807224,-114.00905485891566,-33.82674675863743
748 +K6H,-0.42138827653726113,143,QC,45.01901706083916,-74.72181036643357,-33.84455241761293
749 +G0X,-0.4220520679842744,51,QC,46.6990780672549,-72.46975772039215,-33.88845126643937
750 +T1A,-0.4251222404213699,68,AB,50.05054797214706,-110.71984241275,-34.09111385739371
751 +T4V,-0.4261806635243517,88,AB,53.008270802147734,-112.84362754672726,-34.160836440673414
752 +K8A,-0.4310811973782828,105,QC,45.8141999832381,-77.12668433685715,-34.48269420904156
753 +T4N,-0.4322098077066222,87,BC,52.249740075574714,-113.81555739891954,-34.55659600603208
754 +T5L,-0.433551647295934,69,AB,53.57890355217391,-113.5562797073913,-34.64435166619377
755 +T9V,-0.4349800651638463,82,AB,53.26814715106097,-110.03585099459755,-34.737640198677454
756 +T6J,-0.4394078070204907,134,AB,53.457298902835824,-113.51917695604477,-35.02596629302486
757 +T8R,-0.44183057809441284,64,AB,53.7854173490625,-113.702238535,-35.183192963423934
758 +T6X,-0.4429622650587507,353,AB,53.419388071558075,-113.4506835627762,-35.25650380872904
759 +T5E,-0.44404826205041653,99,AB,53.599494127979796,-113.49768972818181,-35.326776885740976
760 +R5G,-0.44827258863845126,74,MB,49.528114445945945,-96.70379945945946,-35.59940146862554
761 +S7L,-0.45054605807059706,87,SK,52.141231839080454,-106.70835494252873,-35.74564795434952
762 +K6J,-0.45121572075897387,54,QC,45.027415705925925,-74.77139443925927,-35.78866229232425
763 +T5W,-0.452210026195756,78,AB,53.56880679628205,-113.42045126602564,-35.85247624397307
764 +T0J,-0.4571317434185035,180,AB,51.10708697186111,-112.53967411743888,-36.16741655711715
765 +V2N,-0.46225461288822906,159,BC,53.86078218610063,-122.78023604119497,-36.4935863739846
766 +N7M,-0.464098863236543,52,ON,42.38559699211539,-82.19635739096154,-36.610600164906025
767 +T5T,-0.4645829529676187,341,AB,53.52009546558651,-113.66132208032845,-36.64127889619675
768 +B4V,-0.46758274478301853,63,NS,44.364046670476185,-64.55827906777778,-36.83105707936397
769 +G0S,-0.4747265489898303,83,QC,46.53187009807229,-71.45519242759036,-37.280715591037826
770 +E4P,-0.4755591291760568,123,QC,46.21507248780488,-64.49316419512195,-37.33291269237965
771 +T6T,-0.47789358618352085,273,AB,53.45183086904762,-113.38329634758242,-37.479035688196106
772 +T5Z,-0.47827254844759043,187,AB,53.63351592491979,-113.46677246411765,-37.502724285557775
773 +B0P,-0.47862526191398935,145,NS,45.03677262234483,-64.65607027027586,-37.52476402922983
774 +T9E,-0.484475903406337,230,AB,53.26132383026087,-113.55408685421739,-37.88921705544419
775 +V8C,-0.4851357768364521,50,BC,54.0647002556,-128.63767870060002,-37.93018879126632
776 +T7S,-0.48780349699875486,55,BC,54.12469462552727,-115.66316142669092,-38.09555300730052
777 +T5K,-0.4980619312365405,263,AB,53.54230627982509,-113.51101078396579,-38.72734954358449
778 +S7M,-0.5028458765812305,74,SK,52.1211585,-106.70171112162163,-39.01977452422367
779 +T6K,-0.5043232132757233,78,AB,53.459103021794874,-113.45266045141024,-39.10979633632142
780 +V1R,-0.5082476792100931,65,BC,49.09961684584616,-117.7022121173846,-39.34828958093461
781 +T6V,-0.5100815914643223,105,AB,53.61493422590477,-113.5531794907619,-39.45941756528018
782 +B6L,-0.5101278530830549,53,QC,45.401810198490566,-63.26173380792453,-39.46221820584104
783 +T5B,-0.5128238248293585,64,AB,53.5715747825,-113.4625019915625,-39.62520655043581
784 +E1G,-0.5143955323222111,93,QC,46.12472595698925,-64.8750412795699,-39.72002353387967
785 +T6L,-0.5154513865835954,139,AB,53.461955785323745,-113.4143033605036,-39.78363681482085
786 +T0E,-0.5156878964835685,234,BC,53.69615887323504,-114.93267997983332,-39.797876896827965
787 +R0A,-0.5196941417175592,140,MB,49.45415273571428,-96.77553277142857,-40.03857888804476
788 +T9K,-0.5204416029784291,174,AB,56.75448963606322,-111.45476833615518,-40.083380981472125
789 +T5Y,-0.5254401432846719,286,AB,53.6202222893007,-113.40194535482517,-40.382129341761065
790 +R7A,-0.5284394526911235,62,MB,49.83221009677419,-99.95193661290322,-40.56067389299618
791 +S4S,-0.5325383941997079,85,SK,50.41949250588235,-104.62199831764705,-40.80381356594732
792 +T9M,-0.53329823599282,124,AB,54.44018514982258,-110.22386860487903,-40.8487762179784
793 +T5X,-0.5364372403985062,118,AB,53.621857290067794,-113.51862434630509,-41.03416105589864
794 +V2G,-0.5420407529614887,71,BC,52.13133056492958,-122.13235654295775,-41.363652857332355
795 +T9H,-0.5455625178922567,107,AB,56.65121111928973,-111.38734856450468,-41.56979308659252
796 +E3B,-0.5498708587290556,104,QC,45.91962835576923,-66.63627050961539,-41.820988826155116
797 +T5G,-0.5532904913034983,60,AB,53.56732104916667,-113.4959096605,-42.019599885944636
798 +E3A,-0.5574204736375721,73,QC,45.97249969863014,-66.62391587671233,-42.2585641154523
799 +V2L,-0.5578765975401895,54,BC,53.90557664111111,-122.75014268796296,-42.284895358919414
800 +V2M,-0.5637529818324943,87,BC,53.862374266436774,-122.80571560436782,-42.623056936457026
801 +A1L,-0.5674470655309168,70,NL,47.53215062857143,-52.88351435714286,-42.83462115793431
802 +S0J,-0.5833158266505525,181,SK,53.64636858563536,-106.09879032596685,-43.73460519732198
803 +R0C,-0.584692771566753,154,MB,50.60096287012987,-97.29405031818182,-43.81202623217101
804 +S0K,-0.587528177785795,260,SK,52.30172729615385,-106.50538795,-43.97111631334082
805 +T5A,-0.5960126588867342,90,AB,53.59417318144444,-113.41982069088888,-44.44448135008186
806 +G0R,-0.5961426066706598,115,QC,46.86645535556522,-70.40585769886957,-44.45170019756848
807 +B0E,-0.5981391940996512,111,QC,45.92972756963964,-61.05289670207207,-44.562496590506996
808 +B0T,-0.5987097830135899,116,NS,43.91738074255814,-65.03089656154448,-44.59411959264371
809 +T5H,-0.6005737437546402,123,AB,53.53062432992683,-113.50340605660163,-44.69729778861994
810 +E4W,-0.6099528445597843,59,QC,46.66648872881356,-64.8661576440678,-45.213562573189655
811 +E1A,-0.6146467937870377,207,QC,46.09167680676328,-64.72582895169081,-45.470124712911755
812 +S0M,-0.6146999922106315,174,SK,53.50384547974713,-108.93309734270115,-45.47302553915542
813 +T0H,-0.616225316659181,225,BC,56.342032887946665,-117.55666315396444,-45.55613346701553
814 +G0L,-0.6169447204569299,55,QC,47.88740009290909,-69.19724255963636,-45.59528650625232
815 +R0J,-0.6175561152714182,106,SK,50.51303853773585,-99.99368561320755,-45.628539099698685
816 +B0S,-0.6176163699754186,132,NS,44.805698483030305,-65.36674427090908,-45.631815137281976
817 +T9N,-0.6184675365069037,66,AB,54.25565378090909,-110.78010988893939,-45.67807182774863
818 +T0G,-0.6339129595218171,158,BC,55.072868700360765,-115.07036537801899,-46.510650669475595
819 +B0K,-0.6455771681814845,150,QC,45.684979304533336,-62.9367440186,-47.13093699390344
820 +T7E,-0.6456113073979279,72,BC,53.591499910083336,-116.39042841183333,-47.13274187147983
821 +R0G,-0.6474095551810373,94,MB,49.37691019148936,-97.79009932978722,-47.22772487412604
822 +P0J,-0.6499168237750474,69,QC,47.54582441884058,-79.72523725507246,-47.35987340702231
823 +S0G,-0.6549329186026129,227,SK,50.55208828634361,-103.88413824669603,-47.623260135085154
824 +V1J,-0.6557969042001845,158,BC,56.22822570740506,-120.84989123601265,-47.66849334074331
825 +V2J,-0.6588470286033169,100,BC,52.979652449599996,-122.5205916196,-47.8278677667859
826 +T8S,-0.6699959618710262,51,BC,56.21814660388235,-117.31081339805883,-48.40630093953753
827 +E1B,-0.6751987373023386,98,QC,46.05525647959184,-64.80372075510205,-48.67403428724166
828 +J0Z,-0.6780093397924021,129,QC,47.81042031573644,-79.17799626906978,-48.818088639688405
829 +S4N,-0.6833294553613497,61,SK,50.45005506557377,-104.57220647540984,-49.08965928900918
830 +S9H,-0.686729552505342,73,SK,50.306103410958904,-107.79494732876712,-49.26246544771753
831 +S6H,-0.6885631712612246,84,SK,50.42104622619048,-105.54688208333333,-49.355413501010744
832 +S4P,-0.6892653627431847,58,SK,50.44742644827586,-104.60799389655173,-49.3909632154437
833 +S4R,-0.6958706504920213,51,SK,50.47977998039215,-104.62368984313726,-49.724148861163485
834 +T0B,-0.7089086613533399,258,AB,53.10791953458527,-112.134713518531,-50.37539127618291
835 +E3L,-0.7108794496836827,54,QC,45.19697883333333,-67.25736974074074,-50.47309456807654
836 +E1C,-0.7131237181752209,85,QC,46.099840447058824,-64.80482864705883,-50.58412160757637
837 +B5A,-0.7141968972284607,70,NS,43.894168588999996,-66.080079339,-50.637125246879755
838 +V0J,-0.7305569927172618,219,BC,54.47998581675799,-125.170256273242,-51.4381364158478
839 +T0A,-0.7313818381159679,247,AB,54.219962477931176,-111.90045098591904,-51.4781759301031
840 +S3N,-0.7532837670148541,61,SK,51.211713508196716,-102.46195759016393,-52.52934414553787
841 +B0W,-0.7581563525422894,143,NS,43.933772295174826,-65.8353865451049,-52.76008636410977
842 +R0K,-0.7785260129693847,84,MB,49.59411054761905,-99.73654076190476,-53.712613105131766
843 +A2H,-0.7801104737862806,52,QC,48.96909780769231,-57.893923134615385,-53.78589558404359
844 +S6V,-0.7828089988729927,94,SK,53.19294357446808,-105.7423495,-53.91043738900096
845 +XNL,-0.7914517779261845,147,NL,48.143912340136055,-53.86030494557823,-54.30706285326672
846 +S4T,-0.7969899236385463,89,SK,50.4543451011236,-104.6345960449438,-54.55941756363401
847 +G0C,-0.8000965077478731,76,QC,48.17086863763158,-65.44174349223685,-54.70036351137444
848 +S4A,-0.801307602860282,57,SK,49.19965112280702,-103.04507957894737,-54.755192471475226
849 +V1G,-0.8037329944336357,74,BC,55.819297502837834,-120.43316411027027,-54.86479587707601
850 +B0M,-0.8285117151949257,97,QC,45.513049222577315,-64.03947443082474,-55.969446067923656
851 +S0L,-0.8290792039619184,110,SK,51.482070162036365,-108.39778005165455,-55.994425824148664
852 +A0A,-0.8407918880638492,189,NL,47.56656860370371,-53.475450793121695,-56.506842467995064
853 +J0Y,-0.8444055994190368,59,QC,48.456359294067795,-77.59340354084746,-56.663730540404835
854 +S0E,-0.8583284102033099,111,SK,52.95846410810811,-103.58578652252253,-57.262912393418986
855 +R0L,-0.868648867889427,63,SK,51.61560646031746,-100.78283268253968,-57.701710504263204
856 +E2A,-0.8710231537991799,52,QC,47.62416828846154,-65.65905146153847,-57.80201960865086
857 +E3Y,-0.8950105191550692,53,QC,47.066267415094345,-67.72137916981131,-58.80219424695581
858 +R0M,-0.8989362235178056,50,SK,49.79425156,-100.92250111999999,-58.96360761485726
859 +R8N,-0.9131486412870422,73,MB,55.672305465753425,-97.96253098630137,-59.54270900391387
860 +S0A,-0.9208596441684105,174,SK,51.274652522988504,-102.65319847126437,-59.853475590499094
861 +G0J,-0.9506162836407417,59,QC,48.57217272169491,-67.5288127359322,-61.03050221563782
862 +V0C,-0.9530582980848938,137,BC,56.48810871795621,-121.60891133116789,-61.12555019061033
863 +S0H,-0.9579917234403379,110,SK,50.11790250909091,-106.18226065454546,-61.316862087474334
864 +R2W,-0.9729888247965811,72,MB,49.92074486111111,-97.13534740277777,-61.89266852164068
865 +S0C,-0.9745741816524417,94,SK,49.424682129787236,-102.3982300893617,-61.95303437750332
866 +S0N,-1.0024481231516804,105,SK,49.925937733333335,-108.53170541904761,-62.998909228543184
867 +A0G,-1.024155707811574,129,NL,49.209192103100776,-54.44485828062016,-63.79345846622289
868 +A0B,-1.1072454934695073,86,NL,47.51593593023256,-53.65787445348837,-66.68025973162428
added results/reference/heterogeneity.csv +9 −0
@@ -0,0 +1,9 @@
1 +prov,n,elast,se_el,bath,se_bath
2 +NL,1016,0.4449402998648778,0.043698080778453864,0.25726475107539015,0.027165059095347537
3 +NS,1913,0.4851725399074676,0.04565660959163726,0.1656240969570683,0.023490781977225778
4 +BC,29976,0.4912693148799874,0.021788280143043053,0.09192441875259849,0.006043910769659036
5 +ON,48781,0.5027549607050659,0.013665133751418113,0.10834985752206905,0.005397005936542421
6 +AB,22236,0.5649369936597379,0.02248453543955825,0.1215699395201278,0.007876514397877418
7 +QC,30556,0.5963844617932081,0.016056846126880193,0.13256694397453356,0.012297833423032442
8 +SK,3400,0.6506790091858067,0.034228069848937726,0.17076158324307097,0.013111415386346751
9 +MB,3015,0.6618380879321788,0.04705438178848472,0.20593928770410647,0.012669931589266518
added results/reference/lopo.csv +9 −0
@@ -0,0 +1,9 @@
1 +prov,n,r2_within
2 +ON,48781,0.5490266904110517
3 +MB,3015,0.527218263229293
4 +SK,3400,0.47456011149762256
5 +NS,1913,0.4499312984289957
6 +NL,1016,0.37813325946351994
7 +BC,29976,0.3169765993848541
8 +QC,30556,0.3033685288112239
9 +AB,22236,-0.10063210682757151
added results/reference/oos.json +11 −0
@@ -0,0 +1,11 @@
1 +{
2 + "n_train": 112732,
3 + "n_test": 28187,
4 + "oos_r2": 0.7638581016384884,
5 + "rmse_log": 0.2821402305020966,
6 + "mae_log": 0.20478270963446624,
7 + "median_ape": 15.847920976780344,
8 + "mean_ape": 22.455344223161646,
9 + "within10": 33.756696349380924,
10 + "within20": 59.45648703302942
11 +}
\ No newline at end of file
added results/reference/quantile.csv +7 −0
@@ -0,0 +1,7 @@
1 +tau,ln_living,se_living,bathrooms,se_bath,ln_lot,se_lot
2 +0.1,0.557,0.008,0.181,0.004,-0.014,0.001
3 +0.25,0.534,0.005,0.146,0.002,-0.011,0.001
4 +0.5,0.552,0.005,0.114,0.002,-0.002,0.001
5 +0.75,0.601,0.006,0.087,0.003,0.009,0.001
6 +0.9,0.598,0.01,0.071,0.004,0.023,0.002
7 +,0.584,0.0,0.126,0.0,0.007,0.0
added results/reference/robustness.csv +7 −0
@@ -0,0 +1,7 @@
1 +label,n,r2,ln_living,se_living,bathrooms,se_bath,ln_lot,se_lot
2 +Baseline (all residential),140931,0.767468768080029,0.5465902011969274,0.00892947271640908,0.10904453574843155,0.003579252763021647,0.02979174326548159,0.0035709117802369063
3 +Houses only,82334,0.761793265245385,0.5129873475049976,0.01030264542377453,0.10266974717041621,0.003908566686191941,0.054684646186670974,0.0033312381695505995
4 +Condominiums only,57857,0.8129930707132008,0.6193658822714013,0.01734056347749674,0.12089234598066487,0.004809131482406632,0.004523044129116594,0.00316671402839587
5 +Price trimmed 0.5/99.5\%,139552,0.7650301197792827,0.536172123264197,0.008514115109115943,0.10735494541721012,0.0034533933113074134,0.027941636718505563,0.0034513139810203987
6 +FSAs with $\geq$50 listings,130590,0.7599781494218234,0.5421370432175243,0.00974848999045923,0.10896390949561037,0.0037948164163639784,0.02953148809974477,0.0038276450051442294
7 +ON/QC/BC only,109313,0.7616483751038278,0.5323171555588772,0.01037610752310238,0.09601681818930126,0.003994683449270653,0.030175336749736274,0.00312684382715802
added results/reference/summary_stats.csv +10 −0
@@ -0,0 +1,10 @@
1 +,mean,sd,p25,median,p75,n
2 +price_cad,763592.0,475478.0,449000.0,639888.0,928000.0,140931
3 +ppm2,5382.0,2682.0,3580.0,4781.0,6593.0,140931
4 +living_m2,151.7,79.1,93.8,134.6,185.8,140931
5 +bedrooms,3.11,1.32,2.0,3.0,4.0,140931
6 +bathrooms,2.32,1.11,2.0,2.0,3.0,140931
7 +half_baths,0.35,0.52,0.0,0.0,1.0,140931
8 +parking_n,2.72,11.2,0.0,2.0,4.0,140931
9 +stories_n,2.44,6.01,1.5,2.0,2.0,140931
10 +lot_m2_f,2621.0,10818.0,0.0,0.0,656.0,140931
added results/reproduced/coef_M1.csv +10 −0
@@ -0,0 +1,10 @@
1 +,coef,se,p
2 +const,9.561064711431111,0.09767380092125273,0.0
3 +ln_living,0.6802383046000451,0.02291770677003229,1.3197837294749597e-193
4 +bedrooms,0.0008901944719278652,0.0036690138680485892,0.8082959163575186
5 +bathrooms,0.13002371514122335,0.009378632811233642,1.049316867882094e-43
6 +half_baths,-0.011264795553404622,0.012482530729836343,0.36682060610960576
7 +parking_n,0.002393518205781103,0.0018165298619670413,0.18762680702738954
8 +stories_n,-0.03621223965222726,0.021154396014417143,0.0869322723697676
9 +has_lot,0.048655984493162385,0.04777675379320422,0.3084865258129831
10 +ln_lot,0.01504219027825254,0.006444026729633571,0.019580841451921346
added results/reproduced/coef_M2.csv +15 −0
@@ -0,0 +1,15 @@
1 +,coef,se,p
2 +const,9.843219336480711,0.1180119872764956,0.0
3 +ln_living,0.6775136191469533,0.02290249425980483,2.5075782198017083e-192
4 +bedrooms,-0.0011372311640692294,0.0036132514312983625,0.7529598256980948
5 +bathrooms,0.13555014490424772,0.00990992482554156,1.3700308994621599e-42
6 +half_baths,-0.017381604852869936,0.011893921262655453,0.14390965967012603
7 +parking_n,0.0023484621418566436,0.001802806448900163,0.19268739809055757
8 +stories_n,-0.03686067090851472,0.021714783183589,0.08960368079906691
9 +has_lot,0.046959232091369874,0.04728466266543096,0.3206526336262623
10 +ln_lot,0.014130957246089967,0.006388102972615881,0.02696154415150415
11 +ow_Condo/Strata,-0.16522332384717497,0.07680687513170473,0.0314641418064614
12 +ow_Freehold,-0.26959038033908245,0.07486360251600414,0.00031688894269064867
13 +ow_Leasehold,-0.5031052107456738,0.09051568692363605,2.7255509139764786e-08
14 +ow_Other,-0.36972531815110077,0.12609553696433143,0.0033667320965700695
15 +ow_Unknown,-0.21667199202398263,0.07620168076373092,0.004463476928618826
added results/reproduced/coef_M3.csv +23 −0
@@ -0,0 +1,23 @@
1 +,coef,se,p
2 +const,10.361438182384454,0.1100152204743566,0.0
3 +ln_living,0.5849693955314611,0.017677270974361045,3.923725476797545e-240
4 +bedrooms,-0.003636796797465855,0.0032250936849969147,0.25946515421297534
5 +bathrooms,0.1384376211666279,0.00611969936304834,2.6544273357549274e-113
6 +half_baths,-0.018397989126264738,0.009597517006732673,0.05524390147707337
7 +parking_n,0.0014102784512141707,0.0010814544678718798,0.1922140911141791
8 +stories_n,-0.025959535393899225,0.015689999677118403,0.0980203876171749
9 +has_lot,-0.16170482781880885,0.037903848373190274,1.9884394966839912e-05
10 +ln_lot,0.029303815960055123,0.0049626638421236945,3.529546521417734e-09
11 +ow_Condo/Strata,-0.18851647611832043,0.0864394818013423,0.029190291431387554
12 +ow_Freehold,-0.31216457449251667,0.08703466144302298,0.0003349282547636122
13 +ow_Leasehold,-0.5499413552485731,0.1011058252195222,5.350088984782185e-08
14 +ow_Other,-0.41349373150783164,0.12444239810022012,0.0008912769091980017
15 +ow_Unknown,-0.09021428190827951,0.0922108709031278,0.3279024475748098
16 +pv_BC,0.23967599230938008,0.045816536700054054,1.684027256853807e-07
17 +pv_MB,-0.22929989304925064,0.044565200040833426,2.671393087504706e-07
18 +pv_NB,-0.6171892224918915,0.1100500362891499,2.04370785911378e-08
19 +pv_NL,-0.635020848272304,0.050414630879357165,2.2222970952154956e-36
20 +pv_NS,-0.1619570894024912,0.054527772851922174,0.002976290511285856
21 +pv_ON,0.2560522817034921,0.026930851569243172,1.9479762311022223e-21
22 +pv_QC,-0.11980368368208992,0.05683812454953523,0.03504785932733063
23 +pv_SK,-0.37887408102521025,0.04709066577724386,8.580274911611256e-16
added results/reproduced/coef_M5.csv +26 −0
@@ -0,0 +1,26 @@
1 +,coef,se,p
2 +const,10.31279516219887,0.23915658007410237,0.0
3 +ln_living,0.5300775244939722,0.010200096739191443,0.0
4 +bedrooms,-0.0030182556241014962,0.002856962415858243,0.2907598469108321
5 +bathrooms,0.11107079513655177,0.0034720178610876534,0.0
6 +half_baths,-0.031740231596007605,0.007585288657888845,2.8586225252480446e-05
7 +parking_n,0.0008080165147721341,0.0006225344924431983,0.19430569260236452
8 +stories_n,0.0009042377409267352,0.00040373695287741865,0.02511232243560446
9 +has_lot,-0.41697659840283324,0.046463184959439206,0.0
10 +ln_lot,0.060959009581207396,0.0071746528194990096,0.0
11 +bt_Duplex,0.12450902778408916,0.02925594946228214,2.0825326801254818e-05
12 +bt_Fourplex,0.2941177183060848,0.04857047100799493,1.3999594816738181e-09
13 +bt_House,0.357496779086561,0.04729768830050037,4.085620730620576e-14
14 +bt_Manufactured,-0.06390862705637057,0.05730219485889019,0.2647257046303342
15 +bt_Other,0.07996731040275282,0.04765137781299006,0.09331310682009764
16 +bt_Row/Townhouse,-0.014243581329127147,0.02121255684232755,0.5019215913861708
17 +bt_Triplex,0.32485319869009294,0.041832332622528515,8.215650382226158e-15
18 +ow_Condo/Strata,0.08358479240132341,0.03996097657533153,0.03646890495104582
19 +ow_Freehold,0.07046226049616404,0.054388507226910514,0.19513544536921978
20 +ow_Leasehold,-0.15835406185702816,0.0642648249973242,0.013736311088748954
21 +ow_Other,-0.17609324142692748,0.07409117196622711,0.017467807461515994
22 +ow_Unknown,0.16650935659680718,0.02780116256106644,2.107529262218577e-09
23 +cat_condo,-0.00688524619431511,0.23334810769576403,0.9764607707915718
24 +cat_house,-0.10388206170846732,0.23651611652549687,0.6605038102307772
25 +cat_plex,-0.09993184933709527,0.2366941764080861,0.6728803734090887
26 +cat_townhouse,0.09414140867972552,0.2414032609745756,0.6965545065924998
added results/reproduced/ext2.json +21 −0
@@ -0,0 +1,21 @@
1 +{
2 + "nonlin": {
3 + "b1": 1.1452714885176427,
4 + "b2": -0.06237402986748119,
5 + "r2": 0.7703503373020513
6 + },
7 + "gradient": {
8 + "beta_logdist": -0.08208965710370426,
9 + "se": 0.0008188824957605701,
10 + "r2": 0.08291461383008458
11 + },
12 + "moran": {
13 + "struct_I": 0.49414633193493007,
14 + "struct_z": 153.38454763939137,
15 + "struct_p": 0.005,
16 + "grand_I": 0.07233897724866778,
17 + "grand_z": 20.208228113147626,
18 + "grand_p": 0.005
19 + },
20 + "lopo_mean": 0.31451087874557027
21 +}
\ No newline at end of file
added results/reproduced/fit.json +22 −0
@@ -0,0 +1,22 @@
1 +{
2 + "M1": {
3 + "r2": 0.4665611989553674,
4 + "n": 83542
5 + },
6 + "M2": {
7 + "r2": 0.4696655504941184,
8 + "n": 83542
9 + },
10 + "M3": {
11 + "r2": 0.5693124584846623,
12 + "n": 83542
13 + },
14 + "M4": {
15 + "r2": 0.7657314371141364,
16 + "n": 83542
17 + },
18 + "M5": {
19 + "r2": 0.7695479150272374,
20 + "n": 142146
21 + }
22 +}
\ No newline at end of file
added results/reproduced/fsa_premia.csv +870 −0
@@ -0,0 +1,870 @@
1 +fsa_c,fe,n,prov,lat,lon,premium_pct
2 +V6S,1.1804782045116122,107,BC,49.25335851214953,-123.2259642411215,227.03700911064502
3 +V6T,1.1053952849514863,61,BC,49.26204722459016,-123.24006857868852,203.3812977040153
4 +V8E,1.078189575214807,132,BC,50.10202857348485,-122.97235536969697,195.2388568337827
5 +V6G,1.0316073687454952,138,BC,49.289252171739136,-123.13348826014492,181.8013827877746
6 +V7T,1.0144316693907731,54,BC,49.32848744444445,-123.14147361111111,177.00257635944098
7 +V5Y,0.9958410224213045,114,BC,49.254106732456144,-123.11079856754387,171.9004917241993
8 +V5Z,0.9795490900266165,174,BC,49.24777875402299,-123.11981959022988,167.50659700062286
9 +V6Z,0.9692717721220476,235,BC,49.27605226255319,-123.12563951702128,164.77142584817287
10 +V6M,0.9689812312964965,64,BC,49.23410638125,-123.1465720203125,164.69451011364615
11 +V6K,0.9512844025434589,86,BC,49.26588249186047,-123.16110177790698,160.0514614888253
12 +V6E,0.9415239596107334,147,BC,49.28400365578232,-123.12564494761905,157.5255908997475
13 +V6J,0.9166955501593661,97,BC,49.26358798969073,-123.14441420103093,151.21036303147034
14 +V6P,0.9031430064513273,180,BC,49.21633932722222,-123.13091813777777,147.82878982396585
15 +M5R,0.8698908655621355,117,ON,43.67220532820513,-79.39600831538462,139.723458624102
16 +V5V,0.8174453352810126,66,BC,49.2510103469697,-123.09044469545454,127.47502973739469
17 +V6B,0.8159767278677059,317,BC,49.27784318264984,-123.11714510694007,127.14120341228804
18 +V7L,0.807700624691377,194,BC,49.31319002010309,-123.07022435515464,125.26911685353777
19 +V6H,0.7984133601793226,53,BC,49.259071949056604,-123.1211127018868,123.18666807339773
20 +V5T,0.7756421441723007,146,BC,49.26285982212329,-123.09317585157534,118.16186381971949
21 +H3Z,0.7753115103250867,80,QC,45.483907550875,-73.59167753325,118.08974404664542
22 +M4V,0.7724727779611622,79,ON,43.686205711392404,-79.40124440632911,117.47152352843244
23 +M4G,0.7642882272477791,57,ON,43.7090933877193,-79.36629159649122,115.69888085264006
24 +M5M,0.7632314357613094,62,ON,43.7304442483871,-79.41810049838709,115.47105251644037
25 +V7P,0.752041454788166,103,BC,49.324985714563105,-123.11346022427185,113.0733755372494
26 +V7J,0.7434590322879703,110,BC,49.31863358181818,-123.03439226363635,111.25251468017066
27 +V5X,0.74139171590815,113,BC,49.214213138053104,-123.10437581681416,110.81624001055852
28 +V5N,0.7348901251769409,170,BC,49.25667369235294,-123.06651573941177,109.45004513099623
29 +V7M,0.7323330412171332,143,BC,49.317949494405596,-123.07715153076923,108.91514796015862
30 +V6A,0.7317183302559875,87,BC,49.27844599885057,-123.0969782275862,108.7867649920097
31 +M5S,0.731346539858279,81,ON,43.66527621395062,-79.39243932530864,108.70915450592777
32 +M4W,0.7153519387954302,116,ON,43.672825213793104,-79.38232881551724,105.3974898200682
33 +T1W,0.7101778224452885,144,BC,51.07958369780555,-115.3408182382014,104.33748397133473
34 +V5C,0.70300610554675,334,BC,49.266616878443116,-123.00446478353294,102.87727574317778
35 +M6J,0.7027346706338978,103,ON,43.64523133038835,-79.42044304563106,102.82221524052618
36 +M4L,0.6945433755858104,80,ON,43.66916659525,-79.31544520050001,101.16762450517211
37 +M4S,0.6866269389095908,113,ON,43.703525412389375,-79.39309123097345,99.58138072782508
38 +V5H,0.6807764258259574,406,BC,49.22717825960591,-123.000975341133,98.4171362831655
39 +L6J,0.6790708797152167,70,ON,43.48274887828571,-79.65925323399999,98.0790151306448
40 +M5E,0.6784077430350592,136,ON,43.64484033602941,-79.37409938382353,97.94770521316553
41 +H2V,0.6699111139308156,167,QC,45.51882259209581,-73.61069515143713,96.27294197642517
42 +V5K,0.66471253094417,88,BC,49.28709072545455,-123.00190307215908,95.25524837380401
43 +M5T,0.6630552873217685,88,ON,43.653551057045455,-79.39621801784091,94.93193084065415
44 +BC_other,0.6614337449661847,178,BC,49.3558738771904,-122.44415465176056,94.61609659684665
45 +M5P,0.6602780676018791,53,ON,43.69288705283019,-79.41585144528301,94.39131309290207
46 +M5J,0.6553999438184206,136,ON,43.64255669529412,-79.37989593058823,93.44535732570567
47 +V5P,0.6552806791872345,50,BC,49.221308523999994,-123.066947012,93.42228751224329
48 +M4M,0.65198389188783,80,ON,43.661866098625,-79.344496877875,92.7856653518877
49 +V8S,0.641183094169243,51,BC,48.45529912882353,-123.24218735,90.7146309227369
50 +M6G,0.6394847795643633,55,ON,43.667948712727274,-79.42046832545455,90.39101236052556
51 +M5V,0.6389143181866381,608,ON,43.642139918141446,-79.39927199338815,90.28243261452818
52 +M6P,0.6369420167643874,65,ON,43.660300795384615,-79.46310644461538,89.90750815561216
53 +M4P,0.6348943633138071,113,ON,43.70969964955753,-79.39240470619468,89.51904124977936
54 +V5L,0.6317952064186573,58,BC,49.2797864724138,-123.0641884862069,88.93260121055873
55 +V5R,0.6309986143115941,195,BC,49.23825596102564,-123.04046092461539,88.78215892019338
56 +V8W,0.6275550946413989,101,BC,48.42692640128713,-123.36505527742574,88.13320183208712
57 +V7C,0.6257346157859758,190,BC,49.167680536842106,-123.15963086684211,87.7910208772483
58 +V5S,0.6189051512019341,138,BC,49.20814695144927,-123.03039088768115,86.51287823380403
59 +V7E,0.6148631289320997,134,BC,49.131808500000005,-123.17006823358209,85.76051059409424
60 +V5A,0.6106279110167313,121,BC,49.27571034876033,-122.91564597190082,84.97543800190333
61 +M5G,0.6063599811827952,56,ON,43.656454582142864,-79.38556616964286,84.187658101977
62 +M4Y,0.6003369943295772,207,ON,43.6664629410628,-79.3819039231884,83.08163239140869
63 +M6S,0.592061079264905,103,ON,43.642857884951454,-79.47543324786407,81.57271679272586
64 +L6L,0.5914416126861398,196,ON,43.40279550326531,-79.71027687969388,81.46027339411663
65 +V3J,0.5857893430352522,417,BC,49.25901872844433,-122.88441025418952,80.43750420455834
66 +L5H,0.5837005086502931,109,ON,43.54200570247706,-79.60519678504588,80.0609935125797
67 +V6X,0.5753475161253988,480,BC,49.181608957689804,-123.1269859278566,78.5632095774166
68 +M6K,0.5752793694267674,165,ON,43.63956636872727,-79.41825212878788,78.55104149879877
69 +H3J,0.5690686195217985,140,QC,45.48786321028572,-73.56970971307142,77.44554217824937
70 +M5A,0.5685767149758085,300,ON,43.654056123900006,-79.36410062996667,77.35827737412278
71 +V8Y,0.5676598828600917,61,BC,48.519147915081966,-123.37316194868853,77.19574412867283
72 +V0V,0.5671933035845843,159,BC,49.352252605353705,-123.03645617196308,77.11308755117679
73 +L6K,0.5662736645017535,90,ON,43.44110139511111,-79.68307507288888,76.95028230629113
74 +H3B,0.5631330080122484,142,QC,45.49276104415493,-73.59793923485915,76.39541403525307
75 +V3H,0.5598895128907591,256,BC,49.28109370378906,-122.84500172046874,75.8242032308791
76 +M8V,0.5586420168839532,266,ON,43.62014299,-79.4852561931579,75.60499999545705
77 +H2T,0.555187136270546,55,QC,45.52445799363637,-73.594340012,74.99935250766477
78 +V9A,0.554676170870422,269,BC,48.43592613301115,-123.39741033691449,74.90995673450776
79 +V8B,0.5539777793365264,171,BC,49.70227148058479,-123.14849389748538,74.78784374783174
80 +L5G,0.55301614522612,132,ON,43.56012846212121,-79.58319322666668,74.6198425859698
81 +V8V,0.552500459386001,140,BC,48.421299179142856,-123.36135712042856,74.5298168202458
82 +M6H,0.5512154197209821,90,ON,43.665936627444445,-79.440062647,74.30568312409139
83 +H2Z,0.5509174131080784,59,QC,45.504079639322036,-73.56302240915254,74.25374661694937
84 +H2Y,0.5468729210596371,113,QC,45.504820934690265,-73.55542577486726,73.55040201893372
85 +V6Y,0.5464942038747733,466,BC,49.16321200064378,-123.13240907210302,73.48468794355938
86 +L7R,0.5446753045180734,160,ON,43.333123727625,-79.798798251625,73.16942356027178
87 +V5J,0.5436188811902339,87,BC,49.21711755287357,-122.98784176551725,72.98657993869271
88 +H2J,0.54337519536702,91,QC,45.529258230329674,-73.58201836043956,72.94443069735024
89 +V5B,0.5424184390295778,69,BC,49.27002504927536,-122.97860230869564,72.77904414718621
90 +H3G,0.5418689773997604,354,QC,45.4970781629096,-73.57571249483051,72.68413476890947
91 +M8Y,0.5314437163426666,95,ON,43.627862064842105,-79.49140403652632,70.89320923731736
92 +V3N,0.5255823637027038,238,BC,49.220909621512604,-122.93663795228778,69.89447370411241
93 +H3K,0.5225612395108933,101,QC,45.48020237792079,-73.56505899425743,69.3819759490384
94 +M4J,0.5207868502660874,53,ON,43.68624149056603,-79.33681994716981,69.08169288095935
95 +V7A,0.5159935646435766,102,BC,49.13961574607843,-123.11682765980393,68.27317530928244
96 +V3K,0.5089489254271079,222,BC,49.24278744994002,-122.86744199414414,67.09191715336569
97 +M5B,0.5031929114215871,165,ON,43.657262665393944,-79.37669975890908,66.13289645414025
98 +V5E,0.49960849042481015,103,BC,49.2210851446602,-122.96103201747573,65.53847218169003
99 +H3E,0.49880157726176205,312,QC,45.463389512019226,-73.54601841179488,65.40495088678568
100 +M2N,0.4973121705344165,508,ON,43.768244577165355,-79.40971892173228,65.15877901073037
101 +V8R,0.4960185358362434,83,BC,48.433864826385545,-123.32675938771084,64.94526201976483
102 +M8W,0.49520496638206046,59,ON,43.599655339322034,-79.53986481135594,64.81112216641587
103 +L7B,0.4936042443827514,89,ON,43.93770927191011,-79.55990434382022,64.54751641348386
104 +M6B,0.4923108274560211,72,ON,43.707824917500005,-79.44787965944444,64.33482544920128
105 +M2K,0.4889622706651797,169,ON,43.77005613668639,-79.37893308011834,63.78546125539981
106 +H2S,0.4871231402319538,74,QC,45.534869613513514,-73.60592596283783,63.48451525338725
107 +M8Z,0.4835510949270026,105,ON,43.62729407685714,-79.51700381647619,62.90158290844445
108 +H3A,0.4802536984864513,99,QC,45.50463486888889,-73.57192755505051,62.36531643627436
109 +H3C,0.47764982917432325,659,QC,45.49481268691957,-73.56064805188164,61.943088323428476
110 +M9A,0.47671732422527124,108,ON,43.65755771944445,-79.5263898787037,61.79214598028098
111 +L6G,0.47610881714314024,100,ON,43.854794586999994,-79.33263630100001,61.69372426181214
112 +V4L,0.4750009106749055,56,BC,49.01915098571429,-123.05950948571429,61.514681938217606
113 +V8M,0.4724758251619226,68,BC,48.58669803220589,-123.42030706867648,61.10735803499161
114 +V6V,0.46121239282697785,78,BC,49.17682761794872,-122.98094028076922,59.302917383336705
115 +V4B,0.4607953033138201,247,BC,49.02796160186308,-122.80140418079172,59.23648766161384
116 +V4M,0.4586472045767333,155,BC,49.02987598774193,-123.08553847548387,58.89479908535795
117 +M6E,0.4557754430654226,56,ON,43.68869573928571,-79.44732337857144,58.43914569408124
118 +H1Y,0.45573399361347966,50,QC,45.5469413234,-73.5762097886,58.43257861442779
119 +M1N,0.45054896557695234,72,ON,43.69452649861111,-79.26598770416666,57.61322726791889
120 +H4A,0.44474148811845743,111,QC,45.4729043845045,-73.61696003018018,56.700544760098445
121 +M9B,0.44141741655146827,134,ON,43.642383943358205,-79.55127546089551,56.18052570383634
122 +V8L,0.4402844087039524,116,BC,48.65562943827587,-123.41203305137932,56.003672149736076
123 +L5E,0.4384119008232674,76,ON,43.5830920156579,-79.56751400013158,55.71182737031886
124 +V3B,0.4381594239830589,385,BC,49.27628869674761,-122.77632486068681,55.67251870263421
125 +L3R,0.43569036006580947,176,ON,43.855311036931816,-79.32248972954545,55.28862742487484
126 +L3T,0.4332793576759261,209,ON,43.8155042723445,-79.40845262038277,54.91467715167857
127 +L5J,0.4307227295867225,108,ON,43.51483070259259,-79.6303898437963,54.51912379351196
128 +M2M,0.4305992841095872,133,ON,43.78746035263158,-79.41528160977444,54.500050283842214
129 +V3L,0.42986851610063087,187,BC,49.216944285026734,-122.9022059106952,54.38718783286951
130 +M3H,0.42503481661559,130,ON,43.74061505453846,-79.44508818569231,53.6427272613899
131 +L7N,0.4234002966043148,80,ON,43.3461326945,-79.77773671474999,53.39180027754835
132 +V3E,0.42156974600514674,159,BC,49.29629804591195,-122.77784996603772,53.11126567037676
133 +H2H,0.4215173627508789,72,QC,45.53300684277778,-73.57666343305556,53.10324541408129
134 +V8N,0.4212281650714269,80,BC,48.476387493124996,-123.32230179749999,53.05897471259158
135 +V3M,0.41854162547385637,368,BC,49.20012438967392,-122.92354608970108,52.64832757314997
136 +H4C,0.4161095728703602,115,QC,45.47649434634782,-73.5859912552174,52.27752989315648
137 +L7S,0.4147427756932494,107,ON,43.323556469439254,-79.80677573831775,52.069539567835356
138 +H2L,0.41472337169274454,252,QC,45.517315464920635,-73.55602448519842,52.066588839040875
139 +L4K,0.41376264111412725,235,ON,43.809756358808514,-79.52441011289362,51.920563973665665
140 +M2J,0.40851328693186795,195,ON,43.778135812820516,-79.34705057076923,51.125168608266705
141 +V4K,0.40741750994063264,142,BC,49.09987876711268,-123.0508074506338,50.95965982262969
142 +H3X,0.40180336076987555,62,QC,45.48277969854839,-73.63506315354839,50.11452435171471
143 +L6C,0.3995739022703362,104,ON,43.89060367115384,-79.34802891634617,49.780223043411056
144 +H3H,0.39699643938263796,198,QC,45.49211574984848,-73.58344043858585,49.394667168632076
145 +M6N,0.3959882391517223,94,ON,43.674688193617015,-79.4755747137234,49.24412333261212
146 +L4J,0.3955158174216123,299,ON,43.80784435979933,-79.45008760247492,49.173633817358954
147 +V8T,0.3954137299838138,88,BC,48.43808258875001,-123.35765040897728,49.15840584060125
148 +M4C,0.39014316453624853,82,ON,43.6912887792683,-79.30571371341463,48.37432479088053
149 +V3C,0.388835669331579,238,BC,49.25600513865546,-122.78412854411765,48.18045284366042
150 +H2X,0.3882171519799955,158,QC,45.5102038413924,-73.56781236512658,48.08882900080042
151 +V8P,0.38764316662838744,93,BC,48.47469091193548,-123.33396282354839,48.00385257216284
152 +L4L,0.38650068317425096,160,ON,43.7952306431875,-79.586533165625,47.83485717505522
153 +L4C,0.38593242034592007,327,ON,43.86483785409786,-79.44059626987767,47.75087198608161
154 +M3A,0.38234749715982363,52,ON,43.75777056538462,-79.32943425384616,47.22214474885107
155 +V4A,0.38044824046730774,237,BC,49.03986656741906,-122.79532274247883,46.94279746522048
156 +L4B,0.3777181670321345,138,ON,43.851870642753624,-79.41356529130435,46.542179943823946
157 +L6M,0.376882006840981,339,ON,43.44442814038348,-79.75053074053096,46.419698420853116
158 +L6H,0.3739446166231429,353,ON,43.48226256807365,-79.71528860886686,45.990237686684196
159 +L6A,0.3718173218582694,168,ON,43.85975963309524,-79.50502111107143,45.680003515089275
160 +H3S,0.3708747449797889,66,QC,45.51107112287879,-73.62704547499999,45.54275360657583
161 +H3W,0.3707384706813834,66,QC,45.49156095515151,-73.63825344560605,45.522921221292954
162 +L3P,0.3697135810473311,72,ON,43.882825575,-79.2645793638889,45.37385269026082
163 +M3C,0.3673027207183044,137,ON,43.72279223510949,-79.3353165359124,45.02379877103551
164 +V4P,0.3639694811566033,111,BC,49.068367194721446,-122.77679525598691,44.54120445563725
165 +V3T,0.3583480043065411,566,BC,49.18861408988866,-122.84397303988108,43.730948970874216
166 +H4P,0.3553610451705909,80,QC,45.500320964875,-73.653716276875,43.30227104017692
167 +M6A,0.34897636477085003,87,ON,43.713655064252876,-79.45583717068966,42.39024643001108
168 +L6E,0.3489357226168179,73,ON,43.89922047534247,-79.2700620630137,42.3844595012804
169 +L4E,0.34707050988821775,198,ON,43.935920685252526,-79.45423850530302,42.119129720230156
170 +H4G,0.34345668527850876,63,QC,45.46368533269841,-73.57123447873015,41.606463013458054
171 +V9B,0.34157461690065855,498,BC,48.45441336427711,-123.50507767174699,41.340200607943814
172 +M3M,0.340626956831497,63,ON,43.73017160603175,-79.48714938396826,41.206321589579574
173 +K1S,0.3381891824816226,118,QC,45.40162218135593,-75.69199319576272,40.86251167652652
174 +L0P,0.338149863096045,51,ON,43.52162703470588,-80.00628927019608,40.85697315800276
175 +V2Y,0.3378276224829034,494,BC,49.14544117938051,-122.63097306337444,40.811590633046094
176 +V8Z,0.3372262638344697,116,BC,48.48143344051724,-123.39820000551724,40.7269378211206
177 +V1M,0.33467751454796346,131,BC,49.16789236829544,-122.63967426788602,40.3687168404119
178 +M9C,0.3311506838604446,126,ON,43.63645783349206,-79.57141387119047,39.874532107476604
179 +V8X,0.33109585357706456,133,BC,48.46558333045113,-123.36953724759398,39.86686295749624
180 +L7L,0.3299453840223126,186,ON,43.38178980392473,-79.76737650123655,39.70604291696338
181 +V3Z,0.3244111596397202,239,BC,49.04730085529476,-122.77752989349919,38.9350138197706
182 +V4E,0.3238696365883542,74,BC,49.12691328971437,-122.90216997681118,38.859797674621646
183 +L4S,0.31857691068848465,75,ON,43.91031441333333,-79.4261700016,38.12679233632377
184 +L4G,0.31856342003757493,225,ON,43.998765813333335,-79.46276066222222,38.124928928556415
185 +M1M,0.3177863738768571,95,ON,43.728766697894734,-79.22684345610526,38.017641172001085
186 +H9S,0.3171117473192809,98,QC,45.44487940408163,-73.7666272044898,37.924562206153766
187 +M6M,0.3158135419086408,85,ON,43.6942619417647,-79.48466584176471,37.74562396766319
188 +L7P,0.3127805400482295,166,ON,43.360644596024095,-79.84873890680723,37.328474161757974
189 +H4B,0.3106312635091662,61,QC,45.4668393847541,-73.63225761721311,37.03363425384354
190 +L5B,0.3056300047885481,419,ON,43.58468133002386,-79.63852984818617,36.350004525030144
191 +H4R,0.3052377874696266,241,QC,45.51329138576764,-73.70988624414939,36.29653617811168
192 +K2A,0.3029348882019475,51,QC,45.38773149607843,-75.7896050764706,35.98302012126573
193 +V4C,0.29861990607128586,207,BC,49.15516404004479,-122.90830273705352,35.397519939236034
194 +M2H,0.2977353015216674,57,ON,43.802804316666666,-79.35995885684211,35.27779963745956
195 +M2R,0.2976596813085579,107,ON,43.780080790186915,-79.44509874121495,35.267570288199664
196 +L4A,0.29417284431378565,166,ON,43.986498592771085,-79.2666258813253,34.79673565876309
197 +L4H,0.2930684073602628,162,ON,43.885418864314815,-79.81617704042593,34.6479433436774
198 +L5M,0.29168030907638653,288,ON,43.560154465555556,-79.71829526427084,34.46116842555633
199 +V4N,0.2913222098919541,391,BC,49.1533318688766,-122.73194988090775,34.413026611092
200 +V3Y,0.29004689821046076,124,BC,49.21945656048387,-122.68549274919356,34.24171736766803
201 +L7K,0.28985779937756473,57,ON,43.87511605508772,-80.01585890017543,34.216334815568985
202 +L7M,0.28695860189390043,242,ON,43.38847158508265,-79.81273113739668,33.827778678055466
203 +L7T,0.28486998697345145,136,ON,43.31194977764706,-79.84213952720587,33.548555678903845
204 +L5R,0.28320350839385877,118,ON,43.60354915847458,-79.65688163381357,33.32618521080335
205 +L9E,0.2825686825919059,81,ON,43.50156401320987,-79.84531200876543,33.241573168151064
206 +V1Y,0.27893966828545286,522,BC,49.878937206226055,-119.49267727406131,32.75891391129184
207 +H2K,0.2776937920130024,152,QC,45.53025866802631,-73.55666822355263,32.59361572242059
208 +M1T,0.27703123029591886,108,ON,43.78121283768519,-79.29809576240741,32.50579336579169
209 +L5C,0.2757978389447288,75,ON,43.56143002253333,-79.64395328426667,32.34246261234672
210 +L1W,0.2720905128473944,86,ON,43.82465718953488,-79.09300978372093,31.852734299109507
211 +H9R,0.27160536817561837,101,QC,45.45726239059406,-73.8144499291089,31.78878216187886
212 +L3Y,0.2712650947372387,161,ON,44.06078280124223,-79.46152809341615,31.74394556861626
213 +V3A,0.26956647077249735,317,BC,49.09596835659738,-122.65821511368323,31.520352099837655
214 +T2L,0.2654418746907213,55,BC,51.07511494178182,-114.1220316057091,30.979000965744575
215 +H1X,0.26263849891443153,52,QC,45.554701448653844,-73.57006875423077,30.612331803093973
216 +H3L,0.2625035703270524,52,QC,45.5472493025,-73.66891250807693,30.594709654562013
217 +L5L,0.2613504565564743,108,ON,43.539662820740745,-79.69211816796296,30.444205887154773
218 +M1P,0.2561588520619206,143,ON,43.76638952783217,-79.26548178083917,29.76874603889934
219 +V3R,0.2560167047811601,331,BC,49.19229688286874,-122.81132853478071,29.75030107550396
220 +H7T,0.25504375161771803,141,QC,45.56247171503546,-73.76089263929077,29.624121502975974
221 +V3V,0.2530114409498969,174,BC,49.17875063774303,-122.85778090112797,29.360952529175254
222 +L5V,0.2518941046670265,67,ON,43.59289476850746,-79.68674291238807,29.21649356297893
223 +L7G,0.2516729165440695,148,ON,43.64606253405405,-79.91023786108109,29.187915569985456
224 +V8K,0.2508555956262157,86,BC,48.85732078,-123.51460901755814,29.082370722137597
225 +M9M,0.250558842902886,59,ON,43.73781486355932,-79.54368708474576,29.04407086016718
226 +H4M,0.24999606612054437,77,QC,45.50154046558441,-73.67926745493506,28.97146828462638
227 +L0B,0.24978304335016552,70,QC,44.09488145,-78.78865007,28.943997351223615
228 +H9X,0.2480320017563573,66,QC,45.41710128727273,-73.9327119471212,28.718408613861502
229 +L9T,0.24796752411577086,262,ON,43.51137571935114,-79.86930545099236,28.71010942213306
230 +V9C,0.24240821014556274,209,BC,48.416148858660286,-123.51049595956938,27.996554787597063
231 +G1R,0.24085726100414803,66,QC,46.81043285166666,-71.21550812030303,27.798192505513164
232 +V3S,0.2407738382510881,454,BC,49.1192701284593,-122.76601217607927,27.787531673142453
233 +V2X,0.237922362386942,419,BC,49.222562085966594,-122.59707398639618,27.42366763214863
234 +L6B,0.23743678474795157,65,ON,43.881371161384614,-79.23594610692308,27.361808568372847
235 +L9P,0.2324440420020216,70,ON,44.10489174485714,-79.14941283571429,26.727508588470727
236 +V4W,0.23068385729957303,92,BC,49.055138149307716,-122.4773074040243,26.504640968103544
237 +K1Z,0.23028323410895138,69,QC,45.38943826086957,-75.7428131942029,26.453970425785343
238 +H1V,0.2241121627423738,73,QC,45.55560602027398,-73.53918237863013,25.676016822146796
239 +L5N,0.22182567171466946,190,ON,43.58591173736843,-79.75825687336842,25.388988006740743
240 +L5A,0.2197715894515022,134,ON,43.59328066985074,-79.61504483873135,25.131693053445648
241 +V3X,0.2193644082089254,183,BC,49.11450359978964,-122.8427320581033,25.080752146977026
242 +L9G,0.21858717835722685,187,ON,43.21118370160428,-79.98012703294118,24.983573422530302
243 +M1S,0.2180866448951671,97,ON,43.787444254948454,-79.27613653587629,24.921030615514162
244 +L3S,0.2167562357713371,74,ON,43.84829711351351,-79.25293174594594,24.754945042003662
245 +V3W,0.2167298841101111,468,BC,49.13638065208122,-122.85442025145565,24.751657585270802
246 +L4Y,0.21664629925366008,64,ON,43.6208864684375,-79.6047929059375,24.741230671651614
247 +J4Z,0.21616933650059256,221,QC,45.45574204900452,-73.43254233108597,24.68174793750142
248 +V1W,0.21328276128972076,370,BC,49.832129482891894,-119.47655952902703,24.322363639102274
249 +H9W,0.21064971349616676,55,QC,45.43171237272727,-73.86369415963637,23.995447495622212
250 +B3K,0.2106061449473588,57,NS,44.65699289578948,-63.59714011035088,23.990045311599538
251 +L9H,0.21033896648360711,139,ON,43.27702428446043,-79.96245085330935,23.956922266851844
252 +M1H,0.20942067505305362,63,ON,43.77534122857143,-79.24616266031745,23.84314593528678
253 +H8N,0.2085593889264417,184,QC,45.44214373027174,-73.61254208,23.736527472908907
254 +H1W,0.20824694341724903,87,QC,45.54510330011494,-73.54502566551724,23.697872589663717
255 +L7E,0.20744140978473538,113,ON,43.89710461008849,-79.76053293628318,23.598269915060378
256 +M1K,0.20721098520948297,61,ON,43.728040239016394,-79.25964839704918,23.569793117216275
257 +L1N,0.20577258488525926,121,ON,43.87736059090909,-78.93659660826447,23.392178058135226
258 +M9W,0.20558638780087254,95,ON,43.72228922073684,-79.58006120947368,23.369204933175492
259 +H4L,0.205538317468728,74,QC,45.517496101486486,-73.67814538121623,23.36327467705379
260 +M1W,0.2034939970028547,78,ON,43.80231812564103,-79.31967673461538,23.11133821706699
261 +L7C,0.20147576139105433,125,ON,43.78316503648,-79.85564845344,22.8631210946336
262 +M1J,0.20015689810223247,59,ON,43.74670331694915,-79.22795723220338,22.701188241791414
263 +V9J,0.1984099260827385,54,BC,49.776672143703706,-125.12482071407406,22.487019826757184
264 +L4Z,0.19805876524468397,136,ON,43.6058992894853,-79.64538685147058,22.444014733518248
265 +P1P,0.19738877957983106,92,ON,44.924791784021735,-79.37739580163044,22.3620064741465
266 +T2N,0.19607155400478782,136,BC,51.058159152882354,-114.10323192552205,22.20093421734266
267 +V0N,0.19391273945034332,581,BC,49.57642752473322,-123.83567457752153,21.937409614707292
268 +M3J,0.19370897234524534,66,ON,43.75870534272727,-79.49077877454545,21.91256531305863
269 +K2P,0.1930146359101215,104,QC,45.41479849423077,-75.6930021576923,21.827946357473937
270 +V9P,0.19243477643979595,223,BC,49.31774374699551,-124.29305313959641,21.75732374660193
271 +L3M,0.1886662627068947,196,ON,43.2000495252551,-79.57639688744898,21.299343095177072
272 +L8B,0.18823796065593784,174,ON,43.342240413390805,-79.90926895304598,21.24740146189774
273 +T2M,0.1879172847751219,88,BC,51.06505927036364,-114.07836954055682,21.20852657808925
274 +L9L,0.18669969417658538,86,ON,44.096615484186046,-78.95768452988372,21.061034026659087
275 +L0G,0.18506656951618647,194,ON,44.050904217835054,-79.67670641974226,20.863487619437638
276 +M1V,0.1846197696072784,65,ON,43.81505365076923,-79.28574184923077,20.809497886381024
277 +L9Y,0.18384413645803252,435,ON,44.5030662103908,-80.25696926636782,20.715830365589593
278 +V4R,0.18376655736929393,107,BC,49.237776287850465,-122.57068483551403,20.706465704729137
279 +L3X,0.18236524907748553,104,ON,44.04138856153846,-79.46753677980769,20.537437191650287
280 +P0C,0.17780054670032977,61,QC,45.10526486557377,-79.69947767213115,19.988473546599828
281 +M1B,0.1763891571147483,149,ON,43.803317,-79.2149676771812,19.819242518194514
282 +M9R,0.17576912032541883,62,ON,43.68725427096774,-79.5586979032258,19.744973206995642
283 +P0E,0.17340654764681196,58,ON,44.86174264620689,-79.53869767586208,19.462400935098234
284 +J2L,0.17309139326543202,114,QC,45.30858490666667,-72.6717706204386,19.42475776804946
285 +V4S,0.17001402338850785,60,BC,49.174902812223884,-122.34484167250189,19.057808524799214
286 +M1E,0.16988157682496954,132,ON,43.768366069772725,-79.19072617977272,19.042040771413117
287 +N9V,0.16903723704107382,67,ON,42.13768198432836,-83.05490569537314,18.941571261604583
288 +V2W,0.16903499510276418,152,BC,49.19990025657895,-122.54076818157895,18.941304602238283
289 +G1S,0.16602174383787144,51,QC,46.793530874313724,-71.24401846627451,18.58344399842784
290 +H4N,0.16561330839867897,78,QC,45.53066907051282,-73.67492530307693,18.53502020706681
291 +N0B,0.1646851144554284,479,ON,43.57875182079332,-80.3547770758664,18.42504776502034
292 +V4V,0.16300896345508156,176,BC,50.050945243548064,-119.43456814102274,18.22671576636603
293 +V9M,0.16292438062847475,71,BC,49.67281577788732,-124.91141238014085,18.21671623946617
294 +K1R,0.16257117353881623,106,QC,45.4142082745283,-75.70626637358491,18.174968630384015
295 +N1L,0.16228512244535898,175,ON,43.51137985811428,-80.18754607822858,18.141169385773924
296 +H7N,0.1580511181960176,81,QC,45.56311512506173,-73.7109016574074,17.642016625709743
297 +L4T,0.15389866275370415,72,ON,43.704407573611114,-79.66491500694445,17.15452623506868
298 +J8E,0.15255032235436972,310,QC,46.18479280074194,-74.59726172512903,16.99666850127668
299 +L9W,0.15124394191990986,223,ON,43.92403650174888,-80.14036480224216,16.843926134192454
300 +J4K,0.14984323740544703,81,QC,45.520879472345676,-73.51744505432099,16.68037688819226
301 +L1V,0.14752529032366832,112,ON,43.833086972589285,-79.10519722794642,16.410231161787546
302 +L0L,0.14365955923849202,277,ON,44.47351584458483,-79.71052313790614,15.961089202895629
303 +J4Y,0.14301353045569296,138,QC,45.43730300688406,-73.45070323681159,15.886199194740879
304 +V9K,0.1418770063886397,106,BC,49.34103003575472,-124.49989882075472,15.75456655631653
305 +J3E,0.1418520196957813,66,QC,45.59116374333334,-73.3089478730303,15.751674268649518
306 +H4W,0.1418011948991263,120,QC,45.472802090916666,-73.66415563333334,15.745791362842354
307 +V9V,0.14118842752226812,67,BC,49.22770787626866,-124.01844621567164,15.674887843786856
308 +L1X,0.13876001816714295,99,ON,43.87296507060606,-79.09863644959596,15.394322665424287
309 +M9V,0.13645529271970827,74,ON,43.74569663621621,-79.58294284554054,15.12867667161606
310 +H8S,0.13541255950206796,64,QC,45.438862841562496,-73.67310251359375,15.008690743675611
311 +J4X,0.13525578348921702,84,QC,45.445137734642856,-73.48965533154762,14.990661553006834
312 +N1E,0.13483561946977318,231,ON,43.56429529991342,-80.24257606437229,14.942356763128206
313 +L1C,0.13457043151167042,135,ON,43.915537442592594,-78.6954826154074,14.911879475522106
314 +L9B,0.13371098404397702,130,ON,43.20781327438462,-79.906366351,14.813161179370326
315 +L9N,0.13364629512088105,95,ON,44.097551243894735,-79.48612865515788,14.805734279838045
316 +L8E,0.13103330118126424,276,ON,43.23032534894927,-79.70976097423913,14.50613918248147
317 +H9H,0.13045674057421894,81,QC,45.485777092469135,-73.83807338049382,14.440138481894337
318 +V0M,0.12830414386290764,168,BC,49.2799258399177,-121.87038038850376,14.19405996507981
319 +P0G,0.12437863620080056,56,QC,45.48389126964286,-80.18177038249999,13.746669000559253
320 +N1G,0.12355630283818339,142,ON,43.51916822739437,-80.22523459260563,13.653169768791296
321 +J7J,0.12278474793832232,71,QC,45.669819523802815,-73.91754450943662,13.565513928766325
322 +L6W,0.12083743217339349,68,ON,43.682876894705885,-79.74447497970588,13.344581195852934
323 +H7R,0.12000491668916723,52,QC,45.55126828365384,-73.85937917384615,13.2502593446028
324 +K1N,0.11951938683894593,179,QC,45.428573260893856,-75.68628930670391,13.195286309750331
325 +T3B,0.11794579973353975,166,BC,51.09102969589759,-114.1887421325,13.017303739085984
326 +H1N,0.11781419332702744,71,QC,45.63860454507043,-73.30701558352114,13.00243091656801
327 +L9K,0.11746100930095775,89,ON,43.22972317078652,-79.94180702674157,12.96252731013421
328 +V7Z,0.11740793101176632,161,BC,49.48020777018633,-123.78973111801243,12.956531611563982
329 +V1Z,0.11679450175265556,206,BC,49.9142771546602,-119.54923195999999,12.887262018235578
330 +J5R,0.11659463470734929,195,QC,45.39404981748718,-73.49770819610256,12.864701829317537
331 +L1B,0.11598766581075311,61,ON,43.904745081967214,-78.59676506721311,12.796217251890262
332 +T3Z,0.11423443805273754,57,BC,51.07982419124561,-114.37972288145613,12.59863304847142
333 +H7W,0.11334625481731486,92,QC,45.53145113597826,-73.75233587967391,12.498669229931657
334 +N4L,0.10998490126734649,76,ON,44.59777284894737,-80.6061725331579,12.121156261477605
335 +L6P,0.1096399753787446,168,ON,43.77936111619048,-79.70181926464286,12.0824894410001
336 +K7L,0.1083810592633451,104,ON,44.24980467307692,-76.48424197211538,11.94147576960447
337 +H7P,0.1076023528178804,68,QC,45.57778821426471,-73.7929977160294,11.854340151844568
338 +P1H,0.10635134923772295,248,QC,45.3442503408871,-79.16595985427419,11.714497461949257
339 +N1H,0.1058915280542202,175,ON,43.550857119514426,-80.25948843673834,11.663140577908383
340 +N3C,0.10481753867555801,83,ON,43.42923438530121,-80.30735017566265,11.543279926993776
341 +L3Z,0.10416413249770225,142,ON,44.10803914197183,-79.57151869929577,11.470420664729431
342 +L1S,0.1041092393190939,77,ON,43.83910035454546,-79.01866184935065,11.464301866959993
343 +V9Z,0.10151064198388882,193,BC,48.3795976538342,-123.7358888427461,11.1750270463294
344 +L6V,0.10124486716926005,126,ON,43.71161605730158,-79.77140255039681,11.1454834502706
345 +L6Y,0.09930456309204876,239,ON,43.65304793025105,-79.75833926945607,10.930036499459472
346 +L7A,0.09836530196643618,229,ON,43.69588395563319,-79.83145152152838,10.825893145071252
347 +L1P,0.09691220620511941,54,ON,43.90063765185185,-78.97610719259258,10.664969456578532
348 +L0R,0.09667170982854911,380,ON,43.17768153526316,-79.73874219378948,10.638358132502734
349 +V0R,0.09473135947576897,437,SK,49.06612451256293,-124.17702642073226,10.423889095094442
350 +V1V,0.09396983746497818,318,BC,49.92333347330189,-119.47242695264151,10.339830883182909
351 +J7C,0.09096981071475317,85,QC,45.674720692,-73.85670615941176,10.009304480841585
352 +L1R,0.09044116900649772,60,ON,43.91527840183333,-78.9355045855,9.951164343201668
353 +L8J,0.087040057133147,94,ON,43.190589089999996,-79.77384639712766,9.577843345771475
354 +L6X,0.08685422748757747,163,ON,43.67325457944786,-79.79315870331288,9.557482425870113
355 +N2L,0.08483462002296623,340,ON,43.469219171823525,-80.53441638308823,9.336442598533147
356 +L6Z,0.0836260141328074,65,ON,43.727775798461536,-79.79614451523078,9.204377753250403
357 +V2V,0.08159156866701436,287,BC,49.14825194761137,-122.30213873650396,8.982433245635901
358 +L0S,0.08143871544415182,568,ON,43.03739442007043,-79.13348632630282,8.9657762025527
359 +V3G,0.08138127353823263,133,BC,49.0617366123704,-122.23524791544733,8.959517180454446
360 +L6T,0.0812849479458038,132,ON,43.712688483560605,-79.71501677265152,8.949022095892012
361 +V9N,0.0809784189641955,211,BC,49.68736416042654,-124.98150034459717,8.915631181004757
362 +V1P,0.07994855961265046,146,BC,49.820497558150684,-119.1847251269178,8.803521138400217
363 +L6S,0.07954872358591139,148,ON,43.72892907324324,-79.74147481925677,8.760026266800814
364 +K4M,0.07423064000854183,78,QC,45.23120148974359,-75.6854476648718,8.183166610730797
365 +L1Z,0.07005195471226247,54,ON,43.87696430925926,-79.01385894444445,7.73204640422922
366 +T2P,0.06913614646421633,142,AB,51.089312576154924,-114.04637674989436,7.633429671454506
367 +L1L,0.06882541657471,97,ON,44.00525680927835,-79.35818542134021,7.599989943376073
368 +L4P,0.06820815644115981,145,ON,44.23179672068965,-79.46308373696552,7.533593253336646
369 +L0A,0.06797473134060196,70,ON,44.14305905,-78.49365753714285,7.508495142896576
370 +N2K,0.06738267234246235,80,ON,43.5008907105,-80.501320989875,7.44486260993642
371 +L9S,0.06546019865641509,265,ON,44.350557079132074,-79.55886513750943,7.2385011146977485
372 +V2R,0.06445101716660498,484,BC,49.11622883219008,-121.96896889028926,7.130332594392397
373 +G1K,0.06316759380875454,55,QC,46.81410239781819,-71.21762357163637,6.992927216702971
374 +J1X,0.06308628415435895,189,QC,45.26396233380953,-72.1679159478836,6.984228012437632
375 +K4P,0.06114177960845631,53,QC,45.25093009056604,-75.57615913018867,6.77639882261496
376 +L1H,0.061047385400046714,90,ON,43.90765315955555,-78.85127471088889,6.7663202246593945
377 +N1S,0.06070175594894115,133,ON,43.35720466518797,-80.33013079112781,6.729425016406165
378 +V2S,0.05977519158049158,472,BC,49.05290787267465,-122.27883282912707,6.630579134728598
379 +L8R,0.05927363782669111,63,ON,43.25899366063492,-79.86772430587301,6.577111577041639
380 +N3W,0.058094039857484306,103,ON,43.08615220718446,-79.95115340291262,6.4514675519488085
381 +V9H,0.056957101221968336,71,BC,49.95499467873239,-125.23089622943664,6.330507540766361
382 +T3E,0.05519466365407862,180,BC,51.02094003887222,-114.13436668295,6.143271703866016
383 +J3L,0.05242560464462071,83,QC,45.450346099156626,-73.29606788987952,5.849761282444987
384 +V1L,0.05225756743466979,116,BC,49.53047789172413,-117.24065378534483,5.831976078215018
385 +P2A,0.05212398621782855,114,ON,45.34847275052632,-79.9544787359649,5.817839858257523
386 +L6R,0.05158144020894757,152,ON,43.7481342406579,-79.76458317111842,5.76044438282497
387 +T2J,0.05152037687036497,105,AB,50.946966696733334,-114.04238945461904,5.753986494173113
388 +T3H,0.049421405822747726,333,BC,51.04475090209009,-114.19409437124023,5.532244734528757
389 +H7V,0.04801973795276921,54,QC,45.54451400981481,-73.73801037277778,5.384427197584829
390 +N2G,0.04710295558928515,223,ON,43.44972541690583,-80.49608713085202,5.287856887086839
391 +L0E,0.044443898205236754,172,ON,44.36828162587209,-79.3480987483721,5.008262327511104
392 +L1E,0.04372928439434354,56,ON,43.905460348214284,-78.79403846071429,4.93324877904513
393 +V1B,0.0414788525943809,170,BC,50.26711615129412,-119.21577168017647,4.697369174151178
394 +V9T,0.0412436545349835,217,BC,49.21972360341014,-124.00877634557604,4.672747451701587
395 +L9C,0.04028594028853549,138,ON,43.22865918514493,-79.9049214102174,4.572548858720871
396 +H1L,0.03835347372125123,76,QC,45.60282324578947,-73.51671064736843,4.3706610377558075
397 +V9G,0.03780152114724084,118,BC,48.98843013449152,-123.8094584461017,4.313069278166948
398 +V2T,0.035280366498354025,371,BC,49.061333793978804,-122.3374954819645,4.050411138637489
399 +L9A,0.032059228120771055,93,ON,43.230498331182794,-79.87018009010752,3.7157895866057444
400 +L8P,0.03177048648837888,185,ON,43.25269047291892,-79.87207854156757,3.6858468432819924
401 +L9J,0.03148302007194451,86,ON,44.33197742732558,-79.65344772069767,3.656044928185076
402 +P0B,0.031096325328504,148,QC,45.18178659256757,-79.33909377648648,3.6159694294772393
403 +K9A,0.029675966870087885,172,ON,43.97218776046512,-78.17118944215116,3.46890207977284
404 +N9H,0.029408506698370133,52,ON,42.23368632788462,-83.0283619396154,3.441231969946257
405 +J3Y,0.028012827660904887,127,QC,45.4884242543307,-73.40272128346457,3.296961911643148
406 +L3V,0.025600408366766414,259,ON,44.615391754787645,-79.41481792880309,3.0480666682546564
407 +L8N,0.02490641230902063,115,ON,43.266314594608694,-79.87640939313044,2.976576526036312
408 +L0K,0.022717821982345086,393,ON,44.67388622412214,-79.4995409778626,2.751449432129127
409 +L9X,0.02168671457020108,76,ON,44.42492145473684,-79.76359958578946,2.645556254013526
410 +L8S,0.019626413015020595,98,ON,43.255361169489795,-79.92338614204083,2.434293162400647
411 +L4N,0.018362260530559164,443,ON,44.36614929,-79.69143380963882,2.3048824109009436
412 +K0M,0.017815426976036997,630,QC,44.72031158911111,-78.66953249409524,2.2489539615772713
413 +K1L,0.017459535488465603,77,QC,45.429657666233766,-75.69417856233767,2.212570903843547
414 +V4T,0.016342248987467972,303,BC,49.83898614834983,-119.62138801613861,2.0984339518516526
415 +T2G,0.016066647103622763,175,AB,51.04185611505714,-114.04932871784,2.0702993082753585
416 +M3N,0.012415298564842163,78,ON,43.75969713846154,-79.5147439974359,1.6982846609315816
417 +T2T,0.012174381488590583,179,BC,51.03527700482681,-114.1033319393687,1.6737867586312571
418 +T2S,0.010169038915281562,83,AB,51.03134312391566,-114.06967831022892,1.4701002842926414
419 +T2C,0.008909831064345059,63,AB,50.97791365350794,-114.01982215649207,1.342408749343349
420 +J4W,0.007904388093398763,57,QC,45.46804607070175,-73.48594258982456,1.24056594395352
421 +L1G,0.006771120953080574,113,ON,43.91715984070797,-78.86290392743362,1.1258983240970855
422 +T2K,0.00669084297919897,94,AB,51.08990296297872,-114.03468307115958,1.1177804677195535
423 +N3A,0.0063866080623870836,65,ON,43.388550998153846,-80.69892163446154,1.087021587390713
424 +V9R,0.005430083858730188,179,BC,49.1598357326257,-123.9549141860894,0.9903756340323255
425 +L2N,0.004555185596724837,143,ON,43.19328054608392,-79.25154262377623,0.9020579700297571
426 +N3L,0.0028100053025440198,142,ON,43.193817748873236,-80.37609570323944,0.7261192538624339
427 +V4Z,0.002376277008197647,56,BC,49.13533029107143,-121.83477772375,0.682440958903241
428 +L9R,0.002290846823019154,152,ON,44.17238007480263,-79.82964322625,0.6738400067235917
429 +V9S,0.002135385926167295,104,BC,49.17739737269231,-123.9608011451923,0.6581903777508336
430 +L1K,0.0009589457157231866,107,ON,43.93721370897197,-78.84509529841122,0.5398416638225267
431 +L2T,0.0009474255803954889,70,ON,43.13641252942857,-79.23093479585714,0.538683437912213
432 +L9M,-0.0007129460589529039,155,ON,44.777720782516134,-79.99173975354839,0.3718903668352924
433 +L0M,-0.0017027586656147857,171,ON,44.35767363011696,-80.04025075491228,0.27259015680285437
434 +N2P,-0.004167925338504795,132,ON,43.38946819090909,-80.42802763848485,0.025705939743159156
435 +J7V,-0.004252810064427266,188,QC,45.39879618202127,-74.02428400989362,0.01721564546250942
436 +L8W,-0.00442495170183056,102,ON,43.202362101176476,-79.84451420960784,0.0
437 +N2V,-0.006857586294052585,83,ON,43.47464735530121,-80.58455511361446,-0.2429678134505453
438 +J2W,-0.009389800444562474,57,QC,45.35475680017544,-73.29383549403508,-0.49525442529453345
439 +J0R,-0.010341835865715422,157,QC,45.8826938212102,-74.14700997923566,-0.5899413878315385
440 +L1J,-0.010625081381041838,92,ON,43.8850832026087,-78.87201904434782,-0.6180948537520603
441 +K1G,-0.012340713240247162,76,QC,45.39126694078947,-75.63062015657894,-0.7884514400705034
442 +N1R,-0.013026986566615077,203,ON,43.36206823640394,-80.30770722334975,-0.8565143219733562
443 +V1H,-0.01323749733898689,248,BC,50.23016935092742,-119.36660286112904,-0.8773828971120667
444 +L1A,-0.013476679155038924,70,ON,43.95435924342857,-78.33330382114286,-0.9010883896081845
445 +L9V,-0.014322756974816645,106,ON,44.114992899339626,-80.1780948931132,-0.9848983208243123
446 +N1M,-0.014794806064163075,113,ON,43.70789140911504,-80.38913877318583,-1.03162727935463
447 +L8V,-0.01611474763745385,82,ON,43.23082543378049,-79.84865088390244,-1.1621735732556315
448 +L8G,-0.01632261170713421,115,ON,43.21631983095652,-79.76012484382608,-1.1827162709767136
449 +N2Z,-0.01652169298911701,94,ON,44.14978056021277,-81.6611459730851,-1.2023869844031476
450 +L4M,-0.017917328635821343,225,ON,44.4151304892,-79.67037419293332,-1.340176280744676
451 +J0P,-0.01904399238114042,155,QC,45.34918655290323,-74.25366221458064,-1.4512701327894062
452 +L2H,-0.020531384658484718,180,ON,43.09176563638889,-79.13382590288889,-1.5977417951225759
453 +H1E,-0.021280302797521914,61,QC,45.639319499016395,-73.59184662836066,-1.6714094422526138
454 +L2S,-0.021745649083668637,99,ON,43.145723185858586,-79.26472465969697,-1.7171556419531275
455 +N2J,-0.02203194874493764,138,ON,43.471584916666664,-80.51553577275362,-1.7452899593864313
456 +N6K,-0.023465443135621142,166,ON,42.9553523,-81.33914045801205,-1.8860366312038468
457 +V9X,-0.02394243758048996,59,BC,49.10567828254237,-123.88313378559322,-1.9328252868432871
458 +V9W,-0.02422636746183485,199,BC,49.99335749145729,-125.23855869517587,-1.960665535597128
459 +T2E,-0.0252271166638331,190,BC,51.062121287763155,-114.0495289422737,-2.058729244553348
460 +V0E,-0.026497960331198393,700,BC,50.898603938257146,-119.29765466632858,-2.1831182320469544
461 +L4R,-0.027736353747338186,93,ON,44.741758260107524,-79.87705481580645,-2.3041790384911387
462 +N2H,-0.027983024799252982,147,ON,43.45354730836734,-80.4863982244898,-2.3282747974301077
463 +T3L,-0.028534251000418807,92,BC,51.120225515065215,-114.23180294525001,-2.3820991754082477
464 +N0H,-0.028642027019075946,670,ON,44.66555842619403,-81.1174007480597,-2.392619477180491
465 +N5A,-0.02911945229657203,152,ON,43.3782347431579,-80.97541295197368,-2.439208585618313
466 +J7W,-0.029239756574232705,71,QC,45.37554612774648,-73.96327079619718,-2.450944860181248
467 +K2B,-0.03029024888426245,83,QC,45.36093364722892,-75.7876555366265,-2.5533655869446448
468 +V2P,-0.033818421487415574,354,BC,49.169235317655364,-121.94796330166668,-2.8965683374637785
469 +P1L,-0.033952278845074825,142,QC,45.04683863676056,-79.30050257021126,-2.909565476345022
470 +J9B,-0.034943948081325976,59,QC,45.53487765661017,-75.82994977644067,-3.005799349424254
471 +N2R,-0.03566579223464935,95,ON,43.38452937810526,-80.47648910189474,-3.0757887822996377
472 +N3H,-0.036626202242266745,76,ON,43.397080284210524,-80.3627992011842,-3.168831078205725
473 +J7K,-0.03667678208838341,97,QC,45.73135646350516,-73.6164832056701,-3.1737286599685777
474 +K2C,-0.037264829385532154,90,QC,45.356755594444444,-75.73311679333334,-3.230650349160036
475 +V1X,-0.03773560096276031,249,BC,49.88835567522089,-119.40594159975903,-3.276195886909017
476 +N2A,-0.03794760361445887,164,ON,43.44052803140244,-80.42939044335367,-3.2966994163852625
477 +V2A,-0.039588351411470046,375,BC,49.478745628186665,-119.59137499122667,-3.4552350497204287
478 +N1A,-0.03980819747000027,115,QC,42.915351391130436,-79.59609689486958,-3.4764577028226884
479 +K7G,-0.04294706267020064,86,ON,44.32062370465116,-76.22611226627906,-3.778957089975732
480 +J0E,-0.04359591507859753,169,QC,45.256827643786984,-72.51327230159764,-3.84137009480241
481 +N2E,-0.04415952986410713,165,ON,43.412239487878786,-80.50482639951515,-3.8955512502868883
482 +J0L,-0.047799961026705196,142,QC,45.50281547225352,-73.38125935084507,-4.244776828857278
483 +N2C,-0.04810734500002365,53,ON,43.423936110943394,-80.45844726301887,-4.274205926573405
484 +N0E,-0.0482354121242402,265,ON,42.81847826516981,-80.3967485586415,-4.2864644687588545
485 +N3T,-0.049448935860125845,221,ON,43.12832690570136,-80.28644899339366,-4.402544668687258
486 +P0A,-0.049684352512766164,248,QC,45.600351127338705,-79.37440322991935,-4.425047252776848
487 +V9L,-0.05026608838261139,209,BC,48.79673454985646,-123.69628812631579,-4.480630462107826
488 +K1K,-0.051491648217426904,118,QC,45.440794961864405,-75.64409064491525,-4.597623459257649
489 +V2H,-0.053009524852259876,50,BC,50.712199501200004,-120.219862567,-4.742322651972897
490 +T1S,-0.053053498916681534,193,AB,50.73936428580311,-113.97767873340415,-4.746511427113842
491 +ON_other,-0.0536761395850286,684,ON,43.97643260476321,-81.5292601108632,-4.805801662729814
492 +T3C,-0.05642365757709076,133,BC,51.043106818428576,-114.11852290539849,-5.066990460634269
493 +N6P,-0.0564465453130445,142,ON,42.922160668309864,-81.30056109366197,-5.069163237424834
494 +K2S,-0.05716647046855107,142,QC,45.2632119915493,-75.91135835985915,-5.13748173978853
495 +J6A,-0.05817651777623383,57,QC,45.7380557854386,-73.45582268017543,-5.2332489980847825
496 +V0H,-0.058784165840915684,849,BC,49.31001310598351,-119.39933548908127,-5.290816338814364
497 +L2J,-0.05946250029738477,75,ON,43.12737035826667,-79.1056206624,-5.3550390567319806
498 +N5L,-0.05953106311318588,62,ON,42.672857961612905,-81.21872409983871,-5.361527959304368
499 +J8B,-0.06277391719258225,63,QC,45.95271738031746,-74.19538946809524,-5.667929637950042
500 +N0A,-0.0637103972684044,348,ON,42.85369584227011,-80.00877328399424,-5.756228390890605
501 +J7N,-0.0657845971497136,60,QC,45.68818441733333,-74.04742859633333,-5.951506218141233
502 +K2G,-0.06638589175480131,118,QC,45.32112633220339,-75.73968497627119,-6.008040071614995
503 +T6G,-0.06735616995533211,85,AB,53.521995021882354,-113.52217228999999,-6.099194191779489
504 +N6G,-0.06794909712641677,346,ON,43.01457084965318,-81.30885259725433,-6.154854028184598
505 +L8H,-0.06836472367624476,212,ON,43.249103854150945,-79.79440873896228,-6.19385045788583
506 +N6A,-0.06878098636684289,69,ON,42.99502053405797,-81.25506155231884,-6.232890332103624
507 +L8K,-0.07419492115796883,161,ON,43.22433335677019,-79.79639729229814,-6.739167636630672
508 +K9J,-0.07725481629271908,164,ON,44.29660480060976,-78.34030950914634,-7.024099850177789
509 +K0L,-0.07779960969583147,651,QC,44.64028227691221,-78.0389360588052,-7.0747387121164245
510 +N0R,-0.08069919723233535,62,ON,42.1817883416129,-82.8326099501613,-7.343793379284536
511 +T3A,-0.08072327993616953,155,BC,51.112874849587094,-114.14530373469677,-7.346024764397985
512 +N1T,-0.0821428177406394,59,ON,43.3885720081356,-80.28538220050848,-7.4774572761990505
513 +N2T,-0.0822941830143237,55,ON,43.45487761618182,-80.56768615909091,-7.491460916341253
514 +K7H,-0.08399426224876054,98,ON,44.89056791020408,-76.25965309591837,-7.648599151072921
515 +V1S,-0.08631536816542082,123,BC,50.65291599463415,-120.44123575430895,-7.862707953264936
516 +N0J,-0.08641524836462472,161,ON,42.9666729,-80.67902310347826,-7.871910184780662
517 +N3R,-0.08814477898215824,133,ON,43.165602426315786,-80.26691915759399,-8.031110825974896
518 +T3M,-0.0888909391596048,428,BC,50.886853350981305,-113.94985476746496,-8.099708752937197
519 +L2M,-0.08936850252161865,131,ON,43.19091561618321,-79.21873946549618,-8.143586486962185
520 +J0N,-0.09054372332167654,69,QC,45.5494614284058,-73.98656197521738,-8.25147464611964
521 +L9Z,-0.09219900519996498,269,ON,44.49517134635688,-80.03543523791822,-8.403218693264225
522 +K7K,-0.09253021284299219,99,ON,44.24960937777777,-76.48077874444445,-8.433551223849435
523 +T5J,-0.09286809251955777,132,AB,53.50722204999243,-113.51211324997728,-8.464484439799403
524 +H1A,-0.09361665700264642,78,QC,45.6763038924359,-73.49814576371796,-8.5329790361795
525 +K2K,-0.09370179912062526,57,QC,45.34002822719298,-75.90601469,-8.540766400548527
526 +V4Y,-0.094259924718046,53,BC,50.49616109415095,-119.17137182981132,-8.591797897623755
527 +K1V,-0.09596508736061035,144,QC,45.344846499305554,-75.67010186944444,-8.747530936258997
528 +V2C,-0.09657053148991392,173,BC,50.671482222080925,-120.27492817618499,-8.80276248644204
529 +J8X,-0.09669632863703015,56,QC,45.43907190696429,-75.70541064946428,-8.814234117181785
530 +K9H,-0.0995284661974331,95,ON,44.32140996105263,-78.32272694842105,-9.072119394048329
531 +N2N,-0.10016087787095723,64,ON,43.42809295953125,-80.54164111375,-9.129605067970791
532 +T2R,-0.10053343901852944,175,BC,51.04224406318286,-114.07805922938859,-9.163453540882527
533 +J5Z,-0.1019374589650587,62,QC,45.75228943532258,-73.47918886193548,-9.290900374100952
534 +J5Y,-0.1037454154596442,62,QC,45.77274464854839,-73.4220271016129,-9.454750318470618
535 +V0X,-0.10879286454731378,258,BC,49.343928061550386,-120.84517905930232,-9.910621395500463
536 +N7A,-0.10955318730759264,82,ON,43.77818807841464,-81.71039511365854,-9.979092367195207
537 +N0C,-0.11229629944563654,145,QC,44.261915983448276,-80.49218534731034,-10.225691432524576
538 +N2M,-0.11281656290162427,125,ON,43.4365857704,-80.51066402056,-10.272385576877097
539 +J9J,-0.11333671325479558,205,QC,45.42411272809756,-75.8202948869756,-10.319045291123075
540 +N4X,-0.11382560262680605,56,ON,43.26144080285714,-81.14235964982143,-10.362878641049477
541 +T4C,-0.11662576561423417,267,BC,51.19104134085768,-114.48006859438202,-10.6135260999344
542 +K4A,-0.1170315812869165,154,QC,45.46647758246753,-75.47618535584415,-10.649793172597889
543 +T2W,-0.11898268001321294,106,BC,50.946770699132074,-114.09871725133962,-10.82395428931714
544 +N6H,-0.11924063690148597,108,ON,42.97997429722222,-81.30905698805556,-10.846954897866912
545 +T2V,-0.12039966229962192,126,BC,50.98247552287301,-114.08486332539682,-10.950225683169279
546 +N0M,-0.12186042111608338,446,ON,43.25123665311659,-81.55955899966368,-11.080210964419967
547 +N0L,-0.12359650971997675,291,ON,42.81714113254296,-81.43224214075602,-11.23444967205427
548 +T4S,-0.12468210501736597,141,BC,52.30142235089362,-114.07134656192198,-11.330760849121301
549 +V1E,-0.12492703476031769,181,BC,50.69203729475138,-119.27570478651934,-11.35247592363189
550 +N5X,-0.12736681417426116,134,ON,43.03566094470149,-81.25201826664178,-11.56849270416962
551 +L2P,-0.12765429751872276,90,ON,43.155465055,-79.21607653588889,-11.59391163570801
552 +T3G,-0.129239320699817,197,BC,51.13917428569035,-114.2030954104467,-11.73392634252406
553 +K0A,-0.1304699454572893,661,QC,45.308073349621786,-75.64156954795764,-11.842481948703497
554 +L2G,-0.1349681765143164,154,ON,43.071450003831174,-79.08829508045454,-12.23814427687081
555 +G3N,-0.13797905361243953,50,QC,46.8604562884,-71.6037735276,-12.501987039970341
556 +K2M,-0.13853633173318425,50,QC,45.284702838,-75.85338759999999,-12.550734184081602
557 +J0J,-0.13951777735908857,59,QC,45.12998289186441,-73.20860397288136,-12.636518780160987
558 +K1C,-0.1418891592095005,107,QC,45.466917899252344,-75.53161265093458,-12.84344550580354
559 +N4S,-0.14318921376083146,137,ON,43.1273468849635,-80.75039276416058,-12.956680159589984
560 +J9A,-0.1441607554112892,109,QC,45.43871744880734,-75.76881452467889,-13.041205303711479
561 +V0B,-0.14429424979057293,379,BC,49.53745346570712,-115.96558055134037,-13.052813039231758
562 +S7T,-0.1453494197232688,51,SK,52.07849445098039,-106.62304235294118,-13.144508710879709
563 +J8Z,-0.14657345292187643,58,QC,45.470742276034485,-75.76220811758621,-13.250757676302783
564 +L2V,-0.14822360348827623,132,ON,43.10173325136364,-79.2118617298485,-13.393788943638441
565 +V1A,-0.14828799112564953,60,BC,49.66129267016667,-116.11226016966665,-13.399365133429441
566 +K4K,-0.14847235480462315,130,QC,45.54547568307692,-75.27687764076923,-13.41532967338901
567 +K2J,-0.14885456823376722,219,QC,45.26246168082192,-75.74210132922374,-13.448417173499616
568 +T2Y,-0.14943603312599174,242,BC,50.91409439144628,-114.10573004583472,-13.498729251508623
569 +K7C,-0.1494903258546555,115,QC,45.12517176782609,-76.1401131226087,-13.503425514042833
570 +T3R,-0.14981331306066356,212,BC,51.176205910367926,-114.15519126550943,-13.5313582897579
571 +L3C,-0.15042263383294033,180,ON,43.00941052244444,-79.2677785815,-13.584029380877949
572 +V2E,-0.15049264422967923,96,BC,50.65609850531251,-120.32967717645833,-13.590079185488479
573 +K0G,-0.15446681432312334,271,QC,44.85958675608856,-76.0534657107011,-13.932805431282713
574 +S7V,-0.15637524724723728,136,SK,52.111332816176464,-106.55482377941178,-14.096902265378331
575 +K7P,-0.1565198685826757,111,ON,44.2642552018018,-76.5895731882883,-14.109324787788468
576 +K1J,-0.1572790127426706,93,QC,45.44147644408602,-75.60722332365592,-14.174503449143572
577 +K7M,-0.157675153955466,162,ON,44.23766259814815,-76.55549595740742,-14.208495732119363
578 +J9H,-0.15811826606103344,146,QC,45.398076996712334,-75.82984558938355,-14.246502564949559
579 +N0N,-0.15912583604203198,101,ON,43.31897140832758,-84.11388968963736,-14.332861700988264
580 +V0G,-0.16157390121620455,223,BC,49.6145897903139,-117.59159587112109,-14.542323945606594
581 +NS_other,-0.16308157998377829,257,NS,44.670621341322956,-63.57441999957199,-14.671069591394115
582 +V0A,-0.16329872416497282,216,BC,50.714463405833335,-116.29578651166666,-14.689596260567894
583 +T2X,-0.16350240689189294,308,AB,50.873968733237014,-114.03810157447401,-14.706970746734772
584 +L8M,-0.1636532283473464,60,ON,43.249101201500004,-79.83506483133333,-14.719833795510539
585 +N0K,-0.164910987607,100,ON,43.520550788,-81.1330954651,-14.827028287655054
586 +T3S,-0.16640451194915337,68,AB,50.89733853780882,-113.90858358629411,-14.954141247422836
587 +N6M,-0.1667254121943166,88,ON,42.959287870454546,-81.16822283977272,-14.981428105932704
588 +J8V,-0.16726136800665903,145,QC,45.53350748572414,-75.72872859531034,-15.026982095143293
589 +T7Y,-0.16982340324007417,51,AB,53.49568616568627,-114.00289912196078,-15.244407316434327
590 +T1X,-0.1700661417664844,280,AB,51.033251305803574,-113.83611824495357,-15.264978267325201
591 +N5P,-0.17062057211172296,92,ON,42.79119512054348,-81.19517504934782,-15.311944913608189
592 +K9V,-0.173518903318219,160,ON,44.361686321875,-78.7387511219375,-15.557043586340946
593 +K0K,-0.1740962990857937,958,ON,44.17536760449896,-77.4878504154071,-15.605786518640109
594 +K2H,-0.1742431777305529,75,QC,45.33028508133333,-75.81309203333333,-15.618181316053958
595 +T1V,-0.1743027611105373,57,AB,50.58292484452632,-113.86776337435089,-15.623208920238064
596 +L3K,-0.17628427817031825,129,ON,42.88904969635659,-79.25578863782945,-15.790237431637921
597 +T3P,-0.17656659168466074,253,BC,51.17833795156522,-114.09156757443874,-15.814007630168526
598 +B4A,-0.17721145604878344,64,NS,44.719498523125,-63.67272478703125,-15.868278675993686
599 +R4A,-0.17736006231573362,64,MB,49.97712428125,-97.082911921875,-15.880780248102756
600 +J0T,-0.17743017246886064,358,QC,46.148242611284914,-74.44540547818436,-15.886677652744098
601 +L2R,-0.17758313001255682,112,ON,43.16434000366071,-79.24555078178571,-15.899542436014558
602 +N3S,-0.17776493874949895,168,ON,43.141816089880955,-80.23651459267857,-15.914831244118954
603 +N5H,-0.1781747645229553,70,ON,42.748521108571424,-80.971583648,-15.949284453051826
604 +J8R,-0.17929163441454815,122,QC,45.508486319344264,-75.6364396490164,-16.043105763761766
605 +J1N,-0.1804870587244355,70,QC,45.35772506128572,-71.993409861,-16.143409911161434
606 +N4W,-0.18574365264458,87,ON,43.735207721494255,-80.95589748678161,-16.58305342672707
607 +S7N,-0.18756519456975765,64,SK,52.130339984375,-106.61524309375,-16.73486258683029
608 +N4K,-0.18834756886167947,128,ON,44.57313645859375,-80.94117025554688,-16.799981612708148
609 +T1P,-0.18864646034403162,111,QC,50.99826015185585,-113.06265668605405,-16.82484567352255
610 +K1T,-0.18999570098607374,105,QC,45.34646260666666,-75.6276648504762,-16.936993298068227
611 +K8V,-0.19205162833411246,158,ON,44.10843447949367,-77.59376858829114,-17.107589378493294
612 +T5R,-0.19212916626729673,90,AB,53.51974478922222,-113.58348787433333,-17.114016435515968
613 +T0L,-0.19346065950097385,195,BC,50.39541854311795,-113.75713177927179,-17.22430512118539
614 +T1Y,-0.19468629044434657,117,AB,51.082419657683765,-113.95306329388035,-17.325695427947252
615 +N4G,-0.1969032614416998,154,ON,42.86819488597402,-80.73421016928572,-17.508778943001012
616 +N5C,-0.19819916534608226,65,ON,43.03590883015384,-80.88003193200001,-17.615610401842975
617 +N4T,-0.19848070112835797,77,ON,43.15392157220779,-80.74144718467532,-17.63880129073009
618 +V9Y,-0.19850428272176485,182,BC,49.25749696203297,-124.81564689582419,-17.64074347613055
619 +T4G,-0.19854316418064438,64,BC,52.02315580226563,-114.13229756289063,-17.643945661923198
620 +N6C,-0.19970487160917125,84,ON,42.96066521678571,-81.24055645678571,-17.739563751156062
621 +B4B,-0.2030366259626995,62,NS,44.727949188870966,-63.73745066274193,-18.013179254820844
622 +T2B,-0.20354566188966572,70,BC,51.06845201591428,-114.00161875937142,-18.05490287180691
623 +V8A,-0.20365025620257746,125,BC,49.8330482188,-124.51024824992,-18.063473414714682
624 +K0H,-0.20373243790222628,368,ON,44.54784385244979,-76.70812114743184,-18.070206821047606
625 +T6C,-0.20429001530078647,77,AB,53.52104868753247,-113.45856809337663,-18.115876288678223
626 +T3K,-0.2063569523182626,281,BC,51.15350566254804,-114.07426258329538,-18.28495082172147
627 +T2A,-0.2068738719285211,173,AB,51.048503691647404,-113.94861355354335,-18.327180017604906
628 +N3Y,-0.2070197345560645,167,ON,42.830615786287424,-80.31463039461077,-18.33909216093703
629 +K8N,-0.20793652584889644,169,ON,44.17634237988165,-77.36603500059171,-18.413923862441074
630 +N4N,-0.2090735600912463,69,ON,44.153381187826085,-81.01464794014493,-18.506637305539986
631 +L2A,-0.209252640130999,138,ON,42.909871753550725,-78.94049532369564,-18.52122983351665
632 +L2E,-0.20950694367231712,156,ON,43.10226510269231,-79.09245250358974,-18.541947538907657
633 +J8T,-0.21084696414142906,138,QC,45.48932907355072,-75.6714575634058,-18.651029893962356
634 +V1T,-0.2118540650331221,206,BC,50.26094373674757,-119.2783588988835,-18.73291527395382
635 +N5V,-0.21282605020520945,123,ON,43.003776806585364,-81.16931486130082,-18.81186729897163
636 +T5N,-0.21310964972900634,113,AB,53.54539032336283,-113.54715079973451,-18.83488895012465
637 +T4A,-0.21431087539381297,92,AB,51.26673251702174,-113.98727289956523,-18.932328029726463
638 +R3X,-0.21437903918187873,72,MB,49.827297,-97.05047131944444,-18.937853721009468
639 +N0G,-0.2151729441187276,553,ON,43.97892691253165,-80.97054398990959,-19.002183819761576
640 +B3M,-0.21559113873930014,62,NS,44.67639700096774,-63.6608700383871,-19.036049589031457
641 +T4H,-0.2167659872747138,51,BC,51.809858034372546,-114.0841495807255,-19.131114113449886
642 +V2B,-0.2181191682337342,204,BC,50.70316767102941,-120.36667059338237,-19.2404703439375
643 +N6E,-0.22147415335318626,113,ON,42.90482126681416,-81.30740914168142,-19.51096336044418
644 +N5W,-0.22356315974196603,101,ON,42.989466964950495,-81.1944702339604,-19.67892996946814
645 +T2Z,-0.22813357896496209,231,BC,50.92037550117316,-113.95398472974892,-20.045193305886077
646 +T4B,-0.2300839936628901,347,AB,51.2819993709539,-114.03012874095677,-20.200986356116847
647 +P0H,-0.23102893203526875,188,QC,46.25568537287234,-79.54258782340426,-20.27635589079604
648 +N9A,-0.23128195252466197,59,ON,42.31471389,-83.03816794762712,-20.296525054531312
649 +B3Z,-0.23217212230367767,69,NS,44.673411889130435,-63.87824647086956,-20.36744310997247
650 +T3J,-0.23452561250340362,362,BC,51.1217798170442,-113.94565146154143,-20.554637186076143
651 +N7G,-0.23907602884015602,94,ON,42.958166089361704,-81.62388720319149,-20.915325399757855
652 +L3B,-0.24005850917596736,150,ON,42.990502262999996,-79.24073594066667,-20.99298638097621
653 +R3Y,-0.2414054580720947,160,MB,49.791164625,-97.19153735,-21.09933315284469
654 +K0J,-0.2426751134856812,297,QC,45.61193168956229,-77.29957147575757,-21.19944624363019
655 +N4B,-0.24287997944208806,58,ON,42.837924955,-80.49536132620689,-21.215588140921817
656 +N5R,-0.2439294463430385,163,ON,42.7606403997546,-81.17169572,-21.298226402833762
657 +S7W,-0.2499567338220808,87,SK,52.16823979310345,-106.55152913793103,-21.771157938524432
658 +T0M,-0.2501311667990634,274,BC,51.751131089675184,-114.01107841151095,-21.784802438271168
659 +J8P,-0.25052822360439425,142,QC,45.495513789507044,-75.61699411866196,-21.815852150085735
660 +T3N,-0.2508951550001368,254,BC,51.16187492814961,-113.95376577783071,-21.844535105920915
661 +G1B,-0.25432785438153765,80,QC,46.913393748375,-71.211540741,-22.112359378817416
662 +N5Y,-0.2570905682917305,130,ON,43.01132548076923,-81.22519679069231,-22.32724367839497
663 +L8L,-0.2571617585049133,196,ON,43.25817463035714,-79.8444182330102,-22.332773021656095
664 +G0A,-0.2618860546473662,251,QC,47.04669310326693,-71.08397035792828,-22.698830639333735
665 +T4L,-0.2644863000720578,68,AB,52.47947012829412,-113.75273277383823,-22.899571550364005
666 +T1B,-0.2667434089531703,74,AB,49.99869036922973,-110.66034874886486,-23.073399364206317
667 +B2T,-0.26674933832128456,73,NS,44.86450270068493,-63.59958094958904,-23.073855488987004
668 +S4V,-0.26836463543086964,105,SK,50.426380095238095,-104.52712035238096,-23.198013764619297
669 +J0H,-0.2700032167638532,63,QC,45.62615276698413,-72.96024870301588,-23.323757017192925
670 +N6J,-0.2706258832278295,85,ON,42.95495317964706,-81.27103536564705,-23.37148588115845
671 +G1C,-0.2708251540678582,51,QC,46.87777760215686,-71.19809814490196,-23.386754188222348
672 +J8M,-0.2721280924790329,70,QC,45.546715387285715,-75.47510518428571,-23.486511526048915
673 +K7R,-0.27400952443937954,94,ON,44.23490647382979,-76.93860487585106,-23.630331112853643
674 +R2N,-0.2755070801142958,51,MB,49.81483982352941,-97.09690437254902,-23.744613350522147
675 +K7S,-0.2766749996089528,82,QC,45.44026800304878,-76.38341916695121,-23.833621515859406
676 +S7K,-0.2806404983952166,102,SK,52.13616694117647,-106.65187929411765,-24.135061123078174
677 +J0B,-0.281307600806928,171,QC,45.36823870298245,-71.82857520409357,-24.185653929599425
678 +B4E,-0.28152899400713144,60,NS,44.79974237333333,-63.74819542533333,-24.20243685241624
679 +T8N,-0.2860798691119654,197,AB,53.644245822131985,-113.62609420614214,-24.546598383501184
680 +T1H,-0.2877487301338265,76,AB,49.72202186397368,-112.82291102501316,-24.672414610326488
681 +T6E,-0.2878639083232192,141,AB,53.51888027510638,-113.4976996296454,-24.681090205593726
682 +J8N,-0.2883117379895408,137,QC,45.66451380350365,-75.6703680459854,-24.714812696305188
683 +N0P,-0.29144415068513596,79,ON,42.4223845378481,-82.19406837708861,-24.950268008676566
684 +T1J,-0.29179486390006043,123,AB,49.68018809100813,-112.87858156254472,-24.97658432645252
685 +N5Z,-0.2919655431262191,109,ON,42.96926638238532,-81.20588527642202,-24.989388172277128
686 +K7A,-0.29391416555933,101,ON,44.91694675742574,-76.02319007227723,-25.135413213164437
687 +T1K,-0.2954701052767596,130,AB,49.66959209143846,-112.83947596396922,-25.2518074225064
688 +T8W,-0.29812739978796704,57,AB,55.1382759208772,-118.81776772747368,-25.450171711472734
689 +K0B,-0.3037096648389852,109,QC,45.5398871293578,-74.78899778623853,-25.865169221770334
690 +K8P,-0.3083587571740355,110,ON,44.167248149090916,-77.40272639999999,-26.209028958119184
691 +B3T,-0.31016826411307313,75,NS,44.62445100986667,-63.699295172666666,-26.342433497637106
692 +T6H,-0.3109686053468414,100,AB,53.492754182549994,-113.52884051841,-26.401361101047073
693 +T8A,-0.31237966793984884,74,AB,53.52932092121621,-113.29140752783783,-26.505140150706673
694 +R3W,-0.3132830801027067,61,MB,49.910494032786886,-97.04974427868852,-26.571506318486726
695 +T4R,-0.31642910308686084,113,AB,52.24614668221239,-113.77067537485841,-26.802151050253865
696 +K0E,-0.3166220188435542,196,ON,44.67909677933673,-75.70587330392857,-26.816270706676438
697 +V1N,-0.31912393351280793,99,BC,49.3180719179798,-117.70564845454545,-26.999141293852745
698 +J8L,-0.32219492855926324,132,QC,45.601648478030306,-75.42771841962121,-27.222982685502984
699 +P1B,-0.3226159605592327,58,QC,46.327072705,-79.45718005120689,-27.253617689043764
700 +J9P,-0.32376256130197234,61,QC,48.0283209347541,-77.73347803672131,-27.336980943715172
701 +R2M,-0.3311102165101745,55,MB,49.84438450909091,-97.1110911090909,-27.86892708249408
702 +J0S,-0.3317659362069906,94,QC,45.16434777244681,-74.06699474765956,-27.916209344109276
703 +T8X,-0.33466073101606375,110,BC,55.18361406446364,-118.76795371426364,-28.12457539313361
704 +V0P,-0.3348068981260518,74,BC,50.09331618310811,-125.73371992756758,-28.13508044846207
705 +V1C,-0.3350134952829835,177,BC,49.51573370864407,-115.76521734293785,-28.149926002947055
706 +V1K,-0.3372345388024032,84,BC,50.10189925785715,-120.77951860488095,-28.309331055858966
707 +T0K,-0.33850456854632655,214,BC,49.5811402515514,-113.17127403997196,-28.40032254460062
708 +R2V,-0.33975796417098136,112,MB,49.9582585625,-97.11326158928571,-28.490009048972365
709 +T4P,-0.34026485076445834,118,AB,52.28910296960169,-113.79569321624575,-28.526247319562437
710 +K0C,-0.3402876632895529,278,QC,45.13970386151079,-74.9117643503597,-28.52787779774133
711 +AB_other,-0.34549367548754634,167,AB,53.33971860125749,-112.85711816273651,-28.898995677451666
712 +K7V,-0.34902768481720753,60,QC,45.46505088,-76.68998030333334,-29.14982381453357
713 +B0J,-0.35021232912195044,244,NS,44.560062126065574,-63.8680221977459,-29.233706376931867
714 +MB_other,-0.35244170871531905,316,MB,49.99048039556962,-97.55004429113924,-29.391295579487362
715 +V8G,-0.3537472688682483,71,BC,54.51653568943662,-128.57427450760562,-29.483419340787485
716 +R3T,-0.35440419562236913,69,MB,49.80754247826087,-97.15994439130435,-29.529728356750475
717 +R2C,-0.35483513114898824,54,MB,49.89991798148148,-96.99823859259259,-29.560089957955892
718 +T6W,-0.35643297139795715,748,BC,53.41624393383289,-113.60160719538904,-29.672551809391333
719 +K6V,-0.36182470524979066,174,ON,44.60597935402299,-75.70335219425287,-30.05071828987361
720 +T5S,-0.3622638380505652,94,AB,53.56806994067021,-113.68405186848936,-30.081428570423885
721 +T6R,-0.36629982973939323,202,AB,53.44882881371287,-113.57414020029702,-30.363050649140067
722 +K6A,-0.3663606686686149,53,QC,45.579260579433964,-74.60925065867924,-30.36728715769921
723 +T6M,-0.3668686683736232,324,AB,53.46811515964815,-113.66421756104629,-30.40265157196549
724 +T4J,-0.36722347162335006,57,AB,52.6656679124386,-113.6356559595614,-30.427340557235027
725 +R3M,-0.36986155683856786,56,MB,49.868542375,-97.1621845,-30.610637279004173
726 +T4X,-0.3801069562843314,185,AB,53.34461808345405,-113.43301640874053,-31.317929584348057
727 +T0C,-0.381815244694568,286,BC,52.809778188076926,-113.76291371336713,-31.43515821056989
728 +V0K,-0.382177144728845,392,BC,51.32351947540816,-121.26977584655613,-31.45996733968056
729 +T5P,-0.38363920403788737,71,AB,53.54041232887324,-113.59272009281689,-31.560103711978236
730 +T7X,-0.384161960234008,240,AB,53.55771771704167,-113.899984026875,-31.595871742030447
731 +B0N,-0.38513482461160076,163,NS,45.04967581233129,-63.71622660552148,-31.66238732112796
732 +J0V,-0.38536194282907654,198,QC,45.80625693353535,-74.96071547803031,-31.677906275520794
733 +T8H,-0.3863576185218103,91,AB,53.55821312362637,-113.27576578582418,-31.745899068516138
734 +J0K,-0.38644658766740014,253,QC,46.15552006525692,-73.6171113883004,-31.751971307434058
735 +R2G,-0.38657221223513194,52,MB,49.93583401923077,-97.06944544230768,-31.760544398030433
736 +R2P,-0.390656777268796,80,MB,49.9607538625,-97.16705175,-32.03870442421272
737 +T8L,-0.3913081533497673,135,AB,53.68476113185185,-113.22869478911112,-32.082958372036344
738 +R0E,-0.39611309293751934,202,MB,50.27952075247524,-96.23922542574257,-32.40851289278361
739 +T5K,-0.40227399426581,263,AB,53.54230627982509,-113.51101078396579,-32.82365723070703
740 +S7H,-0.4031824950933272,71,SK,52.11500907042254,-106.61225757746479,-32.8846592793009
741 +QC_other,-0.4082664865496549,3523,QC,46.4638677084956,-70.17726339510645,-33.22500720206782
742 +T6J,-0.40898388582033746,134,AB,53.457298902835824,-113.51917695604477,-33.27289435404314
743 +K6H,-0.41028938269430837,145,QC,45.01923576827586,-74.72070429172415,-33.35994954436947
744 +V2K,-0.41222252947060184,97,BC,53.88901506525773,-122.7872925028866,-33.48865010446327
745 +T6X,-0.4140623224324154,353,AB,53.419388071558075,-113.4506835627762,-33.6109047218052
746 +SK_other,-0.4147662546377066,123,SK,51.95476379674797,-105.94395302439024,-33.65762169933005
747 +T5L,-0.42257613182939313,69,AB,53.57890355217391,-113.5562797073913,-34.17372953376514
748 +T4N,-0.4232194832933637,87,BC,52.249740075574714,-113.81555739891954,-34.21606534137517
749 +T5E,-0.42468028999853213,99,AB,53.599494127979796,-113.49768972818181,-34.3120927983638
750 +T7Z,-0.42591297404400447,83,AB,53.525670301807224,-114.00905485891566,-34.39301534733732
751 +T8V,-0.42597480964880197,83,BC,55.177643593289154,-118.7983257912289,-34.397072069486036
752 +B4N,-0.42678392380877295,53,QC,45.07236364735849,-64.49812433264151,-34.45013085920648
753 +T1A,-0.43162774867455694,69,AB,50.048656826594204,-110.72037531453623,-34.76687519894048
754 +T5T,-0.4331708223197652,341,AB,53.52009546558651,-113.66132208032845,-34.86745709202362
755 +K8A,-0.4335653027194386,109,QC,45.81360440587156,-77.12971027954129,-34.89314553645466
756 +T1R,-0.4350414144028231,51,AB,50.56000350454902,-111.89459957015686,-34.98917962903625
757 +K6J,-0.43691155657848263,56,QC,45.027655595,-74.77072785928571,-35.11064549146855
758 +T5W,-0.4432339710682361,78,AB,53.56880679628205,-113.42045126602564,-35.51960870687751
759 +T5Z,-0.4433593540800726,187,AB,53.63351592491979,-113.46677246411765,-35.52769294571855
760 +T6T,-0.4439970165792508,273,AB,53.45183086904762,-113.38329634758242,-35.568791413294186
761 +S7L,-0.4480549732182119,87,SK,52.141231839080454,-106.70835494252873,-35.82972068603723
762 +T9V,-0.4483030460189671,82,AB,53.26814715106097,-110.03585099459755,-35.845637612591986
763 +V2N,-0.44879489254313043,164,BC,53.86110115878049,-122.77582285762195,-35.87718395412697
764 +T4V,-0.45330743241361326,89,AB,53.007390173359546,-112.843284085191,-36.16588883209695
765 +N7M,-0.45750279868256283,52,ON,42.38559699211539,-82.19635739096154,-36.43313531846609
766 +J0X,-0.4601202233856359,535,QC,45.8648612691215,-76.07448895816822,-36.59929924473323
767 +J0W,-0.4616142185771094,78,QC,46.457720865384616,-75.4674183874359,-36.693948866153
768 +T8R,-0.46163039543902973,65,AB,53.78524130584615,-113.70198205138462,-36.694972951117656
769 +T9E,-0.46479738891032846,230,AB,53.26132383026087,-113.55408685421739,-36.89514242347006
770 +R5G,-0.4721706934144657,74,MB,49.528114445945945,-96.70379945945946,-37.35872259495545
771 +T6V,-0.47327434439859434,105,AB,53.61493422590477,-113.5531794907619,-37.42781856647862
772 +V8C,-0.4744409940688403,50,BC,54.0647002556,-128.63767870060002,-37.50077581526449
773 +T0J,-0.48341571103066316,181,AB,51.10547730555248,-112.52602027353039,-38.05917915860739
774 +T6K,-0.48370825312876964,78,AB,53.459103021794874,-113.45266045141024,-38.077296806078266
775 +T6L,-0.48604857139246077,139,AB,53.461955785323745,-113.4143033605036,-38.22204619341559
776 +T5Y,-0.49364923428273016,286,AB,53.6202222893007,-113.40194535482517,-38.68981964824032
777 +V1R,-0.49528802976967656,65,BC,49.09961684584616,-117.7022121173846,-38.79021221119683
778 +S7M,-0.49995221391750566,74,SK,52.1211585,-106.70171112162163,-39.075041169375744
779 +T5X,-0.5015680409238987,118,AB,53.621857290067794,-113.51862434630509,-39.17340587164478
780 +T5B,-0.5043719964784126,64,AB,53.5715747825,-113.4625019915625,-39.343722047032315
781 +B0P,-0.5073202183336167,148,NS,45.03814467486487,-64.6585403372973,-39.52228685766934
782 +E4P,-0.5079804777658609,124,QC,46.21517185483871,-64.49273066129032,-39.56220465870963
783 +G0S,-0.5087340030279566,83,QC,46.53187009807229,-71.45519242759036,-39.6077289102938
784 +R3L,-0.50966617642089,56,MB,49.873883178571425,-97.14393655357142,-39.66399874784513
785 +T9K,-0.5139016879523036,174,AB,56.75448963606322,-111.45476833615518,-39.9190121395918
786 +B4V,-0.5170985380535943,63,NS,44.364046670476185,-64.55827906777778,-40.11077536925297
787 +V2L,-0.5193289042651899,55,BC,53.88655265818181,-122.6873628150909,-40.244201422516554
788 +G0X,-0.5200588745526659,51,QC,46.6990780672549,-72.46975772039215,-40.28780546321923
789 +B6L,-0.5201111574197546,53,QC,45.401810198490566,-63.26173380792453,-40.29092730633961
790 +T0E,-0.5213636154367327,248,BC,53.69145252339113,-114.92236381347985,-40.36566360131562
791 +T7S,-0.5290117551655052,55,BC,54.12469462552727,-115.66316142669092,-40.82001565000968
792 +T5G,-0.5298817948761049,60,AB,53.56732104916667,-113.4959096605,-40.871482194251655
793 +T5H,-0.5336886140787133,123,AB,53.53062432992683,-113.50340605660163,-41.096145872936894
794 +E1G,-0.5339402048865451,93,QC,46.12472595698925,-64.8750412795699,-41.11096367709132
795 +S4S,-0.5343442142853249,86,SK,50.419425686046516,-104.62191862790696,-41.13475059585793
796 +V2G,-0.535003312300852,73,BC,52.13422734835616,-122.13884477534246,-41.17353578190007
797 +R0A,-0.5353661780859855,148,MB,49.45332109459459,-96.76132632432432,-41.194878020606915
798 +T9M,-0.5437661612036789,127,AB,54.43979339935433,-110.22535701578741,-41.686771212895316
799 +V2M,-0.5541517921824362,87,BC,53.862374266436774,-122.80571560436782,-42.2892568759756
800 +T9H,-0.5627010177336855,107,AB,56.65121111928973,-111.38734856450468,-42.78053601532233
801 +T5A,-0.5651329057979977,90,AB,53.59417318144444,-113.41982069088888,-42.91951828367721
802 +E3B,-0.5691282462533743,104,QC,45.91962835576923,-66.63627050961539,-43.14711926702132
803 +E3A,-0.582134598520611,73,QC,45.97249969863014,-66.62391587671233,-43.881779877339454
804 +S0K,-0.5895382765440855,268,SK,52.303773003731344,-106.50638420149254,-44.295726854454884
805 +S0J,-0.5896880725031357,190,SK,53.64329271052631,-106.10882098947368,-44.30407050453579
806 +R7A,-0.5915407241450155,64,MB,49.830784140625,-99.954790046875,-44.407160135687995
807 +A1L,-0.6038056374558386,70,NL,47.53215062857143,-52.88351435714286,-45.084837177125515
808 +R0C,-0.6042794719711018,163,MB,50.603661042944786,-97.30552206134969,-45.11085171290308
809 +E1A,-0.6135830058327895,207,QC,46.09167680676328,-64.72582895169081,-45.61914662684449
810 +B0E,-0.6171868648887566,125,QC,45.937936985840004,-61.050800693999996,-45.81477483776316
811 +S0M,-0.6320313581062297,180,SK,53.50021531375556,-108.93214574572222,-46.613186376460334
812 +V1J,-0.6340482269962265,162,BC,56.23051926555556,-120.85154619598765,-46.72075207058004
813 +R0J,-0.6360837136125689,110,SK,50.51852058181818,-99.99157126363637,-46.82909096807536
814 +T0H,-0.6365419424410161,238,BC,56.3156674202689,-117.58536711827311,-46.85344983003592
815 +T7E,-0.6382914095706267,77,BC,53.60010065436364,-116.3755340604156,-46.94634668891633
816 +G0R,-0.6444731367683891,123,QC,46.85878246804878,-70.38906747642277,-47.27329829653757
817 +T0G,-0.6495583557060685,171,BC,55.01782717241521,-114.96989101937426,-47.540744530899325
818 +B0S,-0.6511271497911552,140,NS,44.802568600214286,-65.37236301321428,-47.62297778020429
819 +P0J,-0.6589321400477482,69,QC,47.54582441884058,-79.72523725507246,-48.03018872238118
820 +T9N,-0.6604760336470782,70,AB,54.25744733185714,-110.76997989528572,-48.11036267541936
821 +E4W,-0.6622581844624673,59,QC,46.66648872881356,-64.8661576440678,-48.20275548147651
822 +E1B,-0.6654563321413188,98,QC,46.05525647959184,-64.80372075510205,-48.36814610601338
823 +B0T,-0.6677376789060362,120,NS,43.915185399722866,-65.03480700982632,-48.485802010863075
824 +V2J,-0.6695993589413034,105,BC,52.97488610790476,-122.54019541628573,-48.581615749856745
825 +S0G,-0.6706809258679899,232,SK,50.555656612068965,-103.89381019396552,-48.637198110245706
826 +S4N,-0.6721839205618949,61,SK,50.45005506557377,-104.57220647540984,-48.714338143897905
827 +T8S,-0.6726734846496034,54,BC,56.212139288796294,-117.30276917492593,-48.73943961726571
828 +S6H,-0.6759867682717395,85,SK,50.420906447058826,-105.5472099882353,-48.908999337604456
829 +R0G,-0.6790416642455579,97,MB,49.40360283505155,-97.79856940206186,-49.064838871847236
830 +G0L,-0.6828610804538352,55,QC,47.88740009290909,-69.19724255963636,-49.259010404834356
831 +S4P,-0.6840529805164433,58,SK,50.44742644827586,-104.60799389655173,-49.3194525658464
832 +B0K,-0.6857486446028879,154,QC,45.686596645389606,-62.9450107198052,-49.405316930878165
833 +S9H,-0.6859522716461659,75,SK,50.30991141333333,-107.79178326666667,-49.41561832774003
834 +S4R,-0.6896841053060417,51,SK,50.47977998039215,-104.62368984313726,-49.60403902989798
835 +E1C,-0.6909663705552789,85,QC,46.099840447058824,-64.80482864705883,-49.66861860642996
836 +V0J,-0.7112635706576239,238,BC,54.46653000138656,-125.16325086268908,-50.6799068474449
837 +T0B,-0.7267236913533611,266,AB,53.11132985697368,-112.13424825041353,-51.436537568703464
838 +T0A,-0.7303830086178574,261,AB,54.22403972777011,-111.9225513865479,-51.6139219344258
839 +E3L,-0.7503994790586435,55,QC,45.19644936363637,-67.25669143636364,-52.57281162673778
840 +J0Z,-0.7548252831412421,131,QC,47.81038557045802,-79.17579452450381,-52.78225125940501
841 +B5A,-0.7568326024586717,71,NS,43.89610895788732,-66.07798222338029,-52.8769372942307
842 +S3N,-0.7595006801816446,61,SK,51.211713508196716,-102.46195759016393,-53.00249771111369
843 +S6V,-0.7741585136176422,96,SK,53.19113611458334,-105.74260737499999,-53.68635509379614
844 +V1G,-0.7744636118265333,77,BC,55.81719828558441,-120.4292089657143,-53.700483148572545
845 +S4T,-0.7849995035634568,89,SK,50.4543451011236,-104.6345960449438,-54.18572910742731
846 +R0K,-0.7914760267790879,87,MB,49.605713919540236,-99.7390541954023,-54.48148751955224
847 +NL_other,-0.7982419441485402,149,NL,48.14870160402684,-53.876689624161074,-54.788422494540434
848 +S4A,-0.8189037011690321,57,SK,49.19965112280702,-103.04507957894737,-55.71298865099534
849 +B0W,-0.8227960744510459,146,NS,43.93083566219178,-65.83433192308219,-55.88503517883947
850 +A2H,-0.8374439280306465,53,QC,48.96929237735849,-57.89500337735849,-56.526515102610816
851 +S0L,-0.8616842354200737,112,SK,51.489580775214286,-108.41836970251786,-57.56765597240524
852 +B0M,-0.8655721910552834,99,QC,45.514104107777776,-64.03354898656566,-57.73231075083285
853 +R0L,-0.866537329877873,67,SK,51.60080056716418,-100.7748179402985,-57.77308525897289
854 +S0E,-0.8743211157978212,113,SK,52.96472642477876,-103.596388,-58.100494628088484
855 +A0A,-0.8782492808461225,190,NL,47.56765076894737,-53.471708504736846,-58.26475995874192
856 +J0Y,-0.8981560644500223,60,QC,48.45025051166667,-77.60215428049999,-59.08735953026583
857 +E2A,-0.8989439080805958,53,QC,47.6233130754717,-65.66400166037737,-59.119579599615065
858 +G0C,-0.9046562762998,76,QC,48.17086863763158,-65.44174349223685,-59.35243789453371
859 +V0C,-0.9090609509460087,149,BC,56.44480097040268,-121.53379307322146,-59.5310834541588
860 +R8N,-0.9159098733497553,73,MB,55.672305465753425,-97.96253098630137,-59.8073049338617
861 +R0M,-0.9383446974692723,50,SK,49.79425156,-100.92250111999999,-60.69898127792117
862 +S0A,-0.9390381630479746,179,SK,51.27565879888269,-102.65004955307262,-60.726225733974815
863 +E3Y,-0.9444678245761139,53,QC,47.066267415094345,-67.72137916981131,-60.938891162055775
864 +S0H,-0.9598498537182533,113,SK,50.123990442477876,-106.19959385840707,-61.53513281707815
865 +R2W,-0.9657385537905898,72,MB,49.92074486111111,-97.13534740277777,-61.76097527137827
866 +G0J,-0.9706868926771826,60,QC,48.57111022633333,-67.536719657,-61.94972753419754
867 +S0C,-0.9762375869499837,97,SK,49.41909219793814,-102.39812673608249,-62.160347878311995
868 +S0N,-1.0034714073889994,107,SK,49.93292885981308,-108.51628510280375,-63.17696021798551
869 +A0G,-1.0256430164546346,132,NL,49.21378543409091,-54.43604053181818,-63.984402041810085
870 +A0B,-1.1558331686174537,86,NL,47.51593593023256,-53.65787445348837,-68.38088100658041
added results/reproduced/gradient_bins.csv +9 −0
@@ -0,0 +1,9 @@
1 +x,prem,n
2 +2.0282523534641763,0.1878214496540589,12980
3 +7.563491017989508,0.11142969127236768,11358
4 +14.394147475605937,0.016118590333607075,20383
5 +27.88055702929087,0.10401369998492674,21602
6 +59.65406819554855,0.06257146330258871,20927
7 +104.14998635231608,-0.010089293358040565,25567
8 +217.74684657163596,-0.14115921211123508,19860
9 +485.2518699511848,-0.4780914690614219,9469
added results/reproduced/grand_model.parquet +0 −0

Binary file not shown.

added results/reproduced/heterogeneity.csv +9 −0
@@ -0,0 +1,9 @@
1 +prov,n,elast,se_el,bath,se_bath
2 +NL,1029,0.41886323780274975,0.04345835618416139,0.25835214604184414,0.026510333907419987
3 +ON,49279,0.4720901632997946,0.013156307134272625,0.11472123286285063,0.005531088049014921
4 +NS,1934,0.47483207288538104,0.044920571815778486,0.16886581690826713,0.024607381866662878
5 +BC,30058,0.4958361647154056,0.021890607542201092,0.09149012627659524,0.006093443885784292
6 +AB,22435,0.5527530702149726,0.021986769802557028,0.12293484818163652,0.0077485150029473265
7 +QC,30857,0.5877745125683984,0.01585377636869836,0.12950231091820924,0.012583702295353723
8 +MB,3056,0.666477046579255,0.034615494385032364,0.20513902421662095,0.013229354095124608
9 +SK,3459,0.7235871144875173,0.034985520991915035,0.16683678850681966,0.012723659060980184
added results/reproduced/lopo.csv +9 −0
@@ -0,0 +1,9 @@
1 +prov,n,r2_within
2 +MB,3056,0.5212014330611053
3 +ON,49279,0.5158994827387327
4 +SK,3459,0.47318893331131373
5 +NS,1934,0.46113025528770357
6 +NL,1029,0.3966549132902695
7 +BC,30058,0.2881968210788265
8 +QC,30857,0.14633577388751784
9 +AB,22435,-0.28652058269090674
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
@@ -0,0 +1,61 @@
1 +ln_area,elasticity,se
2 +3.9746788410500162,0.6494380150270442,0.018806169225596938
3 +4.007448185522403,0.6453501028853275,0.018381350505736426
4 +4.0402175299947904,0.6412621907436105,0.01796045289812988
5 +4.072986874467177,0.6371742786018936,0.017543758622809665
6 +4.105756218939565,0.6330863664601766,0.01713157439767673
7 +4.138525563411951,0.6289984543184598,0.016724233689144573
8 +4.171294907884339,0.6249105421767428,0.016322099131342246
9 +4.2040642523567255,0.6208226300350259,0.015925565108838927
10 +4.236833596829113,0.616734717893309,0.015535060490279138
11 +4.2696029413015,0.6126468057515921,0.015151051490099803
12 +4.302372285773887,0.6085588936098751,0.014774044622003154
13 +4.335141630246274,0.6044709814681584,0.01440458969038976
14 +4.3679109747186615,0.6003830693264414,0.014043282743799144
15 +4.400680319191048,0.5962951571847245,0.0136907688868942
16 +4.433449663663435,0.5922072450430077,0.013347744814187709
17 +4.466219008135822,0.5881193329012907,0.013014960889424805
18 +4.498988352608209,0.5840314207595738,0.012693222549853101
19 +4.531757697080597,0.5799435086178569,0.012383390766070595
20 +4.564527041552983,0.57585559647614,0.01208638123875636
21 +4.597296386025371,0.571767684334423,0.011803161968311033
22 +4.6300657304977575,0.5676797721927063,0.011534748799608328
23 +4.662835074970145,0.5635918600509893,0.011282198531678436
24 +4.695604419442532,0.5595039479092724,0.01104659920358333
25 +4.728373763914919,0.5554160357675555,0.010829057236863613
26 +4.761143108387306,0.5513281236258386,0.010630681244971383
27 +4.7939124528596935,0.5472402114841216,0.010452562520423756
28 +4.82668179733208,0.5431522993424048,0.010295752482106702
29 +4.859451141804467,0.5390643872006879,0.010161237696290076
30 +4.892220486276854,0.534976475058971,0.010049913446715157
31 +4.924989830749241,0.5308885629172542,0.009962557175278108
32 +4.957759175221629,0.5268006507755372,0.00989980338558115
33 +4.990528519694015,0.5227127386338203,0.009862121733881722
34 +5.023297864166403,0.5186248264921034,0.009849799974258359
35 +5.0560672086387894,0.5145369143503865,0.009862933153487302
36 +5.088836553111177,0.5104490022086695,0.009901419982289194
37 +5.121605897583564,0.5063610900669527,0.009964966701372051
38 +5.15437524205595,0.5022731779252358,0.010053098103146507
39 +5.187144586528338,0.49818526578351885,0.010165174764940674
40 +5.219913931000725,0.49409735364180196,0.01030041508631286
41 +5.252683275473112,0.4900094415000851,0.010457920458540392
42 +5.285452619945499,0.4859215293583682,0.010636701843251661
43 +5.318221964417886,0.4818336172166513,0.010835706174752534
44 +5.350991308890273,0.4777457050749344,0.011053841274740949
45 +5.3837606533626605,0.4736577929332174,0.011289998315634176
46 +5.416529997835047,0.46956988079150064,0.011543071230185503
47 +5.449299342307435,0.46548196864978364,0.011811972794648285
48 +5.482068686779821,0.46139405650806675,0.01209564738226706
49 +5.514838031252209,0.45730614436634986,0.012393080581882697
50 +5.547607375724596,0.453218232224633,0.012703306004351515
51 +5.580376720196982,0.4491303200829161,0.013025409666862931
52 +5.61314606466937,0.4450424079411992,0.013358532365394058
53 +5.645915409141757,0.4409544957994822,0.013701870432288165
54 +5.678684753614144,0.4368665836577653,0.014054675241619932
55 +5.711454098086531,0.43277867151604854,0.014416251779497234
56 +5.744223442558918,0.42869075937433154,0.014785956547026963
57 +5.776992787031305,0.42460284723261466,0.015163195015218367
58 +5.8097621315036925,0.42051493509089777,0.015547418806566344
59 +5.842531475976079,0.4164270229491809,0.015938122738963504
60 +5.875300820448467,0.4123391108074639,0.01633484183443525
61 +5.908070164920853,0.4082511986657471,0.016737148367867986
added results/reproduced/oos.json +11 −0
@@ -0,0 +1,11 @@
1 +{
2 + "n_train": 113716,
3 + "n_test": 28430,
4 + "oos_r2": 0.7695758148853212,
5 + "rmse_log": 0.2799204872082716,
6 + "mae_log": 0.20249408087341147,
7 + "median_ape": 15.558110855456578,
8 + "mean_ape": 21.995714792380202,
9 + "within10": 34.22441083362645,
10 + "within20": 60.024621878297566
11 +}
\ No newline at end of file
added results/reproduced/quantile.csv +7 −0
@@ -0,0 +1,7 @@
1 +tau,ln_living,se_living,bathrooms,se_bath,ln_lot,se_lot
2 +0.1,0.5907624602909891,0.00854157216912479,0.17847844049765627,0.003971299609479059,-0.00584690608894789,0.0017051166161529854
3 +0.25,0.5671770180033491,0.005324416376657182,0.14818531795728518,0.0023214169264950154,-0.002352869673359237,0.001153678746676559
4 +0.5,0.5704083790496952,0.004744860290189453,0.1166730392561135,0.001955524401797616,0.014391215617820308,0.0010851679848038838
5 +0.75,0.6006108334095188,0.0065587787957749,0.09015714132488029,0.002584740781679338,0.03371462880522813,0.0014853866310596741
6 +0.9,0.5846851372612036,0.010215300951522364,0.07378175197334258,0.0038492026465534296,0.04726651517456304,0.002251612109834233
7 +,0.5813085677006347,0.009653234341615202,0.127356234367056,0.0023632395826616646,0.030608663376169284,0.001678009533164809
added results/reproduced/robustness.csv +7 −0
@@ -0,0 +1,7 @@
1 +label,n,r2,ln_living,se_living,bathrooms,se_bath,ln_lot,se_lot
2 +Baseline (all residential),142146,0.7695479150272374,0.5300775244939722,0.010200096739191443,0.11107079513655177,0.0034720178610876534,0.060959009581207396,0.0071746528194990096
3 +Houses only,83542,0.7657314371141364,0.4860848549657795,0.010302763477595489,0.10541941278639437,0.003915059865757416,0.0802405166313547,0.004654076544900686
4 +Condominiums only,57860,0.8124287804174603,0.6209244425136851,0.017398414434041803,0.1211076396782959,0.004833738823918021,0.0059408796827741675,0.0035982800010453393
5 +Price trimmed 0.5/99.5\%,140739,0.7669067639239838,0.5203621130199332,0.009478396877136818,0.109248895929146,0.0033868967901083138,0.05809020151404406,0.00700405850967329
6 +FSAs with $\geq$50 listings,131792,0.7621236613992234,0.5260636122563492,0.011260120706112911,0.11153142279402012,0.003719756520921279,0.05972909238033767,0.0074311094274621394
7 +ON/QC/BC only,110194,0.7626700124075747,0.5226403771521636,0.011797609007361575,0.09752517275570255,0.003695374548145484,0.04703518783585091,0.009191963567514292
added results/tables/lopo.tex +16 −0
@@ -0,0 +1,16 @@
1 +\begin{table}[t]\centering\caption{Leave-one-province-out spatial cross-validation}
2 +\label{tab:lopo}\begin{threeparttable}\begin{tabular}{lcc}
3 +\toprule
4 +Held-out province & $N$ & Within-province $R^2$ \\
5 +\midrule
6 +ON & 48,781 & 0.549 \\
7 +MB & 3,015 & 0.527 \\
8 +SK & 3,400 & 0.475 \\
9 +NS & 1,913 & 0.450 \\
10 +NL & 1,016 & 0.378 \\
11 +BC & 29,976 & 0.317 \\
12 +QC & 30,556 & 0.303 \\
13 +AB & 22,236 & -0.101 \\
14 +\midrule
15 +Mean & --- & 0.362 \\
16 +\bottomrule\end{tabular}\begin{tablenotes}\footnotesize\item Notes: The structural hedonic model is estimated on all provinces except one and used to predict the held-out province; a province-specific intercept is allowed (the price \emph{level} is not identified out of sample), so the metric captures whether the \emph{structural} implicit prices transfer across space.\end{tablenotes}\end{threeparttable}\end{table}
added results/tables/oos.tex +22 −0
@@ -0,0 +1,22 @@
1 +\begin{table}[t]\centering
2 +\caption{Out-of-sample valuation performance (80/20 split)}
3 +\label{tab:oos}
4 +\begin{threeparttable}
5 +\begin{tabular}{lc}
6 +\toprule
7 +Metric & Value \\
8 +\midrule
9 +Training listings & 112,732 \\
10 +Test listings & 28,187 \\
11 +Out-of-sample $R^2$ (log price) & 0.764 \\
12 +RMSE (log points) & 0.282 \\
13 +Median absolute \% error & 15.8\% \\
14 +Mean absolute \% error & 22.5\% \\
15 +Share priced within $\pm$10\% & 33.8\% \\
16 +Share priced within $\pm$20\% & 59.5\% \\
17 +\bottomrule
18 +\end{tabular}
19 +\begin{tablenotes}\footnotesize\item Notes: Model trained on a random 80\% of listings and scored on the held-out 20\% (restricted to neighbourhoods observed in training). Prices back-transformed with Duan's smearing estimator.
20 +\end{tablenotes}
21 +\end{threeparttable}
22 +\end{table}
added results/tables/quantile.tex +13 −0
@@ -0,0 +1,13 @@
1 +\begin{table}[t]\centering\caption{Quantile hedonic estimates across the price distribution}
2 +\label{tab:quantile}\begin{threeparttable}\begin{tabular}{lccc}
3 +\toprule
4 +Quantile & $\ln$ area & Full bath & $\ln$ lot \\
5 +\midrule
6 +$\tau=0.1$ & \makecell{0.557\\\scriptsize(0.008)} & \makecell{0.181\\\scriptsize(0.004)} & \makecell{-0.014\\\scriptsize(0.001)} \\
7 +$\tau=0.25$ & \makecell{0.534\\\scriptsize(0.005)} & \makecell{0.146\\\scriptsize(0.002)} & \makecell{-0.011\\\scriptsize(0.001)} \\
8 +$\tau=0.5$ & \makecell{0.552\\\scriptsize(0.005)} & \makecell{0.114\\\scriptsize(0.002)} & \makecell{-0.002\\\scriptsize(0.001)} \\
9 +$\tau=0.75$ & \makecell{0.601\\\scriptsize(0.006)} & \makecell{0.087\\\scriptsize(0.003)} & \makecell{0.009\\\scriptsize(0.001)} \\
10 +$\tau=0.9$ & \makecell{0.598\\\scriptsize(0.010)} & \makecell{0.071\\\scriptsize(0.004)} & \makecell{0.023\\\scriptsize(0.002)} \\
11 +\midrule
12 +OLS & 0.584 & 0.126 & 0.007 \\
13 +\bottomrule\end{tabular}\begin{tablenotes}\footnotesize\item Notes: House subsample, province fixed effects, structural controls. Analytical standard errors in parentheses. The size elasticity rises and the lot elasticity rises with price.\end{tablenotes}\end{threeparttable}\end{table}
added results/tables/regression.tex +30 −0
@@ -0,0 +1,30 @@
1 +\begin{table}[t]\centering
2 +\caption{Hedonic regression estimates}
3 +\label{tab:regression}
4 +\begin{threeparttable}
5 +\begin{tabular}{lcccc}
6 +\toprule
7 + & (1) & (2) & (3) & (4) \\
8 + & Structural & +Type/Own. & +Province & Grand+FSA \\
9 +\midrule
10 +$\ln$ living area & \makecell{0.657$^{***}$\\\scriptsize(0.022)} & \makecell{0.650$^{***}$\\\scriptsize(0.022)} & \makecell{0.585$^{***}$\\\scriptsize(0.016)} & \makecell{0.547$^{***}$\\\scriptsize(0.009)} \\
11 +Full bathrooms & \makecell{0.136$^{***}$\\\scriptsize(0.010)} & \makecell{0.141$^{***}$\\\scriptsize(0.010)} & \makecell{0.138$^{***}$\\\scriptsize(0.006)} & \makecell{0.109$^{***}$\\\scriptsize(0.004)} \\
12 +Half bathrooms & \makecell{-0.035$^{***}$\\\scriptsize(0.009)} & \makecell{-0.039$^{***}$\\\scriptsize(0.009)} & \makecell{-0.026$^{***}$\\\scriptsize(0.009)} & \makecell{-0.036$^{***}$\\\scriptsize(0.009)} \\
13 +Bedrooms & \makecell{0.005\\\scriptsize(0.004)} & \makecell{0.003\\\scriptsize(0.004)} & \makecell{-0.003\\\scriptsize(0.003)} & \makecell{-0.002\\\scriptsize(0.003)} \\
14 +Parking spaces & \makecell{0.002\\\scriptsize(0.002)} & \makecell{0.002\\\scriptsize(0.002)} & \makecell{0.001\\\scriptsize(0.001)} & \makecell{0.001\\\scriptsize(0.001)} \\
15 +Storeys & \makecell{0.001\\\scriptsize(0.004)} & \makecell{0.000\\\scriptsize(0.004)} & \makecell{-0.010\\\scriptsize(0.007)} & \makecell{0.001$^{***}$\\\scriptsize(0.000)} \\
16 +Has lot info & \makecell{-0.212$^{***}$\\\scriptsize(0.038)} & \makecell{-0.221$^{***}$\\\scriptsize(0.038)} & \makecell{-0.034\\\scriptsize(0.039)} & \makecell{-0.196$^{***}$\\\scriptsize(0.028)} \\
17 +$\ln(1+$lot m$^2)$ & \makecell{0.026$^{***}$\\\scriptsize(0.004)} & \makecell{0.027$^{***}$\\\scriptsize(0.004)} & \makecell{0.008$^{*}$\\\scriptsize(0.005)} & \makecell{0.030$^{***}$\\\scriptsize(0.004)} \\
18 +\midrule
19 +Dwelling-type FE & No & Yes & Yes & Yes \\
20 +Ownership FE & No & Yes & Yes & Yes \\
21 +Province FE & No & No & Yes & --- \\
22 +FSA fixed effects & No & No & No & Yes \\
23 +$R^2$ & 0.464 & 0.469 & 0.567 & 0.767 \\
24 +Observations & 82,334 & 82,334 & 82,334 & 140,931 \\
25 +\bottomrule
26 +\end{tabular}
27 +\begin{tablenotes}\footnotesize\item Notes: Dependent variable is $\ln(\text{price})$. Columns (1)--(3) use the house subsample; column (4) is the grand model over all residential dwellings with 1{,}153 absorbed FSA fixed effects. Cluster-robust standard errors (by FSA) in parentheses. $^{*}p<0.1$, $^{**}p<0.05$, $^{***}p<0.01$.
28 +\end{tablenotes}
29 +\end{threeparttable}
30 +\end{table}
added results/tables/robustness.tex +20 −0
@@ -0,0 +1,20 @@
1 +\begin{table}[t]\centering
2 +\caption{Robustness of key implicit prices across samples}
3 +\label{tab:robustness}
4 +\begin{threeparttable}
5 +\begin{tabular}{lccccc}
6 +\toprule
7 +Sample / specification & $N$ & $R^2$ & $\ln$ area & Full bath & $\ln$ lot \\
8 +\midrule
9 +Baseline (all residential) & 140,931 & 0.767 & \makecell{0.547\\\scriptsize(0.009)} & \makecell{0.109\\\scriptsize(0.004)} & \makecell{0.030\\\scriptsize(0.004)} \\
10 +Houses only & 82,334 & 0.762 & \makecell{0.513\\\scriptsize(0.010)} & \makecell{0.103\\\scriptsize(0.004)} & \makecell{0.055\\\scriptsize(0.003)} \\
11 +Condominiums only & 57,857 & 0.813 & \makecell{0.619\\\scriptsize(0.017)} & \makecell{0.121\\\scriptsize(0.005)} & \makecell{0.005\\\scriptsize(0.003)} \\
12 +Price trimmed 0.5/99.5\% & 139,552 & 0.765 & \makecell{0.536\\\scriptsize(0.009)} & \makecell{0.107\\\scriptsize(0.003)} & \makecell{0.028\\\scriptsize(0.003)} \\
13 +FSAs with $\geq$50 listings & 130,590 & 0.760 & \makecell{0.542\\\scriptsize(0.010)} & \makecell{0.109\\\scriptsize(0.004)} & \makecell{0.030\\\scriptsize(0.004)} \\
14 +ON/QC/BC only & 109,313 & 0.762 & \makecell{0.532\\\scriptsize(0.010)} & \makecell{0.096\\\scriptsize(0.004)} & \makecell{0.030\\\scriptsize(0.003)} \\
15 +\bottomrule
16 +\end{tabular}
17 +\begin{tablenotes}\footnotesize\item Notes: Each row re-estimates the grand FSA-fixed-effects model on a different sample. Cluster-robust (FSA) standard errors in parentheses. The size elasticity and bathroom premium are stable across all cuts.
18 +\end{tablenotes}
19 +\end{threeparttable}
20 +\end{table}
added results/tables/summary_stats.tex +23 −0
@@ -0,0 +1,23 @@
1 +\begin{table}[t]\centering
2 +\caption{Descriptive statistics}
3 +\label{tab:summary_stats}
4 +\begin{threeparttable}
5 +\begin{tabular}{lccccc}
6 +\toprule
7 +Variable & Mean & SD & P25 & Median & P75 \\
8 +\midrule
9 +List price (CAD) & 763,592 & 475,478 & 449,000 & 639,888 & 928,000 \\
10 +Price per m$^2$ (CAD) & 5,382 & 2,682 & 3,580 & 4,781 & 6,593 \\
11 +Living area (m$^2$) & 151.7 & 79.1 & 93.8 & 134.6 & 185.8 \\
12 +Bedrooms & 3.11 & 1.32 & 2.00 & 3.00 & 4.00 \\
13 +Full bathrooms & 2.32 & 1.11 & 2.00 & 2.00 & 3.00 \\
14 +Half bathrooms & 0.35 & 0.52 & 0.00 & 0.00 & 1.00 \\
15 +Parking spaces & 2.72 & 11.20 & 0.00 & 2.00 & 4.00 \\
16 +Storeys & 2.44 & 6.01 & 1.50 & 2.00 & 2.00 \\
17 +Lot area (m$^2$) & 2,621 & 10,818 & 0 & 0 & 656 \\
18 +\bottomrule
19 +\end{tabular}
20 +\begin{tablenotes}\footnotesize\item Notes: Estimation sample of 140,931 residential dwellings (houses, condominiums, plexes, townhouses and apartments) from the Canadian MLS, after parsing and trimming the extreme 1\% tails of price and living area.
21 +\end{tablenotes}
22 +\end{threeparttable}
23 +\end{table}
added scripts/01_build_sample.py +29 −0
@@ -0,0 +1,29 @@
1 +#!/usr/bin/env python3
2 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
3 +"""Step 01 — Build the estimation sample.
4 +
5 +Reads the raw DuckDB snapshot (``data/raw/realtor_mls_unique.duckdb``),
6 +parses the semi-structured fields, applies the sample restrictions and trims,
7 +and writes ``data/processed/analysis.parquet``.
8 +
9 +Usage: python scripts/01_build_sample.py
10 +"""
11 +import sys
12 +from pathlib import Path
13 +
14 +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
15 +
16 +from wp9 import sample # noqa: E402
17 +
18 +
19 +def main() -> None:
20 + s = sample.build_and_save()
21 + by_cat = s.groupby("cat").size().to_dict()
22 + print(f"Estimation sample written: {len(s):,} listings")
23 + print(f" by category : {by_cat}")
24 + print(f" by province : {s.groupby('prov').size().to_dict()}")
25 + print(f" FSA levels : {s['fsa_c'].nunique():,} (incl. pooled residual categories)")
26 +
27 +
28 +if __name__ == "__main__":
29 + main()
added scripts/02_estimate_core.py +62 −0
@@ -0,0 +1,62 @@
1 +#!/usr/bin/env python3
2 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
3 +"""Step 02 — Estimate the M1–M5 hedonic specification ladder.
4 +
5 +Writes to ``results/reproduced/``:
6 + fit.json R^2 and N for each specification
7 + coef_M{1,2,3,5}.csv coefficient tables (coef, se, p)
8 + grand_model.parquet per-listing grand-model (M5) fitted values/residuals
9 + fsa_premia.csv FSA location premia (grand-model fixed effects, >=50 listings)
10 +
11 +Usage: python scripts/02_estimate_core.py
12 +"""
13 +import json
14 +import sys
15 +from pathlib import Path
16 +
17 +import numpy as np
18 +import pandas as pd
19 +
20 +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
21 +
22 +from wp9 import models, sample # noqa: E402
23 +from wp9.config import REPRODUCED, ensure_dirs # noqa: E402
24 +
25 +
26 +def main() -> None:
27 + ensure_dirs()
28 + s = sample.load_sample()
29 + ladder = models.specification_ladder(s)
30 +
31 + fit = {}
32 + for name, (res, cols, data) in ladder.items():
33 + r2 = float(res.rsquared)
34 + fit[name] = {"r2": r2, "n": int(res.nobs)}
35 + print(f"{name}: N={int(res.nobs):,} R2={r2:.4f}")
36 + if name != "M4":
37 + models.coef_table(res, cols).to_csv(REPRODUCED / f"coef_{name}.csv")
38 + json.dump(fit, open(REPRODUCED / "fit.json", "w"), indent=2)
39 +
40 + # Grand model (M5): per-listing predictions, residuals and FSA premia
41 + res5, cols5, _ = ladder["M5"]
42 + fe = models.fsa_fixed_effects(s, res5, cols5)
43 + pred = models.predict_with_fe(s, res5, cols5, fe)
44 + frame = s[["fsa_c", "prov", "lat", "lon", "ln_price"]].copy()
45 + frame["pred_grand"] = pred
46 + frame["resid_grand"] = frame["ln_price"] - frame["pred_grand"]
47 + frame.to_parquet(REPRODUCED / "grand_model.parquet", index=False)
48 +
49 + premia = (frame.assign(fe=s["fsa_c"].map(fe))
50 + .groupby("fsa_c")
51 + .agg(fe=("fe", "first"), n=("fe", "size"), prov=("prov", "first"),
52 + lat=("lat", "mean"), lon=("lon", "mean")))
53 + premia = premia[premia["n"] >= 50].copy()
54 + reference_level = premia["fe"].median()
55 + premia["premium_pct"] = (np.exp(premia["fe"] - reference_level) - 1) * 100
56 + premia.index.name = "fsa_c"
57 + premia.sort_values("premium_pct", ascending=False).to_csv(REPRODUCED / "fsa_premia.csv")
58 + print(f"FSA premia written for {len(premia):,} neighbourhoods (>=50 listings)")
59 +
60 +
61 +if __name__ == "__main__":
62 + main()
added scripts/03_estimate_extended.py +281 −0
@@ -0,0 +1,281 @@
1 +#!/usr/bin/env python3
2 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
3 +"""Step 03 — Extended analyses.
4 +
5 +Out-of-sample validation, robustness across samples, province heterogeneity,
6 +quantile regressions, nonlinearity in floor space, the urban price gradient,
7 +Moran's I spatial diagnostics, leave-one-province-out cross-validation.
8 +
9 +Writes to ``results/reproduced/``:
10 + oos.json, robustness.csv, heterogeneity.csv, quantile.csv, lopo.csv,
11 + ext2.json, nonlinear_band.csv, gradient_bins.csv
12 +
13 +Usage: python scripts/03_estimate_extended.py
14 +"""
15 +import json
16 +import sys
17 +import warnings
18 +from pathlib import Path
19 +
20 +import numpy as np
21 +import pandas as pd
22 +import statsmodels.api as sm
23 +from sklearn.neighbors import NearestNeighbors
24 +from statsmodels.regression.quantile_regression import QuantReg
25 +
26 +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
27 +
28 +from wp9 import models, sample # noqa: E402
29 +from wp9.config import (METROS, REPRODUCED, SEED_EXT2, SEED_MORAN, # noqa: E402
30 + SEED_OOS, STRUCT, ensure_dirs)
31 +
32 +warnings.filterwarnings("ignore")
33 +
34 +
35 +# --------------------------------------------------------------------------
36 +def out_of_sample(s: pd.DataFrame) -> dict:
37 + """80/20 split validation of the grand model, on common-FSA support."""
38 + np.random.seed(SEED_OOS) # legacy global seed, kept identical to the original
39 + idx = np.arange(len(s))
40 + np.random.shuffle(idx)
41 + cut = int(0.8 * len(s))
42 + train, test = s.iloc[idx[:cut]].copy(), s.iloc[idx[cut:]].copy()
43 + common = set(train["fsa_c"]).intersection(test["fsa_c"])
44 + train = train[train["fsa_c"].isin(common)].copy()
45 + test = test[test["fsa_c"].isin(common)].copy()
46 +
47 + res, cols = models.fit_absorbing(train)
48 + fe = models.fsa_fixed_effects(train, res, cols)
49 + pred_test = models.predict_with_fe(test, res, cols, fe)
50 + err = test["ln_price"].values - pred_test
51 + ss_res = np.sum(err ** 2)
52 + ss_tot = np.sum((test["ln_price"].values - test["ln_price"].mean()) ** 2)
53 +
54 + pred_train = models.predict_with_fe(train, res, cols, fe)
55 + smear = models.duan_smearing(train["ln_price"].values - pred_train)
56 + ape = np.abs(np.exp(pred_test) * smear - test["price_cad"].values) / test["price_cad"].values
57 + return {
58 + "n_train": int(len(train)), "n_test": int(len(test)),
59 + "oos_r2": float(1 - ss_res / ss_tot),
60 + "rmse_log": float(np.sqrt(np.mean(err ** 2))),
61 + "mae_log": float(np.mean(np.abs(err))),
62 + "median_ape": float(np.median(ape) * 100),
63 + "mean_ape": float(np.mean(ape) * 100),
64 + "within10": float(np.mean(ape <= 0.10) * 100),
65 + "within20": float(np.mean(ape <= 0.20) * 100),
66 + }
67 +
68 +
69 +# --------------------------------------------------------------------------
70 +def robustness(s: pd.DataFrame) -> pd.DataFrame:
71 + """Key implicit prices of the grand model across alternative samples."""
72 + def key_coefs(data, label):
73 + res, cols = models.fit_absorbing(data)
74 + tab = models.coef_table(res, cols)
75 + return {"label": label, "n": int(res.nobs), "r2": float(res.rsquared),
76 + "ln_living": tab.loc["ln_living", "coef"], "se_living": tab.loc["ln_living", "se"],
77 + "bathrooms": tab.loc["bathrooms", "coef"], "se_bath": tab.loc["bathrooms", "se"],
78 + "ln_lot": tab.loc["ln_lot", "coef"], "se_lot": tab.loc["ln_lot", "se"]}
79 +
80 + rows = [key_coefs(s, "Baseline (all residential)"),
81 + key_coefs(s[s["cat"] == "house"], "Houses only"),
82 + key_coefs(s[s["cat"] == "condo"], "Condominiums only")]
83 + lo, hi = s["price_cad"].quantile([0.005, 0.995])
84 + rows.append(key_coefs(s[s["price_cad"].between(lo, hi)], "Price trimmed 0.5/99.5\\%"))
85 + counts = s["fsa_c"].value_counts()
86 + rows.append(key_coefs(s[s["fsa_c"].isin(counts[counts >= 50].index)],
87 + "FSAs with $\\geq$50 listings"))
88 + rows.append(key_coefs(s[s["prov"].isin(["ON", "QC", "BC"])], "ON/QC/BC only"))
89 + return pd.DataFrame(rows)
90 +
91 +
92 +# --------------------------------------------------------------------------
93 +def heterogeneity(s: pd.DataFrame) -> pd.DataFrame:
94 + """Within-FSA living-area elasticity, estimated province by province."""
95 + rows = []
96 + for prov, g in s.groupby("prov"):
97 + if len(g) < 400:
98 + continue
99 + res, cols = models.fit_absorbing(g)
100 + tab = models.coef_table(res, cols)
101 + rows.append({"prov": prov, "n": len(g),
102 + "elast": tab.loc["ln_living", "coef"], "se_el": tab.loc["ln_living", "se"],
103 + "bath": tab.loc["bathrooms", "coef"], "se_bath": tab.loc["bathrooms", "se"]})
104 + return pd.DataFrame(rows).sort_values("elast")
105 +
106 +
107 +# --------------------------------------------------------------------------
108 +def quantile_regressions(s: pd.DataFrame) -> pd.DataFrame:
109 + """Quantile hedonic estimates (house subsample, province FE)."""
110 + houses = s[s["cat"] == "house"]
111 + prov_d = pd.get_dummies(houses["prov"], prefix="p", drop_first=True).astype(float)
112 + X = sm.add_constant(pd.concat([houses[STRUCT].astype(float), prov_d], axis=1))
113 + y = houses["ln_price"]
114 + rows = []
115 + for tau in (0.1, 0.25, 0.5, 0.75, 0.9):
116 + fit = QuantReg(y, X).fit(q=tau, max_iter=2000)
117 + rows.append({"tau": tau,
118 + "ln_living": fit.params["ln_living"], "se_living": fit.bse["ln_living"],
119 + "bathrooms": fit.params["bathrooms"], "se_bath": fit.bse["bathrooms"],
120 + "ln_lot": fit.params["ln_lot"], "se_lot": fit.bse["ln_lot"]})
121 + ols = sm.OLS(y, X).fit(cov_type="HC1")
122 + rows.append({"tau": np.nan,
123 + "ln_living": ols.params["ln_living"], "se_living": ols.bse["ln_living"],
124 + "bathrooms": ols.params["bathrooms"], "se_bath": ols.bse["bathrooms"],
125 + "ln_lot": ols.params["ln_lot"], "se_lot": ols.bse["ln_lot"]})
126 + return pd.DataFrame(rows)
127 +
128 +
129 +# --------------------------------------------------------------------------
130 +def nonlinearity(s: pd.DataFrame) -> tuple[dict, pd.DataFrame]:
131 + """Quadratic-in-log-area grand model and the implied marginal elasticity."""
132 + extra = (s["ln_living"] ** 2).to_frame("ln_living2")
133 + res, cols = models.fit_absorbing(s, extra=extra)
134 + params = pd.Series(np.asarray(res.params).ravel(), index=cols)
135 + cov = pd.DataFrame(np.asarray(res.cov), index=cols, columns=cols)
136 + b1, b2 = params["ln_living"], params["ln_living2"]
137 + grid = np.linspace(s["ln_living"].quantile(0.02), s["ln_living"].quantile(0.98), 60)
138 + marginal = b1 + 2 * b2 * grid
139 + v11 = cov.loc["ln_living", "ln_living"]
140 + v22 = cov.loc["ln_living2", "ln_living2"]
141 + v12 = cov.loc["ln_living", "ln_living2"]
142 + se = np.sqrt(v11 + 4 * grid ** 2 * v22 + 4 * grid * v12)
143 + band = pd.DataFrame({"ln_area": grid, "elasticity": marginal, "se": se})
144 + return {"b1": float(b1), "b2": float(b2), "r2": float(res.rsquared)}, band
145 +
146 +
147 +# --------------------------------------------------------------------------
148 +def haversine_km(lat1, lon1, lat2, lon2):
149 + """Great-circle distance in kilometres."""
150 + rad = np.pi / 180
151 + a = (np.sin((lat2 - lat1) * rad / 2) ** 2
152 + + np.cos(lat1 * rad) * np.cos(lat2 * rad) * np.sin((lon2 - lon1) * rad / 2) ** 2)
153 + return 2 * 6371.0 * np.arcsin(np.sqrt(a))
154 +
155 +
156 +def distance_to_metro(s: pd.DataFrame) -> np.ndarray:
157 + """Distance from each listing to the nearest of the nine major metros."""
158 + dist = np.full(len(s), np.inf)
159 + for lat, lon in METROS.values():
160 + dist = np.minimum(dist, haversine_km(s["lat"].values, s["lon"].values, lat, lon))
161 + return dist
162 +
163 +
164 +def urban_gradient(s: pd.DataFrame) -> tuple[dict, pd.DataFrame, pd.Series]:
165 + """Location premium (residual from a structure-only model) vs. metro distance."""
166 + X = models.design(s)
167 + structural = sm.OLS(s["ln_price"], X).fit()
168 + loc_premium = s["ln_price"] - structural.predict(X)
169 + dist = distance_to_metro(s)
170 +
171 + bins = [0, 5, 10, 20, 40, 80, 160, 320, 2000]
172 + banded = (pd.DataFrame({"dist": dist, "prem": loc_premium})
173 + .assign(band=lambda x: pd.cut(x["dist"], bins))
174 + .groupby("band", observed=True)
175 + .agg(x=("dist", "median"), prem=("prem", "mean"), n=("prem", "size"))
176 + .reset_index(drop=True))
177 +
178 + keep = dist > 0.5
179 + fit = sm.OLS(loc_premium[keep],
180 + sm.add_constant(np.log(dist[keep]))).fit(cov_type="HC1")
181 + stats = {"beta_logdist": float(fit.params.iloc[1]), "se": float(fit.bse.iloc[1]),
182 + "r2": float(fit.rsquared)}
183 + return stats, banded, loc_premium
184 +
185 +
186 +# --------------------------------------------------------------------------
187 +def morans_i(coords: np.ndarray, values: np.ndarray, k: int = 10,
188 + permutations: int = 199) -> tuple[float, float, float]:
189 + """Moran's I with row-standardised kNN weights and a permutation test."""
190 + nn = NearestNeighbors(n_neighbors=k + 1).fit(coords)
191 + _, idx = nn.kneighbors(coords)
192 + idx = idx[:, 1:]
193 + z = values - values.mean()
194 + lag = z[idx].mean(axis=1)
195 + stat = np.sum(z * lag) / np.sum(z ** 2)
196 + perms = np.empty(permutations)
197 + for b in range(permutations):
198 + zp = np.random.permutation(z)
199 + perms[b] = np.sum(zp * zp[idx].mean(axis=1)) / np.sum(zp ** 2)
200 + zscore = (stat - perms.mean()) / perms.std()
201 + pvalue = (np.sum(np.abs(perms) >= abs(stat)) + 1) / (permutations + 1)
202 + return float(stat), float(zscore), float(pvalue)
203 +
204 +
205 +def spatial_diagnostics(s: pd.DataFrame, loc_premium: pd.Series) -> dict:
206 + """Moran's I on structure-only vs. grand-model residuals (15k sample)."""
207 + grand = pd.read_parquet(REPRODUCED / "grand_model.parquet")
208 + subsample = s.sample(15000, random_state=SEED_MORAN)
209 + coords = subsample[["lat", "lon"]].values
210 + resid_struct = loc_premium.loc[subsample.index].values
211 + resid_grand = grand.loc[subsample.index, "resid_grand"].values
212 +
213 + np.random.seed(SEED_EXT2)
214 + i_s, z_s, p_s = morans_i(coords, resid_struct)
215 + i_g, z_g, p_g = morans_i(coords, resid_grand)
216 + np.save(REPRODUCED / "moran_coords.npy", coords)
217 + np.save(REPRODUCED / "moran_resid_struct.npy", resid_struct)
218 + np.save(REPRODUCED / "moran_resid_grand.npy", resid_grand)
219 + return {"struct_I": i_s, "struct_z": z_s, "struct_p": p_s,
220 + "grand_I": i_g, "grand_z": z_g, "grand_p": p_g}
221 +
222 +
223 +# --------------------------------------------------------------------------
224 +def leave_one_province_out(s: pd.DataFrame) -> pd.DataFrame:
225 + """Estimate the structural model out-of-province; within-province R^2."""
226 + X = models.design(s)
227 + rows = []
228 + for prov in s["prov"].value_counts().index:
229 + held = s["prov"] == prov
230 + if held.sum() < 800:
231 + continue
232 + fit = sm.OLS(s["ln_price"].values[~held], X.values[~held]).fit()
233 + err = s["ln_price"].values[held] - X.values[held] @ fit.params
234 + err = err - err.mean() # province-specific intercept allowed
235 + y_held = s["ln_price"].values[held]
236 + r2 = 1 - np.sum(err ** 2) / np.sum((y_held - y_held.mean()) ** 2)
237 + rows.append({"prov": prov, "n": int(held.sum()), "r2_within": float(r2)})
238 + return pd.DataFrame(rows).sort_values("r2_within", ascending=False)
239 +
240 +
241 +# --------------------------------------------------------------------------
242 +def main() -> None:
243 + ensure_dirs()
244 + s = sample.load_sample()
245 + results = {}
246 +
247 + oos = out_of_sample(s)
248 + json.dump(oos, open(REPRODUCED / "oos.json", "w"), indent=2)
249 + print("OOS:", {k: round(v, 3) for k, v in oos.items()})
250 +
251 + robustness(s).to_csv(REPRODUCED / "robustness.csv", index=False)
252 + print("robustness done")
253 +
254 + heterogeneity(s).to_csv(REPRODUCED / "heterogeneity.csv", index=False)
255 + print("heterogeneity done")
256 +
257 + quantile_regressions(s).to_csv(REPRODUCED / "quantile.csv", index=False)
258 + print("quantile done")
259 +
260 + results["nonlin"], band = nonlinearity(s)
261 + band.to_csv(REPRODUCED / "nonlinear_band.csv", index=False)
262 + print("nonlinearity:", results["nonlin"])
263 +
264 + results["gradient"], banded, loc_premium = urban_gradient(s)
265 + banded.to_csv(REPRODUCED / "gradient_bins.csv", index=False)
266 + print("gradient:", results["gradient"])
267 +
268 + results["moran"] = spatial_diagnostics(s, loc_premium)
269 + print("moran:", {k: round(v, 3) for k, v in results["moran"].items()})
270 +
271 + lopo = leave_one_province_out(s)
272 + lopo.to_csv(REPRODUCED / "lopo.csv", index=False)
273 + results["lopo_mean"] = float(lopo["r2_within"].mean())
274 + print("LOPO mean within-province R2:", round(results["lopo_mean"], 3))
275 +
276 + json.dump(results, open(REPRODUCED / "ext2.json", "w"), indent=2)
277 + print("ALL EXTENDED ANALYSES DONE")
278 +
279 +
280 +if __name__ == "__main__":
281 + main()
added scripts/04_make_figures.py +379 −0
@@ -0,0 +1,379 @@
1 +#!/usr/bin/env python3
2 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
3 +"""Step 04 — Generate every figure used in the paper (17 PNG files).
4 +
5 +Number-bearing summary figures (R^2 ladder, variance decomposition, OOS
6 +accuracy, FSA premia, heterogeneity, quantile) are drawn from the results
7 +tier selected with ``--results`` so the paper's published numbers are used by
8 +default; distribution/scatter/map figures are drawn from the micro sample.
9 +
10 +Usage: python scripts/04_make_figures.py [--results reference|reproduced]
11 +"""
12 +import argparse
13 +import json
14 +import sys
15 +from pathlib import Path
16 +
17 +import numpy as np
18 +import pandas as pd
19 +
20 +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
21 +
22 +from wp9 import models, sample # noqa: E402
23 +from wp9.config import FIGURES, REFERENCE, REPRODUCED, RESULTS, ensure_dirs # noqa: E402
24 +from wp9.plotstyle import (ACCENT, ACCENT2, ACCENT3, GREEN, GREY, LIGHT, # noqa: E402
25 + NEUTRAL, ORANGE, apply_style)
26 +
27 +apply_style()
28 +import matplotlib.pyplot as plt # noqa: E402
29 +import statsmodels.api as sm # noqa: E402
30 +
31 +PROVINCE_NAMES = {"ON": "Ontario", "QC": "Quebec", "BC": "British Columbia",
32 + "AB": "Alberta", "SK": "Saskatchewan", "MB": "Manitoba",
33 + "NS": "Nova Scotia", "NL": "Nfld. & Labrador", "NB": "New Brunswick"}
34 +
35 +
36 +def save(fig, name):
37 + fig.tight_layout()
38 + fig.savefig(FIGURES / name, bbox_inches="tight")
39 + plt.close(fig)
40 + print(" fig", name)
41 +
42 +
43 +# ---------------------------------------------------------------- micro-data
44 +def fig_price_dist(s):
45 + fig, ax = plt.subplots(1, 2, figsize=(11, 4))
46 + shown = s[s["price_cad"] <= 3e6]["price_cad"]
47 + ax[0].hist(shown / 1e3, bins=80, color=ACCENT, alpha=0.9)
48 + ax[0].axvline(s["price_cad"].median() / 1e3, color=ACCENT2, ls="--", lw=1.2,
49 + label=f"median \\${s['price_cad'].median():,.0f}")
50 + ax[0].set_xlabel("List price (thousand CAD, truncated at \\$3M)")
51 + ax[0].set_ylabel("Listings")
52 + ax[0].set_title("(a) Raw list price")
53 + ax[0].legend()
54 + ax[1].hist(s["ln_price"], bins=80, color=ACCENT, alpha=0.9)
55 + ax[1].set_xlabel("ln(price)")
56 + ax[1].set_title("(b) Log price (dependent variable)")
57 + save(fig, "fig_price_dist.png")
58 +
59 +
60 +def fig_province_ppm2(s):
61 + g = (s.groupby("prov")["ppm2"].agg(["median", "mean"])
62 + .sort_values("median"))
63 + fig, ax = plt.subplots(figsize=(7.5, 4.2))
64 + y = np.arange(len(g))
65 + ax.barh(y, g["median"], color=ACCENT, alpha=0.9, label="median")
66 + ax.barh(y, (g["mean"] - g["median"]).clip(lower=0), left=g["median"],
67 + color=GREY, alpha=0.55, label="mean$-$median gap")
68 + ax.set_yticks(y)
69 + ax.set_yticklabels([PROVINCE_NAMES.get(p, p) for p in g.index])
70 + ax.set_xlabel("Price per m$^2$ of living area (CAD)")
71 + ax.set_title("Price per square metre by province")
72 + ax.legend()
73 + save(fig, "fig_province_ppm2.png")
74 +
75 +
76 +def fig_size_gradient(s):
77 + bins = np.exp(np.linspace(np.log(45), np.log(470), 14))
78 + banded = (s.assign(band=pd.cut(s["living_m2"], bins))
79 + .groupby(["band", "cat"], observed=True)
80 + .agg(x=("living_m2", "median"), price=("price_cad", "median"),
81 + n=("price_cad", "size"))
82 + .reset_index())
83 + fig, ax = plt.subplots(figsize=(7, 4.4))
84 + for cat, colour, label in (("house", ACCENT, "Houses"), ("condo", ACCENT2, "Condominiums")):
85 + g = banded[(banded["cat"] == cat) & (banded["n"] >= 30)]
86 + ax.plot(g["x"], g["price"] / 1e3, "o-", color=colour, lw=2, ms=5, label=label)
87 + ax.set_xscale("log")
88 + ax.set_yscale("log")
89 + ax.set_xlabel("Living area (m$^2$, log scale)")
90 + ax.set_ylabel("Median list price (thousand CAD, log scale)")
91 + ax.set_title("Median price by living-area bin and dwelling type")
92 + ax.legend()
93 + save(fig, "fig_size_gradient.png")
94 +
95 +
96 +def _canada_axes(ax, s):
97 + ax.set_xlim(-140, -50)
98 + ax.set_ylim(41, 61)
99 + ax.set_xlabel("Longitude")
100 + ax.set_ylabel("Latitude")
101 + for prov, g in s.groupby("prov"):
102 + if len(g) < 400:
103 + continue
104 + ax.annotate(prov, (g["lon"].median(), g["lat"].quantile(0.9) + 1.2),
105 + fontsize=8, fontweight="bold", color="#333333", ha="center")
106 +
107 +
108 +def fig_maps(s):
109 + colour = np.log(s["ppm2"])
110 + fig, ax = plt.subplots(figsize=(7, 5))
111 + sc = ax.scatter(s["lon"], s["lat"], c=colour, s=2, alpha=0.35, cmap="viridis")
112 + _canada_axes(ax, s)
113 + ax.set_title("Listing locations, coloured by log price per m$^2$")
114 + fig.colorbar(sc, ax=ax, shrink=0.75, label="ln(price per m$^2$)")
115 + save(fig, "fig_map.png")
116 +
117 + g = (s.groupby("fsa")
118 + .agg(lat=("lat", "mean"), lon=("lon", "mean"),
119 + ppm2=("ppm2", "median"), n=("ppm2", "size")))
120 + g = g[g["n"] >= 25]
121 + fig, ax = plt.subplots(figsize=(7, 5))
122 + sc = ax.scatter(g["lon"], g["lat"], c=np.log(g["ppm2"]),
123 + s=np.sqrt(g["n"]) * 1.8, alpha=0.75, cmap="viridis",
124 + edgecolors="white", linewidths=0.2)
125 + _canada_axes(ax, s)
126 + ax.set_title("FSA neighbourhood medians (bubble area $\\propto\\sqrt{\\mathrm{listings}}$)")
127 + fig.colorbar(sc, ax=ax, shrink=0.75, label="ln(median price per m$^2$)")
128 + save(fig, "fig_fsa_map.png")
129 +
130 +
131 +def fig_fit_resid():
132 + grand = pd.read_parquet(REPRODUCED / "grand_model.parquet")
133 + fig, ax = plt.subplots(figsize=(5.4, 5.2))
134 + ax.hexbin(grand["pred_grand"], grand["ln_price"], gridsize=90, cmap="Blues",
135 + mincnt=1, bins="log")
136 + lims = [grand["ln_price"].min(), grand["ln_price"].max()]
137 + ax.plot(lims, lims, color=ACCENT2, lw=1.4, ls="--")
138 + ax.set_xlabel("Predicted ln(price)")
139 + ax.set_ylabel("Actual ln(price)")
140 + ax.set_title("Grand model: predicted vs. actual")
141 + save(fig, "fig_fit.png")
142 +
143 + resid = grand["resid_grand"]
144 + fig, ax = plt.subplots(1, 2, figsize=(9.6, 4.1))
145 + ax[0].hist(resid, bins=100, color=ACCENT, alpha=0.9, density=True)
146 + grid = np.linspace(resid.quantile(0.001), resid.quantile(0.999), 200)
147 + ax[0].plot(grid, np.exp(-0.5 * ((grid - resid.mean()) / resid.std()) ** 2)
148 + / (resid.std() * np.sqrt(2 * np.pi)), color=ACCENT2, lw=1.5,
149 + label="Normal density")
150 + ax[0].set_xlabel("Residual")
151 + ax[0].set_title("(a) Residual distribution")
152 + ax[0].legend()
153 + sm.qqplot(resid, line="45", fit=True, ax=ax[1], markerfacecolor=ACCENT,
154 + markeredgecolor=ACCENT, markersize=2, alpha=0.4)
155 + ax[1].set_title("(b) Normal Q--Q plot")
156 + save(fig, "fig_resid.png")
157 +
158 +
159 +def fig_moran(res_dir):
160 + ext2 = json.load(open(res_dir / "ext2.json"))
161 + coords = np.load(REPRODUCED / "moran_coords.npy")
162 + panels = [("Structural-only residuals", np.load(REPRODUCED / "moran_resid_struct.npy"),
163 + ext2["moran"]["struct_I"]),
164 + ("Grand model (FSA FE) residuals", np.load(REPRODUCED / "moran_resid_grand.npy"),
165 + ext2["moran"]["grand_I"])]
166 + from sklearn.neighbors import NearestNeighbors
167 + fig, ax = plt.subplots(1, 2, figsize=(11, 4.4))
168 + for j, (title, resid, moran) in enumerate(panels):
169 + nn = NearestNeighbors(n_neighbors=11).fit(coords)
170 + _, idx = nn.kneighbors(coords)
171 + z = resid - resid.mean()
172 + lag = z[idx[:, 1:]].mean(axis=1)
173 + ax[j].scatter(z, lag, s=3, alpha=0.15, color=ACCENT)
174 + slope, intercept = np.polyfit(z, lag, 1)
175 + xs = np.linspace(z.min(), z.max(), 10)
176 + ax[j].plot(xs, slope * xs + intercept, color=ACCENT2, lw=1.8)
177 + ax[j].axhline(0, color="k", lw=0.5)
178 + ax[j].axvline(0, color="k", lw=0.5)
179 + ax[j].set_xlabel("Residual ($z$)")
180 + ax[j].set_ylabel("Spatial lag of residual")
181 + ax[j].set_title(f"{title}\nMoran's I = {moran:.3f}")
182 + save(fig, "fig_moran.png")
183 +
184 +
185 +def fig_gradient(res_dir):
186 + banded = pd.read_csv(REPRODUCED / "gradient_bins.csv")
187 + fig, ax = plt.subplots(figsize=(7, 4.2))
188 + ax.plot(banded["x"], (np.exp(banded["prem"]) - 1) * 100, "o-", color=ACCENT, lw=2)
189 + ax.axhline(0, color="k", lw=0.7, ls=":")
190 + ax.set_xscale("symlog")
191 + ax.set_xlabel("Distance to nearest major metro (km, symlog)")
192 + ax.set_ylabel("Location premium vs structure-only (%)")
193 + ax.set_title("The urban price gradient: value falls with distance to metro")
194 + save(fig, "fig_gradient.png")
195 +
196 +
197 +def fig_nonlinear(res_dir):
198 + band = pd.read_csv(REPRODUCED / "nonlinear_band.csv")
199 + baseline = pd.read_csv(res_dir / "robustness.csv").iloc[0]["ln_living"]
200 + fig, ax = plt.subplots(figsize=(7, 4.2))
201 + area = np.exp(band["ln_area"])
202 + ax.plot(area, band["elasticity"], color=ACCENT, lw=2)
203 + ax.fill_between(area, band["elasticity"] - 1.96 * band["se"],
204 + band["elasticity"] + 1.96 * band["se"], color=ACCENT, alpha=0.18)
205 + ax.axhline(baseline, color=ACCENT2, ls="--", lw=1,
206 + label=f"linear-model elasticity ({baseline:.2f})")
207 + ax.set_xscale("log")
208 + ax.set_xlabel("Living area (m$^2$)")
209 + ax.set_ylabel("Marginal elasticity of price w.r.t. area")
210 + ax.set_title("Diminishing returns to floor space (quadratic spec., grand model)")
211 + ax.legend()
212 + save(fig, "fig_nonlinear.png")
213 +
214 +
215 +# ----------------------------------------------------------- results-driven
216 +def fig_r2(res_dir):
217 + fit = json.load(open(res_dir / "fit.json"))
218 + names = ["M1", "M2", "M3", "M4", "M5"]
219 + labels = ["M1\nStructural", "M2\n+Type/Own.", "M3\n+Province",
220 + "M4\nHouses+FSA", "M5\nGrand+FSA"]
221 + values = [fit[m]["r2"] for m in names]
222 + fig, ax = plt.subplots(figsize=(7.5, 4))
223 + bars = ax.bar(labels, values, color=[ACCENT, ACCENT, ACCENT, ACCENT3, ACCENT2], alpha=0.92)
224 + for bar, val in zip(bars, values):
225 + ax.text(bar.get_x() + bar.get_width() / 2, val + 0.012, f"{val:.3f}",
226 + ha="center", fontsize=9)
227 + ax.set_ylim(0, 0.9)
228 + ax.set_ylabel("$R^2$ (share of log-price variance explained)")
229 + ax.set_title("Explanatory power across the specification ladder")
230 + save(fig, "fig_r2.png")
231 +
232 +
233 +def fig_decomp(res_dir):
234 + fit = json.load(open(res_dir / "fit.json"))
235 + blocks = [("Structure", fit["M1"]["r2"]),
236 + ("Dwelling type & ownership", fit["M2"]["r2"] - fit["M1"]["r2"]),
237 + ("Province", fit["M3"]["r2"] - fit["M2"]["r2"]),
238 + ("Neighbourhood (FSA)", fit["M5"]["r2"] - fit["M3"]["r2"]),
239 + ("Unexplained", 1 - fit["M5"]["r2"])]
240 + colours = [ACCENT, ACCENT3, GREEN, ACCENT2, NEUTRAL]
241 + fig, ax = plt.subplots(figsize=(8, 2.4))
242 + left = 0.0
243 + for (label, share), colour in zip(blocks, colours):
244 + ax.barh(0, share, left=left, color=colour, edgecolor="white")
245 + if share > 0.03:
246 + ax.text(left + share / 2, 0, f"{label}\n{share * 100:.1f}%",
247 + ha="center", va="center", fontsize=8,
248 + color="black" if colour == NEUTRAL else "white")
249 + left += share
250 + ax.set_xlim(0, 1)
251 + ax.set_ylim(-0.5, 0.5)
252 + ax.set_yticks([])
253 + ax.set_xlabel("Share of log-price variance")
254 + ax.set_title("Variance decomposition of Canadian house prices")
255 + save(fig, "fig_decomp.png")
256 +
257 +
258 +def fig_forest(res_dir):
259 + coefs = pd.read_csv(res_dir / "coef_M3.csv", index_col=0)
260 + order = [("ln_living", "$\\ln$ living area"), ("bathrooms", "Full bathrooms"),
261 + ("half_baths", "Half bathrooms"), ("bedrooms", "Bedrooms"),
262 + ("parking_n", "Parking spaces"), ("stories_n", "Storeys"),
263 + ("ln_lot", "$\\ln(1+$lot m$^2)$")]
264 + rows = [(label, coefs.loc[key, "coef"], coefs.loc[key, "se"])
265 + for key, label in order if key in coefs.index]
266 + fig, ax = plt.subplots(figsize=(7, 4))
267 + y = np.arange(len(rows))[::-1]
268 + ax.errorbar([r[1] for r in rows], y, xerr=[1.96 * r[2] for r in rows],
269 + fmt="o", color=ACCENT, ecolor=GREY, capsize=3, ms=6)
270 + ax.axvline(0, color=ACCENT2, ls="--", lw=1)
271 + ax.set_yticks(y)
272 + ax.set_yticklabels([r[0] for r in rows])
273 + ax.set_xlabel("Coefficient on ln(price), 95% cluster-robust CI")
274 + ax.set_title("Structural implicit prices (houses, province-FE model M3)")
275 + save(fig, "fig_forest.png")
276 +
277 +
278 +def fig_heterogeneity(res_dir):
279 + het = pd.read_csv(res_dir / "heterogeneity.csv").sort_values("elast")
280 + fig, ax = plt.subplots(figsize=(7, 4))
281 + y = np.arange(len(het))
282 + ax.errorbar(het["elast"], y, xerr=1.96 * het["se_el"], fmt="o",
283 + color=ACCENT, ecolor=GREY, capsize=3, ms=6)
284 + ax.axvline(het["elast"].mean(), color=ACCENT2, ls="--", lw=1,
285 + label="cross-province mean")
286 + ax.set_yticks(y)
287 + ax.set_yticklabels([f"{p} (n={n:,})" for p, n in zip(het["prov"], het["n"])])
288 + ax.set_xlabel("Living-area elasticity (within-FSA)")
289 + ax.set_title("Heterogeneity in the size elasticity of price across provinces")
290 + ax.legend()
291 + save(fig, "fig_heterogeneity.png")
292 +
293 +
294 +def fig_premia(res_dir):
295 + premia = pd.read_csv(res_dir / "fsa_premia.csv")
296 + premia = premia.rename(columns={premia.columns[0]: "fsa"})
297 + shown = pd.concat([premia.nsmallest(12, "premium_pct"),
298 + premia.nlargest(12, "premium_pct")]).sort_values("premium_pct")
299 + colours = [ACCENT2 if v < 0 else ACCENT for v in shown["premium_pct"]]
300 + fig, ax = plt.subplots(figsize=(7.5, 5))
301 + ax.barh(np.arange(len(shown)), shown["premium_pct"], color=colours, alpha=0.9)
302 + ax.set_yticks(np.arange(len(shown)))
303 + ax.set_yticklabels([f"{f} ({p})" for f, p in zip(shown["fsa"], shown["prov"])],
304 + fontsize=8)
305 + ax.axvline(0, color="k", lw=0.8)
306 + ax.set_xlabel("Neighbourhood (FSA) price premium vs. national median (%), net of structure")
307 + ax.set_title("Highest- and lowest-valued neighbourhoods in Canada")
308 + save(fig, "fig_premia.png")
309 +
310 +
311 +def fig_quantile(res_dir):
312 + q = pd.read_csv(res_dir / "quantile.csv")
313 + taus = q[q["tau"].notna()]
314 + ols = q[q["tau"].isna()].iloc[0]
315 + fig, ax = plt.subplots(1, 2, figsize=(11, 4.2))
316 + for j, (var, se_var, title) in enumerate(
317 + [("ln_living", "se_living", "$\\ln$ living-area elasticity"),
318 + ("bathrooms", "se_bath", "Full-bathroom premium")]):
319 + ax[j].errorbar(taus["tau"], taus[var], yerr=1.96 * taus[se_var],
320 + fmt="o-", color=ACCENT, capsize=3, label="Quantile")
321 + ax[j].axhline(ols[var], color=ACCENT2, ls="--", label="OLS")
322 + ax[j].set_xlabel("Quantile of price ($\\tau$)")
323 + ax[j].set_title(title)
324 + ax[j].legend()
325 + save(fig, "fig_quantile.png")
326 +
327 +
328 +def fig_oos(res_dir):
329 + oos = json.load(open(res_dir / "oos.json"))
330 + within10 = oos["within10"]
331 + mid = oos["within20"] - oos["within10"]
332 + beyond = 100 - oos["within20"]
333 + fig, ax = plt.subplots(figsize=(6, 4))
334 + ax.bar([5, 15, 30], [within10, mid, beyond], width=8,
335 + color=[ACCENT, ACCENT3, LIGHT], alpha=0.9)
336 + for x, v, label in ((5, within10, "≤10%"), (15, mid, "10–20%"), (30, beyond, ">20%")):
337 + ax.text(x, v + 1, f"{label}\n{v:.0f}%", ha="center", fontsize=9)
338 + ax.axvline(oos["median_ape"], color=ACCENT2, ls="--",
339 + label=f"median APE {oos['median_ape']:.1f}%")
340 + ax.set_xticks([5, 15, 30])
341 + ax.set_xticklabels(["≤10%", "10–20%", ">20%"])
342 + ax.set_xlabel("Absolute percentage error (out-of-sample)")
343 + ax.set_ylabel("Share of test listings (%)")
344 + ax.set_ylim(0, 52)
345 + ax.set_title(f"Out-of-sample valuation accuracy (OOS $R^2$={oos['oos_r2']:.3f})", pad=12)
346 + ax.legend(loc="upper right", fontsize=8)
347 + save(fig, "fig_oos.png")
348 +
349 +
350 +def main() -> None:
351 + parser = argparse.ArgumentParser()
352 + parser.add_argument("--results", choices=["reference", "reproduced"],
353 + default="reference",
354 + help="results tier for number-bearing figures (default: reference)")
355 + args = parser.parse_args()
356 + res_dir = REFERENCE if args.results == "reference" else REPRODUCED
357 + ensure_dirs()
358 + s = sample.load_sample()
359 +
360 + fig_price_dist(s)
361 + fig_province_ppm2(s)
362 + fig_size_gradient(s)
363 + fig_maps(s)
364 + fig_fit_resid()
365 + fig_r2(res_dir)
366 + fig_decomp(res_dir)
367 + fig_forest(res_dir)
368 + fig_heterogeneity(res_dir)
369 + fig_premia(res_dir)
370 + fig_quantile(res_dir)
371 + fig_oos(res_dir)
372 + fig_nonlinear(res_dir)
373 + fig_gradient(res_dir)
374 + fig_moran(res_dir)
375 + print("all figures written to", FIGURES)
376 +
377 +
378 +if __name__ == "__main__":
379 + main()
added scripts/05_make_tables.py +233 −0
@@ -0,0 +1,233 @@
1 +#!/usr/bin/env python3
2 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
3 +"""Step 05 — Generate every LaTeX table used in the paper (6 files).
4 +
5 +Tables are built from the results tier selected with ``--results``; the
6 +default ``reference`` tier reproduces the published numbers exactly.
7 +The summary-statistics table additionally needs the micro sample when the
8 +``reproduced`` tier is selected.
9 +
10 +Usage: python scripts/05_make_tables.py [--results reference|reproduced]
11 +"""
12 +import argparse
13 +import json
14 +import sys
15 +from pathlib import Path
16 +
17 +import pandas as pd
18 +
19 +sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
20 +
21 +from wp9 import sample # noqa: E402
22 +from wp9.config import REFERENCE, REPRODUCED, TABLES, ensure_dirs # noqa: E402
23 +
24 +SUMMARY_VARS = [("price_cad", "List price (CAD)", "{:,.0f}"),
25 + ("ppm2", "Price per m$^2$ (CAD)", "{:,.0f}"),
26 + ("living_m2", "Living area (m$^2$)", "{:,.1f}"),
27 + ("bedrooms", "Bedrooms", "{:.2f}"),
28 + ("bathrooms", "Full bathrooms", "{:.2f}"),
29 + ("half_baths", "Half bathrooms", "{:.2f}"),
30 + ("parking_n", "Parking spaces", "{:.2f}"),
31 + ("stories_n", "Storeys", "{:.2f}"),
32 + ("lot_m2_f", "Lot area (m$^2$)", "{:,.0f}")]
33 +
34 +COEF_ORDER = [("ln_living", "$\\ln$ living area"), ("bathrooms", "Full bathrooms"),
35 + ("half_baths", "Half bathrooms"), ("bedrooms", "Bedrooms"),
36 + ("parking_n", "Parking spaces"), ("stories_n", "Storeys"),
37 + ("has_lot", "Has lot info"), ("ln_lot", "$\\ln(1+$lot m$^2)$")]
38 +
39 +
40 +def write(name: str, content: str) -> None:
41 + (TABLES / name).write_text(content + "\n")
42 + print(" tab", name)
43 +
44 +
45 +def stars(p: float) -> str:
46 + return "$^{***}$" if p < 0.01 else "$^{**}$" if p < 0.05 else "$^{*}$" if p < 0.1 else ""
47 +
48 +
49 +def cell(coefs: pd.DataFrame, key: str) -> str:
50 + if key not in coefs.index:
51 + return ""
52 + b, se, p = coefs.loc[key, ["coef", "se", "p"]]
53 + return f"\\makecell{{{b:.3f}{stars(p)}\\\\\\scriptsize({se:.3f})}}"
54 +
55 +
56 +# --------------------------------------------------------------------------
57 +def table_summary_stats(res_dir: Path) -> None:
58 + stats_file = res_dir / "summary_stats.csv"
59 + if stats_file.exists():
60 + stats = pd.read_csv(stats_file, index_col=0)
61 + n = int(stats.attrs.get("n", 0)) or int(stats["n"].iloc[0])
62 + else: # reproduced tier: compute from the micro sample
63 + s = sample.load_sample()
64 + rows = {}
65 + for var, _, _ in SUMMARY_VARS:
66 + col = s[var]
67 + rows[var] = {"mean": col.mean(), "sd": col.std(), "p25": col.quantile(0.25),
68 + "median": col.median(), "p75": col.quantile(0.75), "n": len(s)}
69 + stats = pd.DataFrame(rows).T
70 + stats.to_csv(res_dir / "summary_stats.csv")
71 + n = len(s)
72 + lines = []
73 + for var, label, fmt in SUMMARY_VARS:
74 + r = stats.loc[var]
75 + lines.append(f"{label} & {fmt.format(r['mean'])} & {fmt.format(r['sd'])} & "
76 + f"{fmt.format(r['p25'])} & {fmt.format(r['median'])} & "
77 + f"{fmt.format(r['p75'])} \\\\")
78 + write("summary_stats.tex",
79 + "\\begin{table}[t]\\centering\n\\caption{Descriptive statistics}\n"
80 + "\\label{tab:summary_stats}\n\\begin{threeparttable}\n"
81 + "\\begin{tabular}{lccccc}\n\\toprule\n"
82 + "Variable & Mean & SD & P25 & Median & P75 \\\\\n\\midrule\n"
83 + + "\n".join(lines) +
84 + "\n\\bottomrule\n\\end{tabular}\n\\begin{tablenotes}\\footnotesize\\item "
85 + f"Notes: Estimation sample of {n:,} residential dwellings (houses, "
86 + "condominiums, plexes, townhouses and apartments) from the Canadian MLS, "
87 + "after parsing and trimming the extreme 1\\% tails of price and living area.\n"
88 + "\\end{tablenotes}\n\\end{threeparttable}\n\\end{table}")
89 +
90 +
91 +# --------------------------------------------------------------------------
92 +def table_regression(res_dir: Path) -> None:
93 + fit = json.load(open(res_dir / "fit.json"))
94 + coefs = {m: pd.read_csv(res_dir / f"coef_{m}.csv", index_col=0)
95 + for m in ("M1", "M2", "M3", "M5")}
96 + lines = [label + " & " + " & ".join(cell(coefs[m], key) for m in ("M1", "M2", "M3", "M5"))
97 + + " \\\\" for key, label in COEF_ORDER]
98 + footer = ["\\midrule",
99 + "Dwelling-type FE & No & Yes & Yes & Yes \\\\",
100 + "Ownership FE & No & Yes & Yes & Yes \\\\",
101 + "Province FE & No & No & Yes & --- \\\\",
102 + "FSA fixed effects & No & No & No & Yes \\\\",
103 + f"$R^2$ & {fit['M1']['r2']:.3f} & {fit['M2']['r2']:.3f} & "
104 + f"{fit['M3']['r2']:.3f} & {fit['M5']['r2']:.3f} \\\\",
105 + f"Observations & {fit['M1']['n']:,} & {fit['M2']['n']:,} & "
106 + f"{fit['M3']['n']:,} & {fit['M5']['n']:,} \\\\"]
107 + write("regression.tex",
108 + "\\begin{table}[t]\\centering\n\\caption{Hedonic regression estimates}\n"
109 + "\\label{tab:regression}\n\\begin{threeparttable}\n"
110 + "\\begin{tabular}{lcccc}\n\\toprule\n"
111 + " & (1) & (2) & (3) & (4) \\\\\n"
112 + " & Structural & +Type/Own. & +Province & Grand+FSA \\\\\n\\midrule\n"
113 + + "\n".join(lines + footer) +
114 + "\n\\bottomrule\n\\end{tabular}\n\\begin{tablenotes}\\footnotesize\\item "
115 + "Notes: Dependent variable is $\\ln(\\text{price})$. Columns (1)--(3) use the "
116 + "house subsample; column (4) is the grand model over all residential dwellings "
117 + "with 1{,}153 absorbed FSA fixed effects. Cluster-robust standard errors "
118 + "(by FSA) in parentheses. $^{*}p<0.1$, $^{**}p<0.05$, $^{***}p<0.01$.\n"
119 + "\\end{tablenotes}\n\\end{threeparttable}\n\\end{table}")
120 +
121 +
122 +# --------------------------------------------------------------------------
123 +def table_robustness(res_dir: Path) -> None:
124 + rob = pd.read_csv(res_dir / "robustness.csv")
125 + lines = []
126 + for _, r in rob.iterrows():
127 + lines.append(
128 + f"{r['label']} & {r['n']:,.0f} & {r['r2']:.3f} & "
129 + f"\\makecell{{{r['ln_living']:.3f}\\\\\\scriptsize({r['se_living']:.3f})}} & "
130 + f"\\makecell{{{r['bathrooms']:.3f}\\\\\\scriptsize({r['se_bath']:.3f})}} & "
131 + f"\\makecell{{{r['ln_lot']:.3f}\\\\\\scriptsize({r['se_lot']:.3f})}} \\\\")
132 + write("robustness.tex",
133 + "\\begin{table}[t]\\centering\n"
134 + "\\caption{Robustness of key implicit prices across samples}\n"
135 + "\\label{tab:robustness}\n\\begin{threeparttable}\n"
136 + "\\begin{tabular}{lccccc}\n\\toprule\n"
137 + "Sample / specification & $N$ & $R^2$ & $\\ln$ area & Full bath & $\\ln$ lot \\\\\n"
138 + "\\midrule\n" + "\n".join(lines) +
139 + "\n\\bottomrule\n\\end{tabular}\n\\begin{tablenotes}\\footnotesize\\item "
140 + "Notes: Each row re-estimates the grand FSA-fixed-effects model on a different "
141 + "sample. Cluster-robust (FSA) standard errors in parentheses. The size elasticity "
142 + "and bathroom premium are stable across all cuts.\n"
143 + "\\end{tablenotes}\n\\end{threeparttable}\n\\end{table}")
144 +
145 +
146 +# --------------------------------------------------------------------------
147 +def table_quantile(res_dir: Path) -> None:
148 + q = pd.read_csv(res_dir / "quantile.csv")
149 + taus = q[q["tau"].notna()]
150 + ols = q[q["tau"].isna()].iloc[0]
151 + lines = []
152 + for _, r in taus.iterrows():
153 + tau = f"{r['tau']:g}"
154 + lines.append(
155 + f"$\\tau={tau}$ & "
156 + f"\\makecell{{{r['ln_living']:.3f}\\\\\\scriptsize({r['se_living']:.3f})}} & "
157 + f"\\makecell{{{r['bathrooms']:.3f}\\\\\\scriptsize({r['se_bath']:.3f})}} & "
158 + f"\\makecell{{{r['ln_lot']:.3f}\\\\\\scriptsize({r['se_lot']:.3f})}} \\\\")
159 + write("quantile.tex",
160 + "\\begin{table}[t]\\centering"
161 + "\\caption{Quantile hedonic estimates across the price distribution}\n"
162 + "\\label{tab:quantile}\\begin{threeparttable}\\begin{tabular}{lccc}\n\\toprule\n"
163 + "Quantile & $\\ln$ area & Full bath & $\\ln$ lot \\\\\n\\midrule\n"
164 + + "\n".join(lines) + "\n\\midrule\nOLS & "
165 + f"{ols['ln_living']:.3f} & {ols['bathrooms']:.3f} & {ols['ln_lot']:.3f} \\\\\n"
166 + "\\bottomrule\\end{tabular}\\begin{tablenotes}\\footnotesize\\item Notes: House "
167 + "subsample, province fixed effects, structural controls. Analytical standard "
168 + "errors in parentheses. The size elasticity rises and the lot elasticity rises "
169 + "with price.\\end{tablenotes}\\end{threeparttable}\\end{table}")
170 +
171 +
172 +# --------------------------------------------------------------------------
173 +def table_lopo(res_dir: Path) -> None:
174 + lopo = pd.read_csv(res_dir / "lopo.csv")
175 + lines = [f"{r['prov']} & {r['n']:,.0f} & {r['r2_within']:.3f} \\\\"
176 + for _, r in lopo.iterrows()]
177 + write("lopo.tex",
178 + "\\begin{table}[t]\\centering"
179 + "\\caption{Leave-one-province-out spatial cross-validation}\n"
180 + "\\label{tab:lopo}\\begin{threeparttable}\\begin{tabular}{lcc}\n\\toprule\n"
181 + "Held-out province & $N$ & Within-province $R^2$ \\\\\n\\midrule\n"
182 + + "\n".join(lines) +
183 + f"\n\\midrule\nMean & --- & {lopo['r2_within'].mean():.3f} \\\\\n"
184 + "\\bottomrule\\end{tabular}\\begin{tablenotes}\\footnotesize\\item Notes: The "
185 + "structural hedonic model is estimated on all provinces except one and used to "
186 + "predict the held-out province; a province-specific intercept is allowed (the "
187 + "price \\emph{level} is not identified out of sample), so the metric captures "
188 + "whether the \\emph{structural} implicit prices transfer across space."
189 + "\\end{tablenotes}\\end{threeparttable}\\end{table}")
190 +
191 +
192 +# --------------------------------------------------------------------------
193 +def table_oos(res_dir: Path) -> None:
194 + oos = json.load(open(res_dir / "oos.json"))
195 + write("oos.tex",
196 + "\\begin{table}[t]\\centering\n"
197 + "\\caption{Out-of-sample valuation performance (80/20 split)}\n"
198 + "\\label{tab:oos}\n\\begin{threeparttable}\n\\begin{tabular}{lc}\n\\toprule\n"
199 + "Metric & Value \\\\\n\\midrule\n"
200 + f"Training listings & {oos['n_train']:,} \\\\\n"
201 + f"Test listings & {oos['n_test']:,} \\\\\n"
202 + f"Out-of-sample $R^2$ (log price) & {oos['oos_r2']:.3f} \\\\\n"
203 + f"RMSE (log points) & {oos['rmse_log']:.3f} \\\\\n"
204 + f"Median absolute \\% error & {oos['median_ape']:.1f}\\% \\\\\n"
205 + f"Mean absolute \\% error & {oos['mean_ape']:.1f}\\% \\\\\n"
206 + f"Share priced within $\\pm$10\\% & {oos['within10']:.1f}\\% \\\\\n"
207 + f"Share priced within $\\pm$20\\% & {oos['within20']:.1f}\\% \\\\\n"
208 + "\\bottomrule\n\\end{tabular}\n\\begin{tablenotes}\\footnotesize\\item Notes: "
209 + "Model trained on a random 80\\% of listings and scored on the held-out 20\\% "
210 + "(restricted to neighbourhoods observed in training). Prices back-transformed "
211 + "with Duan's smearing estimator.\n"
212 + "\\end{tablenotes}\n\\end{threeparttable}\n\\end{table}")
213 +
214 +
215 +def main() -> None:
216 + parser = argparse.ArgumentParser()
217 + parser.add_argument("--results", choices=["reference", "reproduced"],
218 + default="reference",
219 + help="results tier (default: reference — published numbers)")
220 + args = parser.parse_args()
221 + res_dir = REFERENCE if args.results == "reference" else REPRODUCED
222 + ensure_dirs()
223 + table_summary_stats(res_dir)
224 + table_regression(res_dir)
225 + table_robustness(res_dir)
226 + table_quantile(res_dir)
227 + table_lopo(res_dir)
228 + table_oos(res_dir)
229 + print("all tables written to", TABLES)
230 +
231 +
232 +if __name__ == "__main__":
233 + main()
added src/wp9/__init__.py +11 −0
@@ -0,0 +1,11 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""WP9 — A Grand Hedonic Model of the Canadian Housing Market.
3 +
4 +Analysis package for UQO Working Paper No. 9. Modules:
5 +
6 +- ``config`` paths and global constants
7 +- ``parsing`` parsers for the semi-structured raw MLS fields
8 +- ``sample`` construction of the estimation sample from the raw DuckDB
9 +- ``models`` design matrices and the M1–M5 hedonic specification ladder
10 +- ``plotstyle`` shared matplotlib style and colour palette
11 +"""
added src/wp9/config.py +57 −0
@@ -0,0 +1,57 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""Paths and global constants for the WP9 pipeline.
3 +
4 +All paths are relative to the repository root, so the pipeline runs on any
5 +machine after cloning. Override the root with the ``WP9_ROOT`` environment
6 +variable if the scripts are launched from elsewhere.
7 +"""
8 +import os
9 +from pathlib import Path
10 +
11 +ROOT = Path(os.environ.get("WP9_ROOT", Path(__file__).resolve().parents[2]))
12 +
13 +RAW_DB = ROOT / "data" / "raw" / "realtor_mls_unique.duckdb"
14 +PROCESSED = ROOT / "data" / "processed"
15 +ANALYSIS_PARQUET = PROCESSED / "analysis.parquet"
16 +FIGURES = ROOT / "figures"
17 +RESULTS = ROOT / "results"
18 +REFERENCE = RESULTS / "reference" # original (canonical) outputs — paper numbers
19 +REPRODUCED = RESULTS / "reproduced" # outputs regenerated by this pipeline
20 +TABLES = RESULTS / "tables"
21 +
22 +# Unit conversions (as documented in the paper's data section)
23 +SQFT_TO_M2 = 0.0929023
24 +ACRE_TO_M2 = 4046.86
25 +HA_TO_M2 = 10_000.0
26 +
27 +# Sample construction
28 +TRIM_LO, TRIM_HI = 0.01, 0.99 # 1% tails of price and living area
29 +FSA_MIN_LISTINGS = 25 # FSAs below this are pooled into <PROV>_other
30 +LOT_TAIL_Q = 0.99 # positive lot areas above this quantile set to 0 (unparseable/exotic)
31 +
32 +# Structural regressors used in every specification
33 +STRUCT = ["ln_living", "bedrooms", "bathrooms", "half_baths",
34 + "parking_n", "stories_n", "has_lot", "ln_lot"]
35 +
36 +# Random seeds (identical to the original analysis scripts)
37 +SEED_OOS = 12345
38 +SEED_MORAN = 3
39 +SEED_EXT2 = 7
40 +
41 +# Nine major metropolitan centres for the urban-gradient analysis
42 +METROS = {
43 + "Toronto": (43.65, -79.38),
44 + "Montreal": (45.50, -73.57),
45 + "Vancouver": (49.28, -123.12),
46 + "Calgary": (51.05, -114.07),
47 + "Ottawa-Gatineau": (45.42, -75.70),
48 + "Edmonton": (53.55, -113.49),
49 + "Winnipeg": (49.90, -97.14),
50 + "Quebec City": (46.81, -71.21),
51 + "Halifax": (44.65, -63.58),
52 +}
53 +
54 +def ensure_dirs() -> None:
55 + """Create every output directory the pipeline writes to."""
56 + for p in (PROCESSED, FIGURES, REFERENCE, REPRODUCED, TABLES):
57 + p.mkdir(parents=True, exist_ok=True)
added src/wp9/models.py +105 −0
@@ -0,0 +1,105 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""Design matrices and the M1–M5 hedonic specification ladder.
3 +
4 +The semi-logarithmic hedonic equation regresses ln(price) on structural
5 +attributes, dwelling-type/ownership dummies and location fixed effects.
6 +FSA fixed effects are absorbed with ``linearmodels.AbsorbingLS`` (numerically
7 +identical to full-dummy OLS); standard errors are clustered by FSA.
8 +"""
9 +import numpy as np
10 +import pandas as pd
11 +import statsmodels.api as sm
12 +from linearmodels.iv.absorbing import AbsorbingLS
13 +
14 +from .config import STRUCT
15 +
16 +
17 +def design(data: pd.DataFrame, extra: pd.DataFrame | None = None) -> pd.DataFrame:
18 + """Structural regressors + dwelling-type, ownership and category dummies."""
19 + blocks = [data[STRUCT].astype(float)]
20 + if extra is not None:
21 + blocks.append(extra)
22 + blocks += [pd.get_dummies(data[col], prefix=pfx, drop_first=True).astype(float)
23 + for col, pfx in (("btype_c", "bt"), ("own_c", "ow"), ("cat", "cat"))]
24 + return sm.add_constant(pd.concat(blocks, axis=1))
25 +
26 +
27 +def fit_absorbing(data: pd.DataFrame, extra: pd.DataFrame | None = None):
28 + """FSA-fixed-effects hedonic model with FSA-clustered standard errors.
29 +
30 + Returns the fitted AbsorbingLS results and the design column order.
31 + """
32 + X = design(data, extra=extra)
33 + res = AbsorbingLS(data["ln_price"], X,
34 + absorb=data[["fsa_c"]].astype("category"),
35 + drop_absorbed=True).fit(cov_type="clustered",
36 + clusters=data[["fsa_c"]])
37 + return res, X.columns.tolist()
38 +
39 +
40 +def coef_table(res, columns=None) -> pd.DataFrame:
41 + """Coefficient / SE / p-value table indexed by regressor name.
42 +
43 + Works for both statsmodels (``bse``) and linearmodels (``std_errors``);
44 + uses the estimator's own parameter index, which may exclude regressors
45 + dropped as collinear with the absorbed effects.
46 + """
47 + se = res.std_errors if hasattr(res, "std_errors") else res.bse
48 + index = res.params.index if hasattr(res.params, "index") else columns
49 + return pd.DataFrame({
50 + "coef": pd.Series(np.asarray(res.params).ravel(), index=index),
51 + "se": pd.Series(np.asarray(se).ravel(), index=index),
52 + "p": pd.Series(np.asarray(res.pvalues).ravel(), index=index),
53 + })
54 +
55 +
56 +def fsa_fixed_effects(data: pd.DataFrame, res, columns=None) -> pd.Series:
57 + """Recover the absorbed FSA effects as within-FSA mean residuals of X'b."""
58 + beta = pd.Series(np.asarray(res.params).ravel(), index=res.params.index)
59 + xb = design(data).reindex(columns=beta.index, fill_value=0.0).values @ beta.values
60 + return (data["ln_price"] - xb).groupby(data["fsa_c"]).mean()
61 +
62 +
63 +def predict_with_fe(data: pd.DataFrame, res, columns, fe: pd.Series) -> np.ndarray:
64 + """Linear prediction X'b + absorbed FSA effect."""
65 + beta = pd.Series(np.asarray(res.params).ravel(), index=res.params.index)
66 + xb = design(data).reindex(columns=beta.index, fill_value=0.0).values @ beta.values
67 + return xb + data["fsa_c"].map(fe).values
68 +
69 +
70 +def specification_ladder(sample: pd.DataFrame) -> dict:
71 + """Estimate the M1–M5 ladder; returns {name: (results, columns, data)}.
72 +
73 + M1–M3 use the house subsample (structural; +type/ownership; +province);
74 + M4 is houses with FSA fixed effects; M5 is the grand model over all
75 + residential dwellings with FSA fixed effects.
76 + """
77 + houses = sample[sample["cat"] == "house"]
78 + out = {}
79 +
80 + X1 = sm.add_constant(houses[STRUCT].astype(float))
81 + out["M1"] = (sm.OLS(houses["ln_price"], X1)
82 + .fit(cov_type="cluster", cov_kwds={"groups": houses["fsa_c"]}),
83 + X1.columns.tolist(), houses)
84 +
85 + X2 = design(houses)
86 + out["M2"] = (sm.OLS(houses["ln_price"], X2)
87 + .fit(cov_type="cluster", cov_kwds={"groups": houses["fsa_c"]}),
88 + X2.columns.tolist(), houses)
89 +
90 + X3 = X2.join(pd.get_dummies(houses["prov"], prefix="pv", drop_first=True).astype(float))
91 + out["M3"] = (sm.OLS(houses["ln_price"], X3)
92 + .fit(cov_type="cluster", cov_kwds={"groups": houses["fsa_c"]}),
93 + X3.columns.tolist(), houses)
94 +
95 + res4, cols4 = fit_absorbing(houses)
96 + out["M4"] = (res4, cols4, houses)
97 +
98 + res5, cols5 = fit_absorbing(sample)
99 + out["M5"] = (res5, cols5, sample)
100 + return out
101 +
102 +
103 +def duan_smearing(residuals: np.ndarray) -> float:
104 + """Duan (1983) smearing factor for retransformation from logs."""
105 + return float(np.mean(np.exp(residuals)))
added src/wp9/parsing.py +166 −0
@@ -0,0 +1,166 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""Parsers for the semi-structured raw MLS fields.
3 +
4 +The raw ``listings`` table stores every attribute as free text. These
5 +functions harmonise them to numeric analysis variables:
6 +
7 +- bedrooms reported as ``"3 + 1"`` (main + lower level) are summed;
8 +- living area is taken from the explicit floor-area measurement
9 + (``building.floor_area_measurements``), using the upper bound of banded
10 + entries such as ``"1100-1500 sqft"``, and falls back to
11 + ``building.size_interior``; square feet are converted at
12 + 1 ft^2 = 0.0929 m^2;
13 +- lot size is recovered from the free-text ``land.size_total`` where a
14 + numeric value with a recognisable unit (sqft, m2, acres, hectares, or
15 + frontage x depth in feet) is present.
16 +
17 +NOTE — reconstruction: the original cleaning code lived in the upstream
18 +RE_DB_QC pipeline, which no longer exists. These rules were reverse-engineered
19 +from the description in the paper's data section and validated against the
20 +original sample counts, summary statistics and regression estimates
21 +(see AUDIT.md, "Reproduction verification").
22 +"""
23 +import re
24 +
25 +import numpy as np
26 +
27 +from .config import SQFT_TO_M2, ACRE_TO_M2, HA_TO_M2
28 +
29 +_RANGE = re.compile(r"([\d.,]+)\s*-\s*([\d.,]+)")
30 +_NUMBER = re.compile(r"([\d.,]+)")
31 +_UNFORMATTED = re.compile(r'"area_unformatted":\s*"([^"]+)"')
32 +_SIZE_WITH_UNIT = re.compile(r"([\d.,]+)\s*(\w*)")
33 +_LOT_UNIT = re.compile(r"([\d.,]+)\s*(sqft|sq ft|m2|ac|acre|acres|hectare|ha)\b")
34 +_LOT_UNDER = re.compile(r"under\s+([\d/.]+)\s*acre")
35 +_LOT_ACRE_RANGE = re.compile(r"([\d/.]+)\s*-\s*([\d.]+)\s*acres")
36 +_LOT_DIMS = re.compile(r"(\d+(?:\.\d+)?)\s*x\s*(\d+(?:\.\d+)?)")
37 +
38 +
39 +def _to_float(text: str) -> float:
40 + return float(text.replace(",", ""))
41 +
42 +
43 +def parse_bedrooms(value) -> float:
44 + """Sum the integer components of a bedroom string ('3 + 1' -> 4)."""
45 + if not isinstance(value, str):
46 + return np.nan
47 + parts = re.findall(r"\d+", value)
48 + return float(sum(int(p) for p in parts)) if parts else np.nan
49 +
50 +
51 +def parse_count(value) -> float:
52 + """Parse a plain numeric count field (bathrooms, storeys, parking)."""
53 + try:
54 + return float(value)
55 + except (TypeError, ValueError):
56 + return np.nan
57 +
58 +
59 +def parse_floor_area(value) -> float:
60 + """Living area in m^2 from ``building.floor_area_measurements``.
61 +
62 + Banded entries ("1100-1500 sqft") are mapped to the upper bound of the
63 + band; exact entries ("1698 sqft") are used as reported.
64 + """
65 + if not isinstance(value, str):
66 + return np.nan
67 + match = _UNFORMATTED.search(value)
68 + if not match:
69 + return np.nan
70 + text = match.group(1)
71 + band = _RANGE.match(text)
72 + if band:
73 + area = _to_float(band.group(2))
74 + else:
75 + number = _NUMBER.match(text)
76 + if not number:
77 + return np.nan
78 + area = _to_float(number.group(1))
79 + return area if "m2" in text else area * SQFT_TO_M2
80 +
81 +
82 +def parse_size_interior(value) -> float:
83 + """Living area in m^2 from ``building.size_interior`` ('102.19 m2', '1698 sqft')."""
84 + if not isinstance(value, str):
85 + return np.nan
86 + match = _SIZE_WITH_UNIT.match(value)
87 + if not match:
88 + return np.nan
89 + area = _to_float(match.group(1))
90 + unit = match.group(2).lower()
91 + return area if unit == "m2" else area * SQFT_TO_M2 # unitless values are sqft
92 +
93 +
94 +def parse_lot(value) -> float:
95 + """Lot area in m^2 from the free-text ``land.size_total`` field.
96 +
97 + Recognises '<n> sqft|m2|ac|acres|hectare|ha', 'under <x> acre(s)',
98 + '<a> - <b> acres' (upper bound), and '<w> x <d>' frontage-by-depth in
99 + feet. Returns NaN when no numeric value can be recovered.
100 + """
101 + if not isinstance(value, str):
102 + return np.nan
103 + text = value.lower().strip()
104 + match = _LOT_UNIT.match(text)
105 + if match:
106 + size = _to_float(match.group(1))
107 + unit = match.group(2)
108 + if unit in ("sqft", "sq ft"):
109 + return size * SQFT_TO_M2
110 + if unit == "m2":
111 + return size
112 + if unit.startswith("ac"):
113 + return size * ACRE_TO_M2
114 + return size * HA_TO_M2
115 + match = _LOT_UNDER.match(text)
116 + if match:
117 + frac = match.group(1)
118 + if "/" in frac:
119 + num, den = frac.split("/", 1)
120 + acres = float(num) / float(den)
121 + else:
122 + acres = float(frac)
123 + return acres * ACRE_TO_M2
124 + match = _LOT_ACRE_RANGE.match(text)
125 + if match:
126 + return float(match.group(2)) * ACRE_TO_M2
127 + match = _LOT_DIMS.match(text)
128 + if match:
129 + return float(match.group(1)) * float(match.group(2)) * SQFT_TO_M2
130 + return np.nan
131 +
132 +
133 +# Consolidation of raw dwelling types into the eight groups used in the paper
134 +BUILDING_TYPE_MAP = {
135 + "House": "House",
136 + "Apartment": "Apartment",
137 + "Row / Townhouse": "Row/Townhouse",
138 + "Duplex": "Duplex",
139 + "Triplex": "Triplex",
140 + "Fourplex": "Fourplex",
141 + "Manufactured Home": "Manufactured",
142 + "Manufactured Home/Mobile": "Manufactured",
143 + "Mobile Home": "Manufactured",
144 + "Park Model Mobile Home": "Manufactured",
145 +}
146 +
147 +
148 +def consolidate_building_type(value) -> str:
149 + """Map the raw ``building.type`` to the paper's eight dwelling-type groups."""
150 + return BUILDING_TYPE_MAP.get(value, "Other")
151 +
152 +
153 +def consolidate_ownership(value) -> str:
154 + """Map the raw ``ownership.type`` to the paper's ownership-form groups."""
155 + if not isinstance(value, str):
156 + return "Unknown"
157 + text = value.lower()
158 + if "lease" in text:
159 + return "Leasehold"
160 + if "condo" in text or "strata" in text:
161 + return "Condo/Strata"
162 + if "freehold" in text:
163 + return "Freehold"
164 + if "co-op" in text or "cooperative" in text or "co-ownership" in text:
165 + return "Co-op/Co-ownership"
166 + return "Other"
added src/wp9/plotstyle.py +27 −0
@@ -0,0 +1,27 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""Shared matplotlib style and colour palette for all WP9 figures."""
3 +import matplotlib
4 +
5 +matplotlib.use("Agg")
6 +import matplotlib.pyplot as plt # noqa: E402
7 +
8 +ACCENT = "#16365c" # dark navy — primary series
9 +ACCENT2 = "#a02020" # dark red — reference/contrast
10 +ACCENT3 = "#4a7ab5" # medium blue
11 +GREEN = "#2e7d32"
12 +ORANGE = "#e08214"
13 +GREY = "#888888"
14 +LIGHT = "#b0c4de"
15 +NEUTRAL = "#cccccc"
16 +
17 +
18 +def apply_style() -> None:
19 + """Serif fonts, open spines, print-quality DPI — applied by every figure script."""
20 + plt.rcParams.update({
21 + "font.size": 10,
22 + "figure.dpi": 150,
23 + "savefig.dpi": 220,
24 + "axes.spines.top": False,
25 + "axes.spines.right": False,
26 + "font.family": "serif",
27 + })
added src/wp9/sample.py +114 −0
@@ -0,0 +1,114 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""Construction of the estimation sample from the raw DuckDB snapshot.
3 +
4 +Steps (documented in the paper's data section):
5 +
6 +1. read the raw ``listings`` table (172,019 unique for-sale listings);
7 +2. parse the semi-structured fields (bedrooms, areas, lot, counts);
8 +3. consolidate dwelling type and ownership form; derive the FSA from the
9 + postal code;
10 +4. keep residential listings with a strictly positive price and non-missing
11 + core structural fields (living area, bedrooms, bathrooms) and a valid FSA;
12 +5. trim the extreme 1% tails of price and living area;
13 +6. pool FSAs with fewer than 25 listings into a province-level residual
14 + category.
15 +"""
16 +import duckdb
17 +import numpy as np
18 +import pandas as pd
19 +
20 +from . import parsing
21 +from .config import (ANALYSIS_PARQUET, FSA_MIN_LISTINGS, LOT_TAIL_Q, RAW_DB,
22 + TRIM_HI, TRIM_LO, ensure_dirs)
23 +
24 +_RAW_QUERY = """
25 +select "_category" as cat,
26 + "_province" as prov,
27 + "building.type" as btype_raw,
28 + "ownership.type" as own_raw,
29 + "building.bedrooms" as bed_raw,
30 + "building.bathroom_total" as bath_raw,
31 + "building.half_bath_total" as half_raw,
32 + "building.size_interior" as size_interior,
33 + "building.floor_area_measurements" as floor_area,
34 + "building.stories_total" as stories_raw,
35 + "parking.spaces_total" as parking_raw,
36 + "land.size_total" as lot_raw,
37 + "location.postal_code" as postal_code,
38 + price_cad, lat, lon
39 +from listings
40 +"""
41 +
42 +_FSA_PATTERN = r"^[A-Z]\d[A-Z]$"
43 +
44 +
45 +def load_raw() -> pd.DataFrame:
46 + """Read the raw listings table from the DuckDB snapshot."""
47 + with duckdb.connect(str(RAW_DB), read_only=True) as con:
48 + return con.execute(_RAW_QUERY).df()
49 +
50 +
51 +def parse_variables(raw: pd.DataFrame) -> pd.DataFrame:
52 + """Parse raw text fields into numeric/categorical analysis variables."""
53 + d = raw.copy()
54 + d["bedrooms"] = d["bed_raw"].map(parsing.parse_bedrooms)
55 + d["bathrooms"] = d["bath_raw"].map(parsing.parse_count)
56 + d["half_baths"] = d["half_raw"].map(parsing.parse_count).fillna(0.0)
57 + d["parking_n"] = d["parking_raw"].map(parsing.parse_count).fillna(0.0)
58 + d["stories_n"] = d["stories_raw"].map(parsing.parse_count).fillna(0.0)
59 + d["living_m2"] = (d["floor_area"].map(parsing.parse_floor_area)
60 + .fillna(d["size_interior"].map(parsing.parse_size_interior)))
61 +
62 + lot = d["lot_raw"].map(parsing.parse_lot)
63 + # Very large parsed lots (top 1% of positive values, mostly multi-acre
64 + # rural acreage strings) are treated as "no usable lot information".
65 + cap = lot[lot > 0].quantile(LOT_TAIL_Q)
66 + lot = lot.where(lot <= cap, np.nan)
67 + d["lot_m2_f"] = lot.fillna(0.0)
68 + d["has_lot"] = (d["lot_m2_f"] > 0).astype(float)
69 +
70 + d["btype_c"] = d["btype_raw"].map(parsing.consolidate_building_type)
71 + d["own_c"] = d["own_raw"].map(parsing.consolidate_ownership)
72 +
73 + fsa = d["postal_code"].astype("string").str.upper().str[:3]
74 + d["fsa"] = fsa.where(fsa.str.match(_FSA_PATTERN, na=False))
75 + return d
76 +
77 +
78 +def build_sample(d: pd.DataFrame) -> pd.DataFrame:
79 + """Apply the sample restrictions and derive the model variables."""
80 + core = ((d["price_cad"] > 0) & d["living_m2"].notna()
81 + & d["bedrooms"].notna() & d["bathrooms"].notna() & d["fsa"].notna())
82 + s = d[core].copy()
83 +
84 + lo_p, hi_p = s["price_cad"].quantile([TRIM_LO, TRIM_HI])
85 + lo_a, hi_a = s["living_m2"].quantile([TRIM_LO, TRIM_HI])
86 + s = s[(s["price_cad"].between(lo_p, hi_p)) & (s["living_m2"].between(lo_a, hi_a))].copy()
87 +
88 + s["ln_price"] = np.log(s["price_cad"])
89 + s["ln_living"] = np.log(s["living_m2"])
90 + s["ln_lot"] = np.log1p(s["lot_m2_f"])
91 + s["ppm2"] = s["price_cad"] / s["living_m2"]
92 +
93 + counts = s.groupby("fsa")["fsa"].transform("size")
94 + s["fsa_c"] = np.where(counts >= FSA_MIN_LISTINGS, s["fsa"], s["prov"] + "_other")
95 +
96 + keep = ["cat", "prov", "btype_c", "own_c", "fsa", "fsa_c",
97 + "price_cad", "ln_price", "ppm2",
98 + "living_m2", "ln_living", "bedrooms", "bathrooms", "half_baths",
99 + "parking_n", "stories_n", "lot_m2_f", "has_lot", "ln_lot",
100 + "lat", "lon"]
101 + return s[keep].reset_index(drop=True)
102 +
103 +
104 +def build_and_save() -> pd.DataFrame:
105 + """Full raw-to-parquet pipeline; returns the estimation sample."""
106 + ensure_dirs()
107 + sample = build_sample(parse_variables(load_raw()))
108 + sample.to_parquet(ANALYSIS_PARQUET, index=False)
109 + return sample
110 +
111 +
112 +def load_sample() -> pd.DataFrame:
113 + """Load the processed estimation sample (build it first with script 01)."""
114 + return pd.read_parquet(ANALYSIS_PARQUET)
115