révision scientifique complète (editorial board, 2026-10-17)
Version 2.1 (October 2026) : fuite du prix demandé dans les descriptions DuProprio documentée et quantifiée ; indicatrice de langue (43 % EN) ; EF RTA ; validation croisée spatiale ; bootstrap en grappes ; accord inter-sources des extractions ; sensibilité du blend ; affirmation « largest gain of any feature block » retirée ; température vision / alias de modèles / 15 aménités / 21 régresseurs vision corrigés ; bibliographie 35 -> 53 références vérifiées (DOI) ; docs/REVIEW-REPORT.md + docs/CHANGELOG-REVISION.md ; scripts 18-19 ; chemins exec des scripts 11-16 réparés. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
32 changed files +3,872 −506
modified
README.md
+77 −47
@@ -3,7 +3,7 @@ | ||
| 3 | 3 | |
| 4 | 4 | **UQO Working Paper No. 14** — *Evidence from Quebec Real-Estate Listings* |
| 5 | 5 | |
| 6 | −[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 6 | +[](paper/main.pdf) | |
| 7 | 7 | [](requirements.txt) |
| 8 | 8 | [](data/raw/README.md) |
| 9 | 9 | [](scripts/) |
@@ -12,11 +12,14 @@ | ||
| 12 | 12 | |
| 13 | 13 | > **TL;DR** — Much of a home's value is recorded only in the free text and the photographs of its listing. We use a |
| 14 | 14 | > large language model to turn each description into structured specifications and a vision–language model to turn the |
| 15 | −> façade photo into objective visual attributes, both under strict JSON schemas. On 19,123 Quebec house listings the two | |
| 16 | −> AI layers lift the R² of an already rich log-linear hedonic model from 0.717 to 0.755; the vision layer is the largest | |
| 17 | −> out-of-sample gain of any feature block for every estimator (OLS, gradient boosting, neural nets); the best ensemble | |
| 18 | −> reaches out-of-sample R² 0.779 with a 14.0% median absolute error. Implicit prices are economically sensible (+2.3% per | |
| 19 | −> point of curb appeal, +3–4% for brick or stone) and survive municipality-clustered inference. | |
| 15 | +> façade photo into visual attributes, both under strict JSON schemas. On 19,123 Quebec house listings the two AI | |
| 16 | +> layers lift the R² of an already rich log-linear hedonic model from 0.717 to 0.755 (3.0 of the 3.8 points come from | |
| 17 | +> the photo); the vision layer lifts every estimator (OLS, random forest, gradient boosting, neural nets) and adds more | |
| 18 | +> to OLS than switching to a random forest; the best ensemble reaches out-of-sample R² 0.779 with a 14.0% median | |
| 19 | +> absolute percentage error. Implicit prices are economically sensible (+2.3% per point of curb appeal, +3–4% for | |
| 20 | +> brick or stone) and survive municipality-clustered inference, a cluster bootstrap, postal-code (RTA) fixed effects | |
| 21 | +> and language controls. Caveat documented in v2.1: every DuProprio description embeds the asking price, so the text | |
| 22 | +> layer's gain is credible only on Realtor.ca (+0.6 pt in-sample). | |
| 20 | 23 | |
| 21 | 24 | --- |
| 22 | 25 | |
@@ -24,38 +27,44 @@ | ||
| 24 | 27 | |
| 25 | 28 | | Item | Value | |
| 26 | 29 | |---|---| |
| 27 | −| Version | 2.0 (July 2026) — revised draft after an internal review round (`scripts/13_revision_extras.py`) | | |
| 30 | +| Version | **2.1 (October 2026)** — revised 2026-10-17 by a full editorial-board review (`docs/REVIEW-REPORT.md`, `docs/CHANGELOG-REVISION.md`); 2.0 (July 2026) after an internal review round (`scripts/13_revision_extras.py`) | | |
| 28 | 31 | | SSRN | not yet submitted | |
| 29 | −| Journal | Elsevier-format highlights prepared (`docs/highlights_elsevier.tex`); target to be decided | | |
| 32 | +| Journal | Elsevier-format highlights prepared (`docs/highlights_elsevier.tex`); target to be decided (Journal of Housing Economics considered) | | |
| 30 | 33 | | Code & data | reproducible from `scripts/` run from the repository root; raw crawls and LLM caches not committed | |
| 34 | +| Pre-revision reference | `docs/main_pre-revision-20261017.pdf` (v2.0), git tag `pre-revision-20261017` | | |
| 31 | 35 | |
| 32 | 36 | ## 🎯 What this paper does |
| 33 | 37 | |
| 34 | 38 | Hedonic models are bounded by the characteristics an analyst can measure. We treat general-purpose AI models as a |
| 35 | 39 | **feature-engineering technology**: each listing description is parsed by an LLM into a fixed schema of property |
| 36 | 40 | specifications (renovations, finishes, systems, extras), and each façade photograph is parsed by a vision–language model |
| 37 | −into objective attributes (cladding, storeys, garage, curb appeal). The outputs are ordinary econometric variables and | |
| 38 | −enter a log-linear hedonic regression with city fixed effects: | |
| 41 | +into visual attributes (cladding, storeys, garage, curb appeal). The outputs are ordinary econometric variables and | |
| 42 | +enter a log-linear hedonic regression with municipality fixed effects: | |
| 39 | 43 | |
| 40 | 44 | ``` |
| 41 | −ln P_i = α_city(i) + X_i'β + S_i'γ (LLM text layer) + V_i'δ (vision layer) + ε_i | |
| 45 | +ln P_i = α + β ln Area_i + γ ln Lot_i + controls_i'δ + S_i'δ_g (LLM text layer) + V_i'δ_v (vision layer) + μ_city(i) + τ_type(i) + ε_i | |
| 42 | 46 | ``` |
| 43 | 47 | |
| 44 | −We then measure, under identical 5-fold splits, how much each layer adds for OLS, histogram gradient boosting, a | |
| 45 | −residual MLP with city/type embeddings, and a stacked blend. | |
| 48 | +We then measure, under identical 5-fold splits (random and spatially grouped by RTA), how much each layer adds for OLS, | |
| 49 | +random forest, histogram gradient boosting, a residual MLP with city/type embeddings, and an equal-weight blend; and we | |
| 50 | +test the AI implicit prices against clustered, bootstrap and RTA-level inference, language controls and the | |
| 51 | +platform-specific leakage of the asking price into the text. | |
| 46 | 52 | |
| 47 | 53 | ## 🏆 Headline results |
| 48 | 54 | |
| 49 | 55 | | Object | Estimate | |
| 50 | 56 | |---|---| |
| 51 | −| Base hedonic OLS (structural + location), in-sample R² | 0.717 | | |
| 52 | −| + LLM text layer + vision layer | 0.755 | | |
| 53 | −| Out-of-sample R², OLS: base → +text → +text+vision (5-fold) | 0.52 → 0.62 → … (see `paper/tables/ablation.tex`) | | |
| 54 | −| Out-of-sample R², GBM: base → +text | 0.69 → 0.73 | | |
| 55 | −| Best ensemble (robust NN + GBM blend) | R²_OOS = 0.779, median absolute error 14.0% | | |
| 56 | −| Curb-appeal score (1–5) | +2.3% per point | | |
| 57 | −| Brick / stone façade | +3–4% | | |
| 58 | −| Inference | HC3 and municipality-clustered standard errors agree | | |
| 57 | +| Base hedonic OLS (structural + amenity + rooms + listing, city FE), in-sample R² (Model A, N = 9,446) | 0.717 | | |
| 58 | +| + LLM text layer / + vision layer | 0.725 / 0.755 (+0.8 / +3.0 pt) | | |
| 59 | +| Same, Realtor.ca only (text never contains the price) | 0.779 → 0.786 → 0.810 (+0.6 / +2.4 pt) | | |
| 60 | +| Out-of-sample R², OLS: rooms+listing → +text → +vision (random 5-fold) | 0.619 → 0.628 → 0.686 | | |
| 61 | +| Out-of-sample R², GBM: rooms+listing → +text → +vision | 0.729 → 0.743 → 0.770 | | |
| 62 | +| Same under spatial (RTA-grouped) folds, OLS / GBM | 0.561 → 0.568 → 0.638 / 0.690 → 0.703 → 0.734 | | |
| 63 | +| Best ensemble (robust NN + GBM, w = 0.5 fixed) | R²_OOS = 0.779, MdAPE 14.0% (grid 0.3–0.7: 0.771–0.780; nested weight 0.775) | | |
| 64 | +| Curb-appeal score (1–10) | +2.3% per point (cluster-bootstrap 95% CI [0.1%, 3.6%]) | | |
| 65 | +| Brick / stone / vinyl façade | +3.4% / +3.7% / −4.4% | | |
| 66 | +| English-language description (conditional on everything, within municipality) | +7.2% (Model A), +11.8% (Model B); AI coefficients unchanged | | |
| 67 | +| Inference | municipality-clustered SEs (195), HC3, pairs cluster bootstrap (299 reps), RTA FE (250) agree on the AI block | | |
| 59 | 68 | |
| 60 | 69 | ## 🗂 Repository layout |
| 61 | 70 | |
@@ -73,9 +82,11 @@ hedonic-llm-vision-features/ | ||
| 73 | 82 | │ ├── 06_hedonic_ml_cv.py / 07_torch_nn.py / 08_torch_nn_robust.py |
| 74 | 83 | │ ├── 09_v5_ml_text_vision.py / 10_final_blend.py |
| 75 | 84 | │ ├── 11_extras_v5_robustness.py / 12_ablation_extras.py / 13_revision_extras.py |
| 76 | −│ └── 14_figures_v5.py / 15_make_tables.py / 16_make_tables_v5.py / 17_gen_regression_table.py | |
| 77 | −├── results/ # hedonic summaries (txt), ablation_extras.json, revision_extras.json | |
| 78 | −├── docs/ # METHODOLOGIE.md + methodologie.tex/pdf (French data & method note), Elsevier highlights | |
| 85 | +│ ├── 14_figures_v5.py / 15_make_tables.py / 16_make_tables_v5.py / 17_gen_regression_table.py | |
| 86 | +│ └── 18_revision_language_leakage_spatial.py # v2.1: language, leakage, RTA FE, spatial CV, bootstrap, agreement, blend weights | |
| 87 | +├── results/ # hedonic summaries (txt), ablation_extras.json, revision_extras.json, revision_2026-10-17.json (+ .log) | |
| 88 | +├── docs/ # METHODOLOGIE.md + methodologie.tex/pdf (French data & method note), Elsevier highlights, | |
| 89 | +│ # REVIEW-REPORT.md, CHANGELOG-REVISION.md, main_pre-revision-20261017.pdf | |
| 79 | 90 | └── paper/ # main.tex + sections/ + tables/ + figures/ + references.bib → main.pdf |
| 80 | 91 | ``` |
| 81 | 92 | |
@@ -92,46 +103,58 @@ python3 scripts/05_hedonic_ols_v4_text.py | ||
| 92 | 103 | python3 scripts/08_torch_nn_robust.py && python3 scripts/09_v5_ml_text_vision.py && python3 scripts/10_final_blend.py |
| 93 | 104 | python3 scripts/11_extras_v5_robustness.py && python3 scripts/12_ablation_extras.py && python3 scripts/13_revision_extras.py |
| 94 | 105 | python3 scripts/14_figures_v5.py && python3 scripts/16_make_tables_v5.py && python3 scripts/17_gen_regression_table.py |
| 106 | +python3 scripts/18_revision_language_leakage_spatial.py # v2.1 robustness tables (≈5 min, no API calls) | |
| 95 | 107 | cd paper && make # latexmk → main.pdf |
| 96 | 108 | ``` |
| 97 | 109 | |
| 98 | −LLM extraction ≈ 600 tokens in / 110 out per listing (24 threads); vision ≈ 2,470 tokens in per image (16 threads); | |
| 99 | −both are resumable. Econometrics and ML ≈ 20 minutes on an Apple-silicon laptop (PyTorch on MPS). | |
| 110 | +LLM extraction ≈ 600 tokens in / 110 out per listing (24 threads, temperature 0); vision ≈ 2,470 tokens in per image | |
| 111 | +(16 threads, API default temperature); both are resumable. Econometrics and ML ≈ 25 minutes on an Apple-silicon laptop | |
| 112 | +(PyTorch on MPS). Scripts 11–14, 16 and 18 rebuild the design matrix by executing the preamble of | |
| 113 | +`scripts/09_v5_ml_text_vision.py`. | |
| 100 | 114 | |
| 101 | 115 | ## 🗃 Data |
| 102 | 116 | |
| 103 | 117 | 27,302 Realtor.ca and 7,693 DuProprio listings crawled on 2026-07-03; houses (single-family and townhouse) with a valid |
| 104 | −price retained, outliers removed by the rules in `docs/METHODOLOGIE.md` §3, giving 19,123 observations. Structural | |
| 105 | −variables (living area, lot, rooms, year built, type, city), text-derived specifications and façade attributes. See | |
| 106 | −`data/raw/README.md` and `data/processed/README.md`. | |
| 118 | +price retained, outliers removed by the rules in `docs/METHODOLOGIE.md` §3, giving 19,123 observations (15,356 | |
| 119 | +Realtor.ca, 3,767 DuProprio). Structural variables (living area, lot, rooms, year built, type, city, postal code), | |
| 120 | +15 bilingual keyword amenities, text-derived specifications (18 regressors) and façade attributes (21 regressors). | |
| 121 | +Language of the description (stop-word rule): 44.6% French, 43.1% English, 12.3% mixed. **Every DuProprio | |
| 122 | +"description" embeds the platform's structured sheet including the asking price**; Realtor.ca descriptions never do. | |
| 123 | +See `data/raw/README.md` and `data/processed/README.md`. | |
| 107 | 124 | |
| 108 | 125 | ## 🔬 Methodology |
| 109 | 126 | |
| 110 | −1. **AI feature layers** with strict JSON schemas and retry/backoff — `scripts/01_…`, `scripts/02_…`. | |
| 111 | −2. **Log-linear hedonic OLS** with city fixed effects, HC3 and municipality-clustered SEs — `scripts/05_…`, `scripts/13_…`. | |
| 112 | −3. **Ablation by feature block × estimator** under identical folds (OLS, GBM, NN) — `scripts/09_…`, `scripts/12_…`. | |
| 113 | −4. **Stacked blend** of the robust NN and HistGradientBoosting — `scripts/10_final_blend.py`. | |
| 114 | −5. **Robustness** by segment, extreme city effects, calibration and importance plots — `scripts/11_…`, `scripts/14_…`. | |
| 127 | +1. **AI feature layers** with strict JSON schemas and retry/backoff — `scripts/01_…`, `scripts/02_…` (raw outputs archived; regressors regenerable without API calls). | |
| 128 | +2. **Log-linear hedonic OLS** with municipality fixed effects, HC3, municipality-clustered SEs and a pairs cluster bootstrap — `scripts/05_…`, `scripts/13_…`, `scripts/18_…`. | |
| 129 | +3. **Ablation by feature block × estimator** under identical random folds and under RTA-grouped (spatial) folds — `scripts/09_…`, `scripts/12_…`, `scripts/18_…`. | |
| 130 | +4. **Equal-weight blend** of the robust NN and HistGradientBoosting, with weight-grid and nested-weight checks — `scripts/10_…`, `scripts/18_…`. | |
| 131 | +5. **Robustness** by segment, language, platform (leakage), RTA fixed effects; inter-source agreement of the AI attributes — `scripts/11_…`, `scripts/18_…`. | |
| 115 | 132 | |
| 116 | 133 | ## 🖼 Figures & tables inventory |
| 117 | 134 | |
| 118 | 135 | | Figure | Content | |
| 119 | 136 | |---|---| |
| 120 | −| `fig_ablation` | out-of-sample gain by feature block and estimator | | |
| 137 | +| `fig_ablation` | out-of-sample gain by feature block and estimator (random folds) | | |
| 121 | 138 | | `fig_calibration` | predicted vs actual, blend | |
| 122 | −| `fig_importance` | feature importance | | |
| 123 | −| `fig_premia` | location premia | | |
| 124 | −| `fig_validation` | validation of AI-extracted attributes | | |
| 139 | +| `fig_importance` | feature-block permutation importance (GBM) | | |
| 140 | +| `fig_premia` | municipality fixed effects (extremes) | | |
| 141 | +| `fig_validation` | median price by vision score | | |
| 125 | 142 | | `nn_diagram` (TikZ) | architecture of the robust NN | |
| 126 | 143 | |
| 127 | −Tables (`paper/tables/*.tex`): summary stats, regression (A/B panels), models, ablation, robustness, AI summary. | |
| 144 | +Tables (`paper/tables/*.tex`): summary stats, AI summary, regression (A/B, clustered SEs), models (two panels), | |
| 145 | +ablation, robustness by subsample, and — new in v2.1 — `rob_ai_coefs` (language / RTA FE / Realtor-only / bootstrap CI), | |
| 146 | +`rob_language_source` (gains by language, platform, price-in-text), `rob_spatial` (random vs RTA-grouped CV), | |
| 147 | +`agreement` (AI attributes vs independent sources). Appendix: feature definitions, sample flow, language rule. | |
| 128 | 148 | |
| 129 | 149 | ## ⚠️ Limitations |
| 130 | 150 | |
| 131 | −- Asking prices from listings, single cross-section (July 2026). | |
| 132 | −- Realtor.ca listings lack coordinates; location enters through city fixed effects and postal codes. | |
| 133 | −- LLM/vision outputs are model-dependent; schemas and prompts are versioned in the scripts. | |
| 134 | −- API costs make the extraction layers the expensive part of replication. | |
| 151 | +- Asking prices from listings, single cross-section (3 July 2026); no forward-in-time holdout possible. | |
| 152 | +- The LLM read the asking price for the 19.7% of listings from DuProprio; text-layer gains on that platform are an upper bound. | |
| 153 | +- No human-labelled validation set: extraction error is measured only by agreement with keyword rules and structured fields (high for garage/fireplace/pool, low for waterfront, visual setting and visual building type). | |
| 154 | +- Vision extraction at API default temperature; model identifiers are provider aliases (snapshots not pinned); test–retest variability not measured. | |
| 155 | +- Realtor.ca listings lack coordinates; location enters through municipality or RTA fixed effects. | |
| 156 | +- English-language indicator carries a large conditional premium that proxies for unobserved location/clientele. | |
| 157 | +- API costs (~$60) make the extraction layers the expensive part of replication. | |
| 135 | 158 | |
| 136 | 159 | ## 📝 Citation |
| 137 | 160 | |
@@ -143,7 +166,8 @@ Tables (`paper/tables/*.tex`): summary stats, regression (A/B panels), models, a | ||
| 143 | 166 | type = {Working Paper}, |
| 144 | 167 | number = {14}, |
| 145 | 168 | year = {2026}, |
| 146 | − month = {July} | |
| 169 | + month = {October}, | |
| 170 | + note = {Version 2.1} | |
| 147 | 171 | } |
| 148 | 172 | ``` |
| 149 | 173 | |
@@ -155,10 +179,16 @@ Université du Québec en Outaouais (UQO), Gatineau, QC. | ||
| 155 | 179 | |
| 156 | 180 | ## 🗒 Notes |
| 157 | 181 | |
| 182 | +- **Revision 2026-10-17 (v2.1)**: full scientific review by an editorial-board agent — report in `docs/REVIEW-REPORT.md`, | |
| 183 | + audit trail in `docs/CHANGELOG-REVISION.md`. Main corrections: the claim that the vision layer was "the largest gain | |
| 184 | + of any feature block" was wrong (the rooms/listing block adds more) and is withdrawn; the asking-price leakage in | |
| 185 | + DuProprio descriptions is documented and quantified; vision temperature/model-version statements corrected; 15 (not 17) | |
| 186 | + keyword amenities; 12 vision fields → 21 regressors; reference category of the city FE made explicit; bibliography | |
| 187 | + verified (all DOIs) and extended from 35 to 53 references. Headline numbers of v2.0 are unchanged. | |
| 158 | 188 | - Numbering: this paper was first issued as "Working Paper No. 11" (July 2026); number 11 belongs to *Half a Million |
| 159 | − Prices, Twenty Models*. Renumbered **14** on 2026-10-17; cover date fixed to July 2026 (was `\today`). | |
| 189 | + Prices, Twenty Models*. Renumbered **14** on 2026-10-17. | |
| 160 | 190 | - Harmonised 2026-10-17: flat scripts moved to `scripts/` (numbered), data to `data/`, logs removed, summaries to |
| 161 | 191 | `results/`, methodology note to `docs/`; file paths inside the scripts now point to `data/…` and `results/…` |
| 162 | − (run them from the repository root). Bibliography switched from `plainnat` to `aer`. | |
| 192 | + (run them from the repository root). Bibliography style `aer`. | |
| 163 | 193 | - The script `13_revision_extras.py` was written for a Journal of Housing Economics revision round (clustered SEs, |
| 164 | − in-sample ablation, extreme city effects). | |
| 194 | + in-sample ablation, extreme city effects); `18_…` for the October 2026 review. | |
added
docs/CHANGELOG-REVISION.md
+131 −0
@@ -0,0 +1,131 @@ | ||
| 1 | +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca --> | |
| 2 | +# CHANGELOG — révision scientifique complète (editorial board, 2026-10-17) | |
| 3 | + | |
| 4 | +**Papier** : UQO Working Paper No. 14, *Hedonic House Pricing with Language-Model and Vision Features: Evidence from | |
| 5 | +Quebec Real-Estate Listings*. Version examinée : 2.0 (juillet 2026, 33 p., 35 réf.). Version produite : **2.1 | |
| 6 | +(octobre 2026)**. État de départ figé : tag git `pre-revision-20261017`, copie `docs/main_pre-revision-20261017.pdf`. | |
| 7 | +Rapport de l'editorial board : `docs/REVIEW-REPORT.md`. | |
| 8 | + | |
| 9 | +Convention : chaque entrée donne *où* / *avant* / *après* / *pourquoi* / *preuve*. Aucun chiffre du texte n'a changé sans | |
| 10 | +résultat recalculé ; tous les nouveaux chiffres proviennent de `scripts/18_revision_language_leakage_spatial.py` | |
| 11 | +(sortie `results/revision_2026-10-17.json` ; journal local `results/revision_2026-10-17.log`, non commité car `*.log` est ignoré) et des tables générées par | |
| 12 | +`scripts/19_make_revision_tables.py`. | |
| 13 | + | |
| 14 | +--- | |
| 15 | + | |
| 16 | +## 1. Corrections majeures (fond) | |
| 17 | + | |
| 18 | +| # | Où | Avant (v2.0) | Après (v2.1) | Pourquoi / preuve | | |
| 19 | +|---|---|---|---|---| | |
| 20 | +| 1 | Résumé, intro (contribution 1), §Benchmark, §Ablation, conclusion, légende fig. ablation, highlights, README | « the vision layer delivers the **largest out-of-sample gain of any feature block** for every estimator » ; « the vision layer the single largest jump for every estimator » | La couche vision est le plus grand des **deux incréments IA** et apporte plus à OLS que le passage OLS → forêt aléatoire ; le bloc **pièces + listing** apporte davantage (+9,8 pt OLS, +3,7 pt GBM contre +5,8 / +2,7 pour la vision) | Contredit par la propre table d'ablation du papier (`results/ablation_extras.json` : L1→L2 0,521→0,619 OLS, 0,692→0,729 GBM) | | |
| 21 | +| 2 | §Data (nouvelle §3.4), §Robustness (nouvelle §7.3), §Limitations, intro, résumé, conclusion | « Because both extractions are … **blind to the listing price** » ; « The models never observe the price » | 100 % des 3 767 descriptions DuProprio contiennent la fiche structurée dont « Asking Price $… » (= prix enregistré dans 3 761 cas) et 46,6 % l'évaluation municipale ; 2,5 % des descriptions Realtor.ca contiennent un montant, aucune le prix demandé. Le LLM a lu la variable dépendante pour 19,7 % de l'échantillon. Gains texte reportés par plateforme ; Realtor.ca retenu comme estimation crédible (+0,6 pt in-sample vs +3,3 pt DuProprio) ; la vision n'est pas exposée | Inspection des descriptions (`data/processed/maisons_avec_prix.json`) ; `revision_2026-10-17.json["text_leakage"]`, `["ablation_A"]` | | |
| 22 | +| 3 | §Methodology (vision), Annexe A, §Limitations | « Decoding temperature is set to zero for determinism » appliqué aux deux couches ; « deterministic » | Température 0 pour le texte seulement ; l'appel vision (`02_facade_vision.py`) ne fixe pas la température → défaut API ; alias de modèles non épinglés ; sorties brutes archivées ; variabilité test–retest non mesurée ; « deterministic » retiré | Lecture de `scripts/02_facade_vision.py` (pas de clé `temperature`) | | |
| 23 | +| 4 | §Methodology, §Data (nouvelle §3.4), §Robustness (§7.2), table `rob_ai_coefs` col. (2), annexe C | Langue jamais mentionnée | Détection FR/EN/mixte (stop-words, ratio 1,5 comme WP 2) : 44,6 % FR, 43,1 % EN, 12,3 % mixte ; Realtor.ca 41,9 % EN ; indicatrice EN +7,2 % (A), +11,8 % (B) conditionnel ; coefficients IA inchangés ; gains des deux couches présents dans chaque langue | `revision_2026-10-17.json["language"]`, `["ols"]["A_lang"]`, `["ablation_A"]["fr"/"en"]`, `["cv"]` | | |
| 24 | +| 5 | §Methodology (localisation), table `rob_ai_coefs` col. (3), §7.4 | EF municipalité seulement | EF **RTA** (419 RTA, 250 avec ≥ 20 annonces) : R² A 0,755 → 0,764, B 0,725 → 0,726 ; coefficients IA stables ; SE groupées par RTA | `["ols"]["A_fsa"]`, `["fsa"]` | | |
| 25 | +| 6 | §Methodology (validation OOS), §7.4, table `rob_spatial` | Validation croisée aléatoire seulement | GroupKFold par RTA : OLS 0,561 → 0,568 → 0,638, GBM 0,690 → 0,703 → 0,734 (vs 0,619/0,628/0,686 et 0,729/0,743/0,770 en aléatoire) ; incréments IA préservés ; MdAPE +1,5 pt | `["cv"]["spatial_fsa"]` | | |
| 26 | +| 7 | §Methodology (inférence), §7.1, table `rob_ai_coefs` dernière colonne | SE groupées analytiques + HC3 | Bootstrap en grappes par paires (299 réplications, 195 municipalités) ; IC 95 % ; discussion des grappes très inégales (regroupement « autres » = 5 006 annonces de 999 municipalités) | `["cluster_bootstrap_A"]` | | |
| 27 | +| 8 | §Results (nouvelle partie de §5.3 Validation), table `agreement`, §Limitations | « we do not perform systematic human validation » (sans mesure d'erreur) | Mesure indirecte de l'erreur d'extraction : accord LLM vs mots-clés (κ 0,96 garage … 0,50 bord de l'eau, précision 40 %), vision vs texte/structuré (garage κ 0,35 ; étages exacts 60 %, ± ½ étage 89 % ; « maison en rangée » précision 18 %) ; champs non fiables identifiés et relégués au rôle de contrôles | `["agreement"]` | | |
| 28 | +| 9 | §Benchmark (blend), table `models` note | « simple 50/50 average », poids non discuté (le script 10 cherchait le meilleur poids sur les prédictions test) | Poids fixé a priori ; grille w ∈ {0,3…0,7} → 0,771–0,780 ; poids choisi en CV emboîtée → 0,775 ; w = 0,5 exactement optimal pour la version texte seule | `["blend"]` (prédictions NN v5 récupérées exactement : R² 0,747) | | |
| 29 | +| 10 | §Methodology (aménités) | « Seventeen amenity indicators » | **Fifteen** (15 clés dans `AMEN`) | `scripts/09_v5_ml_text_vision.py` | | |
| 30 | +| 11 | §Methodology, tables `models`/`ablation` notes, annexe A | « twelve façade vision attributes » (comme régresseurs) ; curb appeal « 1–5 » dans le README | 12 champs vision → **21 régresseurs** ; 20 champs texte → 18 régresseurs ; curb appeal 1–10 partout | Comptage `vv`, `gv` ; `# feats` 56 → 77 | | |
| 31 | +| 12 | §Results (EF ville), légende fig. premia, intro | « relative to the reference city » | Catégorie de référence = municipalités regroupées (< 20 annonces) ; Sainte-Anne-des-Plaines (+143 %) identifié sur 2 observations (dont un domaine à 5,5 M$) | Ordre des niveaux patsy (`__other__` premier) ; `maisons_hedonic_v4.csv` | | |
| 32 | +| 13 | §Results (âge) | « small negative linear term and a positive quadratic » | Chiffré : −0,4 %/an, +2,6 × 10⁻⁵, minimum vers 70 ans | `results/hedonic_v4_summary.txt` (age2 = 2,612e-05) | | |
| 33 | +| 14 | §Results (vision) | Score de condition visuelle non discuté | Non significatif dans A (p = 0,15) ; colinéarité des trois scores visuels → lecture en bloc | `results/revision_extras.json` (`v_cond`) | | |
| 34 | +| 15 | Résumé | « render the outputs reproducible econometric variables » | « auditable » ; ajout des résultats langue, fuite, validation spatiale | — | | |
| 35 | + | |
| 36 | +## 2. Corrections éditoriales (forme) | |
| 37 | + | |
| 38 | +- Intro : ordre des blocs de la couche NN corrigé (BN → Lin₅₁₂ → GELU → Drop → Lin₂₅₆ → Drop, conforme au code) dans §6.5 et | |
| 39 | + le diagramme TikZ ; dimension d'embedding « about 29 » → « about 30 » (1,6 × 195^0,56 = 30,7). | |
| 40 | +- Éq. (hedonic) : blocs explicités (δ_s, δ_a, δ_r, δ_m, δ_g, δ_v) au lieu de `X_i'δ` qui dupliquait ln Area / ln Lot ; | |
| 41 | + équation scindée sur deux lignes (débordement de 31 pt corrigé). | |
| 42 | +- Éq. (consumer) : numéraire `x` scalaire (était en gras). | |
| 43 | +- Paragraphe « Evaluation » : MdAPE indépendante de la constante de rétrotransformation ; parts ± 15 % / ± 25 % définies. | |
| 44 | +- Forêt aléatoire : hyperparamètres indiqués (400 arbres, max_features 0,5, feuille ≥ 3). | |
| 45 | +- Vocabulaire du programme de recherche : « median absolute percentage error (MdAPE) », « neighbourhood/municipality fixed | |
| 46 | + effects », « out-of-sample », « automated valuation model (AVM) », « implicit price » ; orthographe britannique | |
| 47 | + harmonisée (labelled, neighbourhood, modelled, centred). | |
| 48 | +- Déclarations : disponibilité des sorties brutes IA ; mention de l'assistant IA utilisé pour la révision ; chemin de | |
| 49 | + script en `\path{}` (débordement de 150 pt corrigé). | |
| 50 | +- Tables `rob_ai_coefs` et `agreement` en `\footnotesize` ; ligne « Realtor.ca, dollar amount in text » (141 obs., régression | |
| 51 | + saturée R² 0,998) retirée de la table et expliquée en note. | |
| 52 | +- README : statut, résultats-phares, inventaire des tables, limites, notes de révision ; `docs/METHODOLOGIE.md` : §3 (19 115 vs | |
| 53 | + 19 123 expliqué) et nouveau §10 ; `docs/highlights_elsevier.tex` réécrit (5 puces ≤ 85 caractères). | |
| 54 | +- Scripts 11–14 et 16 : `exec(open("v5_ml.py"))` → `exec(open("scripts/09_v5_ml_text_vision.py"))` (chemin cassé par | |
| 55 | + l'harmonisation du 2026-10-17 ; les scripts ne tournaient plus). Script 16 : note de table « twelve attributes » corrigée. | |
| 56 | + | |
| 57 | +## 3. Références | |
| 58 | + | |
| 59 | +Avant : 35 entrées, aucune avec DOI. Après : **53 entrées, toutes vérifiées via Crossref (`api.crossref.org/works`) ou la page | |
| 60 | +arXiv, DOI inscrit dans le .bib** (sauf Kennedy 1981, sans DOI Crossref ; vérifié via RePEc/Statalist : AER 71(4), p. 801). | |
| 61 | + | |
| 62 | +Corrections d'entrées existantes : Lindenthal & Johnson (2021) — volume 71(3), pages 353–384 ajoutés (DOI 10.1007/s11146-021-09845-1) ; | |
| 63 | +Gorishniy et al. — NeurIPS 34, arXiv:2106.11959 ; Grinsztajn et al. — NeurIPS 35, DOI 10.52202/068431-0037 ; Loshchilov & Hutter — | |
| 64 | +arXiv:1711.05101 ; Guo & Berkhahn — arXiv:1604.06737 ; Malpezzi (2003) — DOI chapitre Wiley 10.1002/9780470690680.ch5. | |
| 65 | + | |
| 66 | +Références ajoutées (18) et usage : | |
| 67 | + | |
| 68 | +| Clé | Référence | DOI | Rôle | | |
| 69 | +|---|---|---|---| | |
| 70 | +| kennedy1981estimation | Kennedy, AER 71(4):801, 1981 | — | correction petit échantillon de Halvorsen–Palmquist | | |
| 71 | +| nowak2020quality | Nowak & Smith, AER: Insights 2(3):339–356, 2020 | 10.1257/aeri.20190337 | qualité omise et indices | | |
| 72 | +| nowak2021dictionaries | Nowak, Price & Smith, JREFE 62(1):139–163, 2021 | 10.1007/s11146-019-09740-w | instabilité du vocabulaire | | |
| 73 | +| zhang2024describe | Zhang, Li & Branco, Natural Language Engineering 30(4):661–695, 2024 | 10.1017/S1351324923000360 | complémentarité texte / structuré | | |
| 74 | +| boucher2026decoding | Boucher, UQO WP 2, 2026 | — | papier frère (langue, embeddings) | | |
| 75 | +| bessinger2016quantifying | Bessinger & Jacobs, ICIP 2016, 4388–4392 | 10.1109/ICIP.2016.7533189 | curb appeal appris | | |
| 76 | +| naik2017computer | Naik et al., PNAS 114(29):7571–7576, 2017 | 10.1073/pnas.1619003114 | vision urbaine | | |
| 77 | +| law2019take | Law, Paige & Russell, ACM TIST 10(5):1–19, 2019 | 10.1145/3342240 | street view + satellite | | |
| 78 | +| zhang2018greenery | Zhang & Dong, ISPRS IJGI 7(3):104, 2018 | 10.3390/ijgi7030104 | verdure visible | | |
| 79 | +| kang2021understanding | Kang et al., Land Use Policy 111:104919, 2021 | 10.1016/j.landusepol.2020.104919 | géo-données multi-sources | | |
| 80 | +| dell2025deep | Dell, JEL 63(1):5–58, 2025 | 10.1257/jel.20241733 | deep learning pour économistes | | |
| 81 | +| korinek2023generative | Korinek, JEL 61(4):1281–1317, 2023 | 10.1257/jel.20231736 | IA générative en recherche | | |
| 82 | +| gilardi2023chatgpt | Gilardi, Alizadeh & Kubli, PNAS 120(30), 2023 | 10.1073/pnas.2305016120 | fiabilité de l'annotation LLM | | |
| 83 | +| han2016asking | Han & Strange, JUE 93:115–130, 2016 | 10.1016/j.jue.2016.03.008 | rôle du prix demandé | | |
| 84 | +| pace2020examining | Pace & Hayunga, JREFE 60(1–2):170–180, 2020 | 10.1007/s11146-019-09724-w | résidus hédoniques et arbres | | |
| 85 | +| bourassa2010predicting | Bourassa, Cantoni & Hoesli, JRER 32(2):139–160, 2010 | 10.1080/10835547.2010.12091276 | prédiction et dépendance spatiale | | |
| 86 | +| roberts2017cross | Roberts et al., Ecography 40(8):913–929, 2017 | 10.1111/ecog.02881 | validation croisée bloquée | | |
| 87 | +| abadie2023when | Abadie, Athey, Imbens & Wooldridge, QJE 138(1):1–35, 2023 | 10.1093/qje/qjac038 | quand grouper les SE | | |
| 88 | +| mackinnon2017wild | MacKinnon & Webb, JAE 32(2):233–254, 2017 | 10.1002/jae.2508 | grappes de tailles inégales | | |
| 89 | + | |
| 90 | +Référence envisagée puis non ajoutée : Ho (U. Washington, job-market paper, texte + images Zillow) — non publiée, non vérifiable | |
| 91 | +par Crossref. | |
| 92 | + | |
| 93 | +## 4. Réanalyses exécutées | |
| 94 | + | |
| 95 | +| Script | Durée | Sortie | Contenu | | |
| 96 | +|---|---|---|---| | |
| 97 | +| `scripts/18_revision_language_leakage_spatial.py` | ≈ 5,5 min (Mac M-series, 9 CV GBM, 299 bootstrap) | `results/revision_2026-10-17.json`, `.log` | langue, fuite, OLS A/B + langue / RTA / Realtor seul, ablation in-sample par sous-échantillon, bootstrap en grappes, accord inter-sources, CV aléatoire vs spatiale (OLS, GBM ; L2–L4, L4 + langue), grille et CV emboîtée du blend | | |
| 98 | +| `scripts/19_make_revision_tables.py` | < 1 s | `paper/tables/rob_language_source.tex`, `rob_spatial.tex`, `rob_ai_coefs.tex`, `agreement.tex` | mise en forme des tables à partir du JSON | | |
| 99 | + | |
| 100 | +Vérifications sans script versionné (lecture seule) : égalité prix demandé dans le texte / `priceNumber` ; comptage des | |
| 101 | +municipalités regroupées ; part de Montréal ; composition de Sainte-Anne-des-Plaines (`maisons_hedonic_v4.csv`) ; | |
| 102 | +reproduction exacte des prédictions GBM v5 (R² 0,7695) et récupération des prédictions NN v5 (R² 0,747) à partir de | |
| 103 | +`v5_blend_oos.npy`. | |
| 104 | + | |
| 105 | +Aucun appel aux API OpenAI/Anthropic. Figures non régénérées (chiffres inchangés) ; `fig_ablation` reste valide (légende | |
| 106 | +corrigée). | |
| 107 | + | |
| 108 | +## 5. Chiffres du texte modifiés | |
| 109 | + | |
| 110 | +| Chiffre | Avant | Après | Justification | | |
| 111 | +|---|---|---|---| | |
| 112 | +| Gain in-sample des deux couches | « nearly four points » | 3,8 pt (0,8 texte + 3,0 vision) | `ablationA_insample` (0,7169 / 0,7252 / 0,7552) | | |
| 113 | +| Gain OLS du passage OLS → RF | +4,9 | +4,9 (inchangé, précisé « Panel A ») | — | | |
| 114 | +| Dimension d'embedding | ≈ 29 | ≈ 30 | 1,6 × 195^0,56 | | |
| 115 | +| Aménités par mots-clés | 17 | 15 | code | | |
| 116 | +| Régresseurs vision | 12 | 21 (12 champs) | code | | |
| 117 | +| Part d'extérieurs détectés | 96 % | 95,8 % (18 314 / 19 123) | JSON | | |
| 118 | + | |
| 119 | +Tous les autres chiffres de la v2.0 (R² 0,717 / 0,725 / 0,755 ; 0,779 / 14,0 % ; coefficients de la table de régression ; | |
| 120 | +tables `models`, `ablation`, `robustness`, `summary_stats`, `ai_summary`) sont inchangés et ont été re-vérifiés contre | |
| 121 | +`results/revision_extras.json` et `results/ablation_extras.json`. | |
| 122 | + | |
| 123 | +## 6. Éléments non modifiés faute de données / de temps | |
| 124 | + | |
| 125 | +- Pas de ré-extraction LLM sur des descriptions purgées du prix (nécessite l'API OpenAI ; ≈ 1 $) — recommandée. | |
| 126 | +- Pas de validation humaine des extractions (aucun jeu étiqueté). | |
| 127 | +- Pas de mesure test–retest de la couche vision (API Anthropic). | |
| 128 | +- Pas de prix de transaction (registre foncier) ; pas de dimension temporelle. | |
| 129 | +- Figures `fig_ablation`, `fig_importance`, `fig_calibration` non régénérées (script 14 ≈ 5 min, chiffres inchangés). | |
| 130 | +- Les tables « auto-generated » `models.tex` et `ablation.tex` ont été modifiées à la main **dans leurs notes seulement** | |
| 131 | + (et le générateur `16_make_tables_v5.py` mis en cohérence) ; les chiffres n'ont pas été touchés. | |
modified
docs/METHODOLOGIE.md
+37 −1
@@ -47,7 +47,7 @@ Les prix scrappés contiennent des erreurs de parsing (min 899 $, max 368 G$). R | ||
| 47 | 47 | | Chambres / sdb | 0–15 / 0–12 (sinon → manquant) | plafonds réalistes | |
| 48 | 48 | | **Prix/pied²** | garder **P0,5 – P99,5** (≈ 73–1 276 $/ft²) sur les biens à surface réelle | retire les erreurs résiduelles de parsing prix ou surface | |
| 49 | 49 | |
| 50 | −→ **19 115 maisons** conservées (158 retirées). | |
| 50 | +→ **19 115 maisons** conservées (158 retirées) dans la première version du pipeline (`04_hedonic_ols_base.py`). Dans la version finale (scripts 05–18), la reconstruction de la surface par les pièces précède le filtre prix/pi², ce qui donne **19 123 maisons** (150 retirées) ; c'est ce chiffre qui figure dans le papier. | |
| 51 | 51 | |
| 52 | 52 | **Principe** : on borne plutôt que de supprimer quand une seule variable est aberrante (on met la variable à *manquant* et on l'impute), pour ne pas perdre l'observation entière. |
| 53 | 53 | |
@@ -170,3 +170,39 @@ Progression observée : v2 (structurel) R²≈0,70 → v3 (+ pièces/photos) R² | ||
| 170 | 170 | | `specs.jsonl`, `facade_specs.jsonl` | sorties LLM brutes (clé uid) | |
| 171 | 171 | | `maisons_hedonic*.csv` | dataset final + prix prédit + `resid_pct` | |
| 172 | 172 | | `hedonic_*_summary.txt` | sorties statistiques complètes | |
| 173 | + | |
| 174 | + | |
| 175 | +--- | |
| 176 | + | |
| 177 | +## 10. Révision scientifique du 2026-10-17 (version 2.1 du papier) | |
| 178 | + | |
| 179 | +Réanalyses locales (`scripts/18_revision_language_leakage_spatial.py`, ~5 min, aucun appel API ; résultats dans | |
| 180 | +`results/revision_2026-10-17.json`, tables `paper/tables/rob_*.tex` et `agreement.tex`) : | |
| 181 | + | |
| 182 | +- **Fuite d'information par le texte.** Les 3 767 descriptions DuProprio de l'échantillon nettoyé contiennent toutes la | |
| 183 | + fiche structurée de la plateforme rendue en texte, dont le prix demandé (« Asking Price $499,999 », égal au prix | |
| 184 | + enregistré dans 3 761 cas) et, pour 46,6 % d'entre elles, l'évaluation municipale ; 2,5 % des descriptions Realtor.ca | |
| 185 | + contiennent un montant en dollars, aucune le prix demandé. Le LLM a donc lu la variable dépendante pour 19,7 % de | |
| 186 | + l'échantillon. Gain in-sample de la couche texte (modèle A) : +0,6 pt sur Realtor.ca contre +3,3 pt sur DuProprio ; | |
| 187 | + couche vision (jamais exposée au texte) : +2,4 contre +4,1 pt. Les gains Realtor.ca sont retenus comme estimation | |
| 188 | + crédible ; une ré-extraction sur des descriptions purgées du prix est recommandée (≈ 1 $). | |
| 189 | +- **Langue.** Règle de stop-words (ratio 1,5, comme WP 2) : 44,6 % FR, 43,1 % EN, 12,3 % mixte (DuProprio = traduction | |
| 190 | + anglaise + original français). Sur Realtor.ca, 41,9 % EN ; prix médian EN 749 000 $ vs FR 524 900 $. Indicatrice EN : | |
| 191 | + +7,2 % conditionnel (modèle A), +11,8 % (modèle B). Les prix implicites IA sont inchangés à la 3e décimale ; les gains | |
| 192 | + des deux couches existent dans chaque langue. | |
| 193 | +- **Effets fixes RTA** (3 premiers caractères du code postal ; 419 RTA, 250 avec ≥ 20 annonces) : R² A 0,755 → 0,764 ; | |
| 194 | + coefficients IA stables. | |
| 195 | +- **Validation spatiale** (GroupKFold par RTA vs 5-fold aléatoire) : tous les niveaux baissent de 3 à 5 pt de R² OOS | |
| 196 | + (GBM texte+vision 0,770 → 0,734), les incréments texte/vision sont préservés. | |
| 197 | +- **Bootstrap en grappes** (299 réplications, 195 municipalités) : IC 95 % excluant zéro pour curb appeal, rénovation, | |
| 198 | + luxe, garage, brique, pierre, vinyle, cadre rural, condition LLM, cuisine rénovée ; incluant zéro de peu pour | |
| 199 | + aménagement paysager et bois franc. | |
| 200 | +- **Accord inter-sources** (LLM vs mots-clés sur le même texte ; vision vs texte/champs structurés) : κ = 0,96 garage, | |
| 201 | + 0,91 foyer, 0,81 piscine, 0,65 climatisation, 0,56 sous-sol fini, 0,50 bord de l'eau (le LLM sur-déclare : 22,5 % vs | |
| 202 | + 9,2 %) ; garage visible vs garage texte κ = 0,35 ; étages visuels exacts 60 %, à ± ½ étage 89 % ; type « maison en | |
| 203 | + rangée » visuel : précision 18 % (champ non fiable, utilisé seulement comme contrôle). | |
| 204 | +- **Poids du blend** : w = 0,5 fixé a priori ; grille 0,3–0,7 → R² 0,771–0,780 ; poids choisi en CV emboîtée → 0,775. | |
| 205 | +- **Corrections de forme** : la température n'était pas fixée pour la vision (défaut API), seuls les alias de modèles | |
| 206 | + sont connus ; 15 (et non 17) aménités par mots-clés ; 12 champs vision → 21 régresseurs ; catégorie de référence des | |
| 207 | + EF ville = municipalités regroupées (< 20 annonces) ; la couche vision est le plus grand des deux incréments IA mais | |
| 208 | + le bloc pièces/listing apporte davantage (+9,8 pt OLS). | |
added
docs/REVIEW-REPORT.md
+165 −0
@@ -0,0 +1,165 @@ | ||
| 1 | +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca --> | |
| 2 | +# REVIEW REPORT — editorial board, révision scientifique complète (2026-10-17) | |
| 3 | + | |
| 4 | +**Papier** : UQO Working Paper No. 14, *Hedonic House Pricing with Language-Model and Vision Features: Evidence from | |
| 5 | +Quebec Real-Estate Listings* (S.-P. Boucher). Version examinée : 2.0 (juillet 2026, 33 p., 35 réf., pas sur SSRN). | |
| 6 | +Version produite : 2.1 (octobre 2026, 46 p., 53 réf.). Journal d'audit : `docs/CHANGELOG-REVISION.md`. | |
| 7 | + | |
| 8 | +**Verdict global.** La question est bien posée et actuelle (des modèles d'IA généralistes, contraints par un schéma de | |
| 9 | +sortie, peuvent-ils transformer texte et photos d'annonces en caractéristiques hédoniques interprétables, et combien | |
| 10 | +cela ajoute-t-il ?), le pipeline est entièrement reproductible et les résultats-phares de la v2.0 se reproduisent à | |
| 11 | +l'identique. La v2.0 présentait toutefois trois faiblesses de fond que la révision corrige à partir de réanalyses | |
| 12 | +locales : (i) une **fuite d'information** non détectée — toutes les descriptions DuProprio contiennent le prix demandé | |
| 13 | +que le LLM a lu ; (ii) une **affirmation centrale fausse** — la couche vision n'est pas « le plus grand gain de tout bloc | |
| 14 | +de variables », le bloc pièces/listing fait mieux ; (iii) l'**absence de tout contrôle de langue, d'effets fixes fins et | |
| 15 | +de validation spatiale**, alors que 43 % des annonces sont en anglais, que les codes postaux sont disponibles et que la | |
| 16 | +validation croisée aléatoire flatte des modèles qui exploitent la proximité spatiale. S'y ajoutent des inexactitudes | |
| 17 | +de description du protocole (température, nombre d'aménités, nombre de régresseurs vision, catégorie de référence des | |
| 18 | +effets fixes). Après correction, les conclusions sur la **couche vision** sortent renforcées (robustes à la langue, aux | |
| 19 | +EF RTA, au bootstrap en grappes, à la validation spatiale, et jamais exposée au prix) ; celles sur la **couche texte** | |
| 20 | +sont ramenées à ce que la plateforme sans fuite (Realtor.ca) permet d'établir : un gain modeste (+0,6 pt in-sample). | |
| 21 | + | |
| 22 | +--- | |
| 23 | + | |
| 24 | +## 1. Diagnostic par section | |
| 25 | + | |
| 26 | +### Résumé / Introduction | |
| 27 | +- *Forces* : positionnement clair (mesure vs estimateur), contribution en trois points, prudence sur la causalité. | |
| 28 | +- *Faiblesses* : « blind to the listing price » (faux pour DuProprio) ; « deterministic » (faux pour la vision) ; « largest | |
| 29 | + out-of-sample gain of any feature block » (contredit par la table d'ablation) ; aucune mention de la langue ni de la | |
| 30 | + validation spatiale ; « nearly four points » imprécis. | |
| 31 | +- *Corrigé* : résumé et introduction réécrits ; paragraphe explicite sur les trois menaces (fuite, langue, dépendance | |
| 32 | + spatiale) et sur ce que la révision établit ; chiffres ventilés texte / vision. | |
| 33 | + | |
| 34 | +### Revue de littérature | |
| 35 | +- *Forces* : quatre volets pertinents (hédonique, spatial/prédiction, contenu non structuré, microstructure), 35 références | |
| 36 | + réelles. | |
| 37 | +- *Faiblesses* : aucune DOI ; Lindenthal & Johnson incomplète ; rien sur la validation croisée spatiale, les grappes | |
| 38 | + inégales, la stabilité du vocabulaire (Nowak, Price & Smith), la qualité omise dans les indices (Nowak & Smith 2020), | |
| 39 | + la fiabilité de l'annotation par LLM, le rôle du prix demandé (Han & Strange 2016) ; street-view (Naik 2017, Law 2019, | |
| 40 | + Zhang & Dong 2018, Kang 2021) absent ; pas de lien avec le papier frère WP 2. | |
| 41 | +- *Corrigé* : 18 références vérifiées ajoutées et intégrées à l'argument ; DOI pour toutes les entrées ; renvoi à WP 2 sur | |
| 42 | + la langue sans dépendance. | |
| 43 | + | |
| 44 | +### Données | |
| 45 | +- *Faiblesses* : le contenu réel des « descriptions » DuProprio (fiche structurée + prix demandé + évaluation municipale) | |
| 46 | + n'était pas décrit ; langue absente ; codes postaux non exploités ; couverture des couches IA non chiffrée ; « Rooms | |
| 47 | + (Realtor) » agrégé sur 19 123 obs. sans dire que DuProprio vaut 0. | |
| 48 | +- *Corrigé* : nouvelle §3.4 « Content and Language of the Descriptions » (fuite quantifiée, langue par plateforme, écart de | |
| 49 | + prix EN/FR brut 0,37 et intra-municipal 0,21 log-point) ; couverture (100 % texte, 100 % vision, 95,8 % extérieurs) ; | |
| 50 | + annexe C (règle de langue). | |
| 51 | + | |
| 52 | +### Méthodologie | |
| 53 | +- *Forces* : cadre de Rosen, forme semi-log justifiée, Halvorsen–Palmquist, design en deux parties, SE groupées, rétro- | |
| 54 | + transformation de Duan, définitions formelles des estimateurs ML. | |
| 55 | +- *Faiblesses* : température zéro revendiquée pour les deux couches (vision : défaut API) ; alias de modèles non épinglés ; | |
| 56 | + « Seventeen amenity indicators » (15) ; « twelve attributes » confondant champs et régresseurs (21) ; codage des | |
| 57 | + « inconnu » (condition texte → « bon », scores vision → 5) non documenté ; catégorie de référence des EF ville non | |
| 58 | + précisée ; éq. (hedonic) dupliquant ln Area / ln Lot dans X ; absence d'équation / de description de la validation OOS | |
| 59 | + spatiale ; grappes très inégales non discutées ; « deterministic ». | |
| 60 | +- *Corrigé* : tous ces points ; paragraphes « From schema fields to regressors », « Out-of-sample validation » ; bootstrap | |
| 61 | + en grappes ; EF RTA ; indicatrices de langue ; équation scindée et blocs explicités. | |
| 62 | + | |
| 63 | +### Résultats | |
| 64 | +- *Forces* : coefficients correctement convertis en % (vérifiés un à un : e^b − 1) ; discussion sensée ; validation | |
| 65 | + monotone des scores visuels. | |
| 66 | +- *Faiblesses* : « nearly four points » ; âge non chiffré ; score de condition visuelle (non significatif en A) passé sous | |
| 67 | + silence ; validation « indépendante » surinterprétée (monotonie ≠ qualité) ; Sainte-Anne-des-Plaines +143 % non | |
| 68 | + expliqué (2 observations) ; aucune mesure d'erreur d'extraction. | |
| 69 | +- *Corrigé* : chiffres précisés ; colinéarité des trois scores visuels discutée ; nouvelle table `agreement` (κ par champ, | |
| 70 | + précision/rappel, étages, type de bâtiment) ; champs non fiables (bord de l'eau LLM, cadre et type visuels) relégués aux | |
| 71 | + contrôles ; référence des EF explicitée. | |
| 72 | + | |
| 73 | +### Benchmark prédictif | |
| 74 | +- *Forces* : folds identiques, ladder complet, définitions formelles, blend. | |
| 75 | +- *Faiblesses* : « single largest increment from any one feature layer » faux ; poids du blend présenté comme « simple » | |
| 76 | + alors que le script 10 cherchait le meilleur poids sur les prédictions test ; ordre des couches du bloc résiduel | |
| 77 | + inversé par rapport au code ; gain NN de la vision non chiffré. | |
| 78 | +- *Corrigé* : affirmation retirée ; grille de poids (0,771–0,780) et poids emboîté (0,775) rapportés ; w = 0,5 conservé ; | |
| 79 | + architecture décrite conformément au code ; renvoi à la validation spatiale. | |
| 80 | + | |
| 81 | +### Robustesse et limites | |
| 82 | +- *Forces* : SE groupées vs HC3 bien lues ; table par sous-échantillon ; limites honnêtes sur les prix demandés. | |
| 83 | +- *Faiblesses* : rien sur la langue, la fuite, les EF fins, la validation spatiale, l'erreur d'extraction, la version des | |
| 84 | + modèles ; « Five limitations ». | |
| 85 | +- *Corrigé* : quatre nouvelles sous-sections (inférence + bootstrap ; langue ; fuite ; EF RTA et validation spatiale), | |
| 86 | + quatre nouvelles tables ; sept limites. | |
| 87 | + | |
| 88 | +### Conclusion | |
| 89 | +- Réécrite : gains inégaux entre couches, fuite, validation spatiale, extensions (ré-extraction purgée, jeu étiqueté, | |
| 90 | + coordonnées, prix de transaction). | |
| 91 | + | |
| 92 | +--- | |
| 93 | + | |
| 94 | +## 2. Méthodologie — verdict motivé (§3 du master prompt) | |
| 95 | + | |
| 96 | +| Point | Verdict | | |
| 97 | +|---|---| | |
| 98 | +| Spécification justifiée | Oui (semi-log, Rosen, Malpezzi) ; ordre d'entrée des blocs explicité pour l'attribution des gains. | | |
| 99 | +| Hypothèses d'estimation explicites | Oui après révision (MCO, EF, imputation + indicateurs, codage des « inconnu », troncature à 4 000 caractères). | | |
| 100 | +| Variables correctement définies | Oui après correction (15 aménités, 18 + 21 régresseurs IA, référence des EF, échelles ordinales). | | |
| 101 | +| Effets fixes appropriés | Municipalité (195) adéquat au premier ordre ; EF RTA (250) ajoutés en robustesse : coefficients IA stables, R² A 0,755 → 0,764. | | |
| 102 | +| Dépendance spatiale / temporelle | Spatiale : EF + SE groupées + validation par RTA ; temporelle : impossible (coupe instantanée), dit explicitement. | | |
| 103 | +| Erreurs-types | Groupées municipalité (préférées), HC3, bootstrap en grappes (299) ; grappes inégales discutées (MacKinnon & Webb). | | |
| 104 | +| Construction de l'échantillon | Transparente (annexe B) ; divergence 19 115 / 19 123 entre versions du pipeline expliquée dans METHODOLOGIE.md. | | |
| 105 | +| Robustesse face aux vraies menaces | Désormais : fuite (par plateforme), langue (par groupe et en contrôle), localisation fine, validation spatiale, bootstrap. | | |
| 106 | +| Interprétation des coefficients | Correcte (e^b − 1 vérifié) ; prix implicites d'attributs IA lus comme associations prédictives de « ce que le modèle voit ». | | |
| 107 | +| Significativité statistique vs économique | Distinguées (magnitudes en %, IC bootstrap). | | |
| 108 | +| Affirmations causales | Aucune ; limites explicites. | | |
| 109 | + | |
| 110 | +--- | |
| 111 | + | |
| 112 | +## 3. Littérature | |
| 113 | + | |
| 114 | +- 35 références existantes **toutes vérifiées** (Crossref / arXiv) ; corrections : Lindenthal & Johnson 2021 (vol. 71(3), 353–384), | |
| 115 | + entrées NeurIPS/ICLR/arXiv complétées ; DOI ajoutés partout (Kennedy 1981 sans DOI, vérifié via RePEc). | |
| 116 | +- 18 références ajoutées, toutes vérifiées (liste et DOI dans le CHANGELOG §3), intégrées dans l'argument (qualité omise, | |
| 117 | + vocabulaire instable, annotation LLM, prix demandé, validation bloquée, grappes inégales, street-view). | |
| 118 | +- Aucune référence retirée. Total 53. | |
| 119 | + | |
| 120 | +## 4. Résultats — incohérences trouvées | |
| 121 | + | |
| 122 | +1. Vision = « plus grand gain de tout bloc » (résumé, intro, benchmark, ablation, conclusion, highlights, légende) — faux ; | |
| 123 | + corrigé partout. | |
| 124 | +2. 17 vs 15 aménités ; 12 attributs vs 21 régresseurs ; curb appeal 1–5 (README) vs 1–10 (papier) — corrigés. | |
| 125 | +3. Température zéro « pour les deux couches » — faux pour la vision ; corrigé. | |
| 126 | +4. « Reference city » — c'est la catégorie regroupée ; corrigé. | |
| 127 | +5. Petites différences (± 0,001) entre tables issues de runs différents (ordre des colonnes dans HistGBM) — notées. | |
| 128 | +6. Script 13 imputait les variables avant la CV GBM (0,7689) alors que le script 12 laissait les NaN (0,7695) ; la table | |
| 129 | + `models` (0,770) suit le script 09/12 ; documenté, le script 18 suit la convention NaN. | |
| 130 | +7. Les scripts 11–14 et 16 ne pouvaient plus s'exécuter (`v5_ml.py` introuvable après l'harmonisation) — réparé. | |
| 131 | + | |
| 132 | +## 5. Limites restantes | |
| 133 | + | |
| 134 | +- Prix demandés ; coupe instantanée ; pas de prix de transaction. | |
| 135 | +- Fuite du prix dans le texte DuProprio : seule une ré-extraction purgée (API) tranchera entre « information structurée | |
| 136 | + légitime » et « biais d'ancrage » ; en attendant, gains texte crédibles = Realtor.ca. | |
| 137 | +- Pas de jeu étiqueté humain ; erreur d'extraction mesurée indirectement seulement. | |
| 138 | +- Vision à température par défaut, alias de modèles ; variabilité test–retest non mesurée. | |
| 139 | +- Prime conditionnelle de 7 % des annonces anglaises : proxy de localisation/clientèle, non interprétée causalement. | |
| 140 | +- Modèle commun moins adéquat pour DuProprio (R² OOS 0,58 ; R² OLS intra-groupe négatif). | |
| 141 | +- Effets fixes de municipalités à cellules rares (ex. Sainte-Anne-des-Plaines). | |
| 142 | + | |
| 143 | +## 6. Analyses recommandées non exécutées | |
| 144 | + | |
| 145 | +1. Ré-extraction LLM sur les descriptions DuProprio purgées du bloc structuré et du prix (≈ 3 767 appels, ≈ 1 $) et | |
| 146 | + comparaison des coefficients / gains. | |
| 147 | +2. Validation humaine : 300 annonces codées à la main (texte) et 300 façades (vision) → précision/rappel par champ. | |
| 148 | +3. Test–retest de la vision : ré-extraction de 500 façades à température 0 et à température par défaut. | |
| 149 | +4. Panel de photos intérieures (cuisine, salle de bain) sous le même schéma. | |
| 150 | +5. Appariement au registre foncier (prix de transaction) ; ratio liste/vente par attribut IA. | |
| 151 | +6. Variables spatiales continues (coordonnées DuProprio, centroïdes de RTA) et modèle spatial (SAR/SEM ou GWR). | |
| 152 | +7. Wild cluster bootstrap (Webb weights) en complément du bootstrap par paires. | |
| 153 | +8. Régénération des figures via `14_figures_v5.py` (inchangées en substance). | |
| 154 | + | |
| 155 | +## 7. Maturité pour publication | |
| 156 | + | |
| 157 | +- **Revue cible** : *Journal of Housing Economics* (déjà envisagée ; `13_revision_extras.py`) ou *Journal of Real Estate | |
| 158 | + Finance and Economics* ; *Real Estate Economics* exigerait des prix de transaction. Alternative orientée méthodes : | |
| 159 | + *Journal of Property Research* ou *Journal of Real Estate Research*. | |
| 160 | +- **Risques de rejet** : (1) prix demandés plutôt que transactions (le plus probable) ; (2) fuite DuProprio — désormais | |
| 161 | + documentée, mais un arbitre demandera la ré-extraction purgée ; (3) absence de validation humaine des extractions ; | |
| 162 | + (4) dépendance aux versions de modèles propriétaires ; (5) longueur (46 p.) — une version revue devrait déplacer | |
| 163 | + `agreement`, `rob_spatial` et les définitions formelles ML en annexe. | |
| 164 | +- **État** : manuscrit interne cohérent, chiffres vérifiés, bibliographie vérifiée ; prêt pour SSRN après lecture de | |
| 165 | + l'auteur ; pour soumission en revue, exécuter d'abord les recommandations 1 et 2. | |
modified
docs/highlights_elsevier.tex
+6 −5
@@ -1,6 +1,7 @@ | ||
| 1 | 1 | % ============================================================================ |
| 2 | 2 | % Highlights — separate file required at Elsevier submission |
| 3 | 3 | % (3-5 bullets, max 85 characters each, results-oriented) |
| 4 | +% Revised 2026-10-17 (version 2.1 of the working paper) | |
| 4 | 5 | % ============================================================================ |
| 5 | 6 | \documentclass[12pt]{article} |
| 6 | 7 | \usepackage[utf8]{inputenc} |
@@ -8,10 +9,10 @@ | ||
| 8 | 9 | \begin{document} |
| 9 | 10 | \section*{Highlights} |
| 10 | 11 | \begin{itemize} |
| 11 | − \item LLM and vision models turn listing text and photos into hedonic regressors | |
| 12 | − \item Schema-constrained decoding makes AI outputs reproducible econometric variables | |
| 13 | − \item Two AI feature layers add four points of $R^2$ to a rich hedonic model | |
| 14 | − \item Façade-vision features give the largest out-of-sample gain of any block | |
| 15 | − \item Curb appeal, materials, and luxury cues carry sensible implicit prices | |
| 12 | + \item LLM and vision models turn listing text and photos into auditable hedonic regressors | |
| 13 | + \item Two AI layers add 3.8 points of $R^2$ to a rich hedonic model; 3.0 come from the photo | |
| 14 | + \item Façade-vision features lift every estimator, more than switching OLS to a forest | |
| 15 | + \item Curb appeal, materials and luxury cues price sensibly under clustered and bootstrap SEs | |
| 16 | + \item FSBO descriptions embed the asking price: text gains are credible only on the MLS | |
| 16 | 17 | \end{itemize} |
| 17 | 18 | \end{document} |
modified
paper/appendix/appendix.tex
+58 −30
@@ -12,52 +12,62 @@ | ||
| 12 | 12 | \section{Machine-Generated Feature Definitions} |
| 13 | 13 | \label{app:features} |
| 14 | 14 | |
| 15 | −Table~\ref{tab:app_features} lists the attributes extracted by the language and | |
| 16 | −vision models under their respective strict JSON schemas. All fields use closed | |
| 17 | −enumerations or booleans; absent information is coded as \texttt{false}, | |
| 18 | −\texttt{unknown}, or an empty list. | |
| 15 | +Table~\ref{tab:app_features} lists the fields extracted by the language and | |
| 16 | +vision models under their respective strict JSON schemas, with the value domains as | |
| 17 | +specified in the extraction scripts (the enumerations are in French in the schema; | |
| 18 | +they are translated here). All fields use closed enumerations, integers, or | |
| 19 | +booleans; absent information is coded as \texttt{false}, \texttt{unknown}, or an | |
| 20 | +empty list. The mapping from fields to regressors is described in | |
| 21 | +Section~\ref{subsec:vision}. | |
| 19 | 22 | |
| 20 | 23 | \begin{table}[htbp] |
| 21 | 24 | \centering |
| 22 | 25 | \begin{threeparttable} |
| 23 | − \caption{Attributes Extracted by the AI Models} | |
| 26 | + \caption{Fields Extracted by the AI Models} | |
| 24 | 27 | \label{tab:app_features} |
| 25 | 28 | \small |
| 26 | − \begin{tabular}{@{}p{2.9cm}p{4.4cm}p{6.3cm}@{}} | |
| 29 | + \begin{tabular}{@{}p{3.1cm}p{4.3cm}p{6.2cm}@{}} | |
| 27 | 30 | \toprule |
| 28 | 31 | Layer & Field & Domain \\ |
| 29 | 32 | \midrule |
| 30 | − \multicolumn{3}{@{}l}{\textit{Panel A: Text (LLM, \texttt{gpt-4o-mini})}} \\[3pt] | |
| 31 | − Condition & \texttt{condition} & to renovate / original / good / renovated / like-new / new \\ | |
| 32 | − Turnkey & \texttt{turnkey} & boolean \\ | |
| 33 | − Renovated kitchen & \texttt{renovated\_kitchen} & boolean \\ | |
| 34 | − Renovated bathroom & \texttt{renovated\_bathroom} & boolean \\ | |
| 35 | − Flooring & \texttt{flooring} & hardwood / ceramic / laminate / carpet / vinyl / concrete \\ | |
| 36 | − Countertop & \texttt{countertop} & granite / quartz / marble / laminate / wood \\ | |
| 37 | − Heating & \texttt{heating} & electric / heat pump / wood / gas / oil / radiant / geothermal \\ | |
| 38 | − Water view & \texttt{view} & water / mountain / city / none \\ | |
| 39 | − Income property & \texttt{income\_property} & boolean \\ | |
| 40 | − Large lot; quiet area & \texttt{large\_lot}, \texttt{quiet\_area} & boolean \\[6pt] | |
| 41 | − \multicolumn{3}{@{}l}{\textit{Panel B: Vision (\texttt{claude-haiku-4-5}, façade)}} \\[3pt] | |
| 42 | − Building type (visual) & \texttt{building\_type\_visual} & detached / semi / row / condo / cottage / land \\ | |
| 33 | + \multicolumn{3}{@{}l}{\textit{Panel A: Text (LLM, \texttt{gpt-4o-mini}; 20 fields, 18 regressors)}} \\[3pt] | |
| 34 | + Condition & \texttt{condition} & to renovate / original / good / renovated / like-new / new / unknown \\ | |
| 35 | + Turnkey; recently renovated & \texttt{turnkey}, \texttt{recently\_renovated} & boolean \\ | |
| 36 | + Renovated kitchen / bathroom & \texttt{renovated\_kitchen}, \texttt{renovated\_bathroom} & boolean \\ | |
| 37 | + Flooring (multi-valued) & \texttt{flooring} & hardwood / ceramic / floating / carpet / vinyl / concrete / other \\ | |
| 38 | + Countertop & \texttt{countertop} & granite / quartz / marble / laminate / wood / other / unknown \\ | |
| 39 | + Heating (multi-valued) & \texttt{heating} & electric / baseboards / heat pump / wood / gas / oil / radiant / geothermal / other \\ | |
| 40 | + View & \texttt{view} & water / mountain / city / none / unknown \\ | |
| 41 | + Amenities & \texttt{garage}, \texttt{pool}, \texttt{waterfront}, \texttt{finished\_basement}, \texttt{fireplace}, \texttt{central\_ac} & boolean \\ | |
| 42 | + New construction; income property & \texttt{new\_construction}, \texttt{income\_property} & boolean \\ | |
| 43 | + Large lot; quiet area & \texttt{large\_lot}, \texttt{quiet\_area} & boolean \\ | |
| 44 | + Highlights & \texttt{highlights} & 3--6 free-text keywords (not used in the regressions) \\[6pt] | |
| 45 | + \multicolumn{3}{@{}l}{\textit{Panel B: Vision (\texttt{claude-haiku-4-5}, façade; 12 fields, 21 regressors)}} \\[3pt] | |
| 46 | + Exterior shot & \texttt{is\_exterior} & boolean \\ | |
| 47 | + Building type (visual) & \texttt{building\_type\_visual} & detached / semi-detached / row / condo building / cottage / land / other \\ | |
| 43 | 48 | Condition score & \texttt{condition\_score} & integer 1--10 \\ |
| 44 | 49 | Curb appeal & \texttt{curb\_appeal} & integer 1--10 \\ |
| 45 | − Renovation level & \texttt{renovation\_level} & to renovate / dated / standard / renovated / high-end \\ | |
| 46 | − Exterior materials & \texttt{exterior\_materials} & brick / stone / vinyl / wood / aluminum / stucco / concrete \\ | |
| 50 | + Renovation level & \texttt{renovation\_level} & to renovate / dated / standard / renovated / high-end / unknown \\ | |
| 51 | + Exterior materials (multi-valued) & \texttt{exterior\_materials} & brick / stone / vinyl / wood / aluminum / stucco / roughcast / concrete / other \\ | |
| 47 | 52 | Landscaping & \texttt{landscaping} & none / minimal / maintained / manicured \\ |
| 48 | − Setting & \texttt{setting} & dense urban / suburban / rural / waterfront / wooded \\ | |
| 49 | − Luxury indicator & \texttt{curb\_luxury} & boolean \\ | |
| 53 | + Garage visible & \texttt{has\_garage\_visible} & boolean \\ | |
| 54 | + Storeys (visual) & \texttt{storeys\_visual} & 1 / 1.5 / 2 / 3+ / unknown \\ | |
| 55 | + Setting & \texttt{setting} & dense urban / suburban / rural / waterfront / wooded / unknown \\ | |
| 50 | 56 | Photo quality & \texttt{photo\_quality} & integer 1--10 \\ |
| 57 | + Luxury indicator & \texttt{curb\_luxury} & boolean \\ | |
| 51 | 58 | \bottomrule |
| 52 | 59 | \end{tabular} |
| 53 | 60 | \begin{tablenotes}[flushleft] |
| 54 | 61 | \footnotesize |
| 55 | 62 | \item \textit{Notes:} Both extractions use schema-constrained decoding with |
| 56 | − closed enumerations, required fields, and \texttt{additionalProperties:false}; | |
| 57 | − decoding temperature is zero. The text layer reads the free-text description; | |
| 58 | − the vision layer analyzes one façade photograph per listing. Fields are mapped | |
| 59 | − to numeric regressors (booleans to $0/1$, ordinal scales to integers, categories | |
| 60 | − to indicators), each with an availability flag. | |
| 63 | + closed enumerations, required fields, and \texttt{additionalProperties:false}. | |
| 64 | + The text layer reads the free-text description (truncated at 4{,}000 characters) | |
| 65 | + at temperature zero; the vision layer analyzes one façade photograph per listing | |
| 66 | + at the API's default temperature. Model identifiers are the API aliases current in | |
| 67 | + July 2026. Fields are mapped to numeric regressors (booleans to $0/1$, ordinal | |
| 68 | + scales to integers, multi-valued fields and categories to indicators); the text | |
| 69 | + condition scale is coded $0$--$5$ with ``unknown'' at~2, the visual renovation | |
| 70 | + level $0$--$4$ with ``unknown'' at~2, and landscaping $0$--$3$. | |
| 61 | 71 | \end{tablenotes} |
| 62 | 72 | \end{threeparttable} |
| 63 | 73 | \end{table} |
@@ -77,16 +87,34 @@ enumerations or booleans; absent information is coded as \texttt{false}, | ||
| 77 | 87 | Realtor.ca raw & 27{,}302 \\ |
| 78 | 88 | DuProprio raw & 7{,}693 \\ |
| 79 | 89 | Houses (single-family + townhouse) with price & 19{,}273 \\ |
| 80 | − After outlier cleaning & 19{,}123 \\ | |
| 90 | + After outlier cleaning (price bounds, price-per-ft$^2$ trim) & 19{,}123 \\ | |
| 91 | + \quad of which Realtor.ca / DuProprio & 15{,}356 / 3{,}767 \\ | |
| 81 | 92 | \quad of which with measured living area (Model~A) & 9{,}446 \\ |
| 93 | + \quad of which with a detected exterior photograph & 18{,}314 \\ | |
| 82 | 94 | \bottomrule |
| 83 | 95 | \end{tabular} |
| 84 | 96 | \begin{tablenotes}[flushleft] |
| 85 | 97 | \footnotesize |
| 86 | 98 | \item \textit{Notes:} See Section~\ref{sec:data}. ``Measured living area'' means |
| 87 | − reported area or area reconstructed from room-level dimensions. | |
| 99 | + reported area or area reconstructed from room-level dimensions. Both AI layers | |
| 100 | + cover all 19{,}123 cleaned listings. | |
| 88 | 101 | \end{tablenotes} |
| 89 | 102 | \end{threeparttable} |
| 90 | 103 | \end{table} |
| 91 | 104 | |
| 105 | +\section{Language Classification} | |
| 106 | +\label{app:language} | |
| 107 | + | |
| 108 | +Each description is classified from the counts $e$ and $f$ of English and French | |
| 109 | +stop words it contains (articles, prepositions, pronouns, and auxiliaries such as | |
| 110 | +\textit{the, and, with, is} and \textit{le, la, les, et, avec, est}). A description is | |
| 111 | +``English'' if $e\ge1.5f$, ``French'' if $f\ge1.5e$, and ``mixed'' otherwise or when | |
| 112 | +neither count is positive. On Realtor.ca the mixed class is small (2.6\%) and | |
| 113 | +consists mostly of very short descriptions; on DuProprio it is large (51.7\%) | |
| 114 | +because the crawler returns the automated English translation followed by the | |
| 115 | +original French comments. Table~\ref{tab:rob_language_source} reports the gains from | |
| 116 | +the AI layers within each class, and Table~\ref{tab:rob_ai_coefs} the effect of | |
| 117 | +adding the language indicators to the hedonic regression. The language variable is | |
| 118 | +produced by \texttt{scripts/18\_revision\_language\_leakage\_spatial.py}. | |
| 119 | + | |
| 92 | 120 | \end{appendices} |
modified
paper/figures/nn_diagram.tex
+1 −1
@@ -63,7 +63,7 @@ | ||
| 63 | 63 | % ---- residual detail callout ---- |
| 64 | 64 | \node[detail, right=10mm of resb] (dtl) |
| 65 | 65 | {\textbf{Res block:} $x \mapsto x + f(x)$\\ |
| 66 | − $f=$ Lin$_{256}\!\circ$Drop$\circ$Lin$_{512}\!\circ$GELU$\circ$BN}; | |
| 66 | + $f=$ Drop$\circ$Lin$_{256}\!\circ$Drop$\circ$GELU\\ $\circ$Lin$_{512}\!\circ$BN}; | |
| 67 | 67 | \draw[->, dashed, black!45] (resb.east)--(dtl.west); |
| 68 | 68 | |
| 69 | 69 | % ---- training / ensemble annotation ---- |
modified
paper/main.pdf
+0 −0
Binary file not shown.
modified
paper/main.tex
+32 −19
@@ -71,26 +71,33 @@ | ||
| 71 | 71 | \newcommand{\WPnumber}{14} |
| 72 | 72 | \newcommand{\WPtitle}{Hedonic House Pricing with Language-Model and Vision Features} |
| 73 | 73 | \newcommand{\WPsubtitle}{Evidence from Quebec Real-Estate Listings} |
| 74 | −\newcommand{\WPdate}{July 2026} | |
| 75 | −\newcommand{\WPversion}{2.0} | |
| 74 | +\newcommand{\WPdate}{October 2026} | |
| 75 | +\newcommand{\WPversion}{2.1} | |
| 76 | 76 | \newcommand{\WPabstract}{% |
| 77 | 77 | Hedonic house-price models are bounded by the characteristics an analyst can |
| 78 | 78 | measure, yet much of a home's value is recorded only in the free-text description |
| 79 | 79 | and photographs of its listing. We treat general-purpose AI models as a |
| 80 | 80 | feature-engineering technology for hedonic analysis: a large language model |
| 81 | 81 | converts each description into structured property specifications, and a |
| 82 | − vision--language model converts the façade photograph into objective visual | |
| 83 | − attributes, both under strict JSON schemas that render the outputs reproducible | |
| 84 | − econometric variables. Using 19{,}123 Quebec house listings, the two AI layers | |
| 85 | − raise the $R^2$ of an already rich log--linear hedonic specification from 0.717 to | |
| 86 | − 0.755, and the vision layer delivers the largest out-of-sample gain of any feature | |
| 87 | − block for every estimator, from OLS to gradient boosting and neural networks (best | |
| 88 | − ensemble: out-of-sample $R^2$ of 0.779, median absolute error 14.0\%). The | |
| 89 | − extracted attributes carry economically sensible implicit prices---2.3\% per point | |
| 90 | − of curb appeal, 3--4\% for brick or stone façades---that survive | |
| 91 | − municipality-clustered inference. | |
| 82 | + vision--language model converts the façade photograph into visual attributes, both | |
| 83 | + under strict JSON schemas that make the outputs auditable econometric variables. | |
| 84 | + Using 19{,}123 Quebec house listings, the two AI layers raise the $R^2$ of an | |
| 85 | + already rich log-linear hedonic specification with municipality fixed effects from | |
| 86 | + 0.717 to 0.755, 3.0 of the 3.8 points coming from the façade photograph, and they | |
| 87 | + raise the out-of-sample $R^2$ of every estimator from OLS to gradient boosting and | |
| 88 | + neural networks (best ensemble: $R^2$ of 0.779, median absolute error 14.0\%). The | |
| 89 | + vision layer adds more to the linear model than switching from OLS to a random | |
| 90 | + forest does. The extracted attributes carry economically sensible implicit | |
| 91 | + prices---2.3\% per point of curb appeal, 3--4\% for brick or stone façades---that | |
| 92 | + survive municipality-clustered inference, a cluster bootstrap, postal-code fixed | |
| 93 | + effects, and a control for the language of the description, which itself carries a | |
| 94 | + 7\% conditional premium for English listings. We also document that | |
| 95 | + for-sale-by-owner descriptions embed the asking price, so that the text layer's | |
| 96 | + gain is credible only on the brokered platform, and that spatially grouped | |
| 97 | + cross-validation lowers all accuracy levels by three to five points while | |
| 98 | + preserving the AI increments. | |
| 92 | 99 | } |
| 93 | −\newcommand{\WPkeywords}{hedonic pricing, house prices, large language models, computer vision, feature engineering, Quebec} | |
| 100 | +\newcommand{\WPkeywords}{hedonic pricing, house prices, large language models, computer vision, text as data, automated valuation, Quebec} | |
| 94 | 101 | \newcommand{\WPjel}{R31, C21, C55, R21} |
| 95 | 102 | |
| 96 | 103 | % --- Author --- |
@@ -133,14 +140,20 @@ appeared to influence the work reported in this paper. | ||
| 133 | 140 | \paragraph{Data availability.} The listing data were collected from publicly |
| 134 | 141 | accessible web platforms (Realtor.ca and DuProprio) on 3~July~2026. The full |
| 135 | 142 | data-construction code, the extraction schemas, and the derived analysis dataset |
| 136 | −(excluding copyrighted listing text and images) are available from the author upon | |
| 137 | −reasonable request. | |
| 138 | − | |
| 139 | −\paragraph{Use of AI models.} Large language and vision--language models | |
| 140 | −(\texttt{gpt-4o-mini} and \texttt{claude-haiku-4-5}) are the object of study of this | |
| 143 | +(excluding copyrighted listing text and images), together with the raw JSON outputs | |
| 144 | +of the two AI models, are available from the author upon reasonable request. The | |
| 145 | +robustness analyses added in version 2.1 are produced by a single script | |
| 146 | +(\path{scripts/18_revision_language_leakage_spatial.py}) from the archived | |
| 147 | +extractions, without new API calls. | |
| 148 | + | |
| 149 | +\paragraph{Use of AI models.} The large language model \texttt{gpt-4o-mini} and the | |
| 150 | +vision--language model \texttt{claude-haiku-4-5} are the object of study of this | |
| 141 | 151 | paper and were used exclusively as documented in Section~\ref{sec:methodology} to |
| 142 | 152 | extract structured features from listing text and photographs. They were not used to |
| 143 | −generate the analysis or the conclusions of the paper. | |
| 153 | +generate the analysis or the conclusions of the paper. An AI coding assistant was | |
| 154 | +used in the October 2026 revision, under the author's direction, to check the | |
| 155 | +manuscript for internal consistency and to run the additional robustness analyses; | |
| 156 | +all results were verified by the author. | |
| 144 | 157 | |
| 145 | 158 | \newpage |
| 146 | 159 | \bibliography{references} |
modified
paper/references.bib
+282 −36
@@ -5,7 +5,8 @@ | ||
| 5 | 5 | volume={82}, |
| 6 | 6 | number={1}, |
| 7 | 7 | pages={34--55}, |
| 8 | − year={1974} | |
| 8 | + year={1974}, | |
| 9 | + doi={10.1086/260169} | |
| 9 | 10 | } |
| 10 | 11 | |
| 11 | 12 | @article{lancaster1966new, |
@@ -15,7 +16,8 @@ | ||
| 15 | 16 | volume={74}, |
| 16 | 17 | number={2}, |
| 17 | 18 | pages={132--157}, |
| 18 | − year={1966} | |
| 19 | + year={1966}, | |
| 20 | + doi={10.1086/259131} | |
| 19 | 21 | } |
| 20 | 22 | |
| 21 | 23 | @article{sirmans2005composition, |
@@ -25,7 +27,8 @@ | ||
| 25 | 27 | volume={13}, |
| 26 | 28 | number={1}, |
| 27 | 29 | pages={1--44}, |
| 28 | − year={2005} | |
| 30 | + year={2005}, | |
| 31 | + doi={10.1080/10835547.2005.12090154} | |
| 29 | 32 | } |
| 30 | 33 | |
| 31 | 34 | @incollection{malpezzi2003hedonic, |
@@ -35,7 +38,8 @@ | ||
| 35 | 38 | editor={O'Sullivan, Tony and Gibb, Kenneth}, |
| 36 | 39 | pages={67--89}, |
| 37 | 40 | publisher={Blackwell Science}, |
| 38 | − year={2003} | |
| 41 | + year={2003}, | |
| 42 | + doi={10.1002/9780470690680.ch5} | |
| 39 | 43 | } |
| 40 | 44 | |
| 41 | 45 | @article{duan1983smearing, |
@@ -45,7 +49,8 @@ | ||
| 45 | 49 | volume={78}, |
| 46 | 50 | number={383}, |
| 47 | 51 | pages={605--610}, |
| 48 | − year={1983} | |
| 52 | + year={1983}, | |
| 53 | + doi={10.1080/01621459.1983.10478017} | |
| 49 | 54 | } |
| 50 | 55 | |
| 51 | 56 | @article{white1980heteroskedasticity, |
@@ -55,7 +60,8 @@ | ||
| 55 | 60 | volume={48}, |
| 56 | 61 | number={4}, |
| 57 | 62 | pages={817--838}, |
| 58 | − year={1980} | |
| 63 | + year={1980}, | |
| 64 | + doi={10.2307/1912934} | |
| 59 | 65 | } |
| 60 | 66 | |
| 61 | 67 | @article{mackinnon1985some, |
@@ -65,7 +71,8 @@ | ||
| 65 | 71 | volume={29}, |
| 66 | 72 | number={3}, |
| 67 | 73 | pages={305--325}, |
| 68 | − year={1985} | |
| 74 | + year={1985}, | |
| 75 | + doi={10.1016/0304-4076(85)90158-7} | |
| 69 | 76 | } |
| 70 | 77 | |
| 71 | 78 | @article{can1992spatial, |
@@ -75,7 +82,8 @@ | ||
| 75 | 82 | volume={22}, |
| 76 | 83 | number={3}, |
| 77 | 84 | pages={453--474}, |
| 78 | − year={1992} | |
| 85 | + year={1992}, | |
| 86 | + doi={10.1016/0166-0462(92)90039-4} | |
| 79 | 87 | } |
| 80 | 88 | |
| 81 | 89 | @book{anselin1988spatial, |
@@ -83,7 +91,8 @@ | ||
| 83 | 91 | author={Anselin, Luc}, |
| 84 | 92 | publisher={Kluwer Academic Publishers}, |
| 85 | 93 | address={Dordrecht}, |
| 86 | − year={1988} | |
| 94 | + year={1988}, | |
| 95 | + doi={10.1007/978-94-015-7799-1} | |
| 87 | 96 | } |
| 88 | 97 | |
| 89 | 98 | @article{gentzkow2019text, |
@@ -93,7 +102,8 @@ | ||
| 93 | 102 | volume={57}, |
| 94 | 103 | number={3}, |
| 95 | 104 | pages={535--574}, |
| 96 | − year={2019} | |
| 105 | + year={2019}, | |
| 106 | + doi={10.1257/jel.20181020} | |
| 97 | 107 | } |
| 98 | 108 | |
| 99 | 109 | @article{poursaeed2018vision, |
@@ -103,7 +113,8 @@ | ||
| 103 | 113 | volume={29}, |
| 104 | 114 | number={4}, |
| 105 | 115 | pages={667--676}, |
| 106 | − year={2018} | |
| 116 | + year={2018}, | |
| 117 | + doi={10.1007/s00138-018-0922-2} | |
| 107 | 118 | } |
| 108 | 119 | |
| 109 | 120 | @inproceedings{ahmed2016house, |
@@ -111,7 +122,8 @@ | ||
| 111 | 122 | author={Ahmed, Eman H. and Moustafa, Mohamed}, |
| 112 | 123 | booktitle={Proceedings of the 8th International Joint Conference on Computational Intelligence (NCTA)}, |
| 113 | 124 | pages={62--68}, |
| 114 | − year={2016} | |
| 125 | + year={2016}, | |
| 126 | + doi={10.5220/0006040700620068} | |
| 115 | 127 | } |
| 116 | 128 | |
| 117 | 129 | @article{bin2004prediction, |
@@ -121,7 +133,8 @@ | ||
| 121 | 133 | volume={13}, |
| 122 | 134 | number={1}, |
| 123 | 135 | pages={68--84}, |
| 124 | − year={2004} | |
| 136 | + year={2004}, | |
| 137 | + doi={10.1016/j.jhe.2004.01.001} | |
| 125 | 138 | } |
| 126 | 139 | |
| 127 | 140 | @article{mullainathan2017machine, |
@@ -131,7 +144,8 @@ | ||
| 131 | 144 | volume={31}, |
| 132 | 145 | number={2}, |
| 133 | 146 | pages={87--106}, |
| 134 | − year={2017} | |
| 147 | + year={2017}, | |
| 148 | + doi={10.1257/jep.31.2.87} | |
| 135 | 149 | } |
| 136 | 150 | |
| 137 | 151 | @article{halvorsen1980interpretation, |
@@ -151,7 +165,8 @@ | ||
| 151 | 165 | volume={45}, |
| 152 | 166 | number={1}, |
| 153 | 167 | pages={5--32}, |
| 154 | − year={2001} | |
| 168 | + year={2001}, | |
| 169 | + doi={10.1023/A:1010933404324} | |
| 155 | 170 | } |
| 156 | 171 | |
| 157 | 172 | @article{friedman2001greedy, |
@@ -161,35 +176,43 @@ | ||
| 161 | 176 | volume={29}, |
| 162 | 177 | number={5}, |
| 163 | 178 | pages={1189--1232}, |
| 164 | − year={2001} | |
| 179 | + year={2001}, | |
| 180 | + doi={10.1214/aos/1013203451} | |
| 165 | 181 | } |
| 166 | 182 | |
| 167 | 183 | @article{guo2016entity, |
| 168 | 184 | title={Entity embeddings of categorical variables}, |
| 169 | 185 | author={Guo, Cheng and Berkhahn, Felix}, |
| 170 | − journal={arXiv preprint arXiv:1604.06737}, | |
| 171 | − year={2016} | |
| 186 | + journal={arXiv preprint}, | |
| 187 | + volume={arXiv:1604.06737}, | |
| 188 | + year={2016}, | |
| 189 | + doi={10.48550/arXiv.1604.06737} | |
| 172 | 190 | } |
| 173 | 191 | |
| 174 | 192 | @inproceedings{loshchilov2019decoupled, |
| 175 | 193 | title={Decoupled weight decay regularization}, |
| 176 | 194 | author={Loshchilov, Ilya and Hutter, Frank}, |
| 177 | 195 | booktitle={International Conference on Learning Representations (ICLR)}, |
| 178 | − year={2019} | |
| 196 | + year={2019}, | |
| 197 | + note={arXiv:1711.05101}, | |
| 198 | + doi={10.48550/arXiv.1711.05101} | |
| 179 | 199 | } |
| 180 | 200 | |
| 181 | 201 | @inproceedings{gorishniy2021revisiting, |
| 182 | 202 | title={Revisiting deep learning models for tabular data}, |
| 183 | 203 | author={Gorishniy, Yury and Rubachev, Ivan and Khrulkov, Valentin and Babenko, Artem}, |
| 184 | − booktitle={Advances in Neural Information Processing Systems (NeurIPS)}, | |
| 185 | − year={2021} | |
| 204 | + booktitle={Advances in Neural Information Processing Systems (NeurIPS) 34}, | |
| 205 | + year={2021}, | |
| 206 | + note={arXiv:2106.11959}, | |
| 207 | + doi={10.48550/arXiv.2106.11959} | |
| 186 | 208 | } |
| 187 | 209 | |
| 188 | 210 | @inproceedings{grinsztajn2022why, |
| 189 | 211 | title={Why do tree-based models still outperform deep learning on tabular data?}, |
| 190 | 212 | author={Grinsztajn, L{\'e}o and Oyallon, Edouard and Varoquaux, Ga{\"e}l}, |
| 191 | − booktitle={Advances in Neural Information Processing Systems (NeurIPS)}, | |
| 192 | − year={2022} | |
| 213 | + booktitle={Advances in Neural Information Processing Systems (NeurIPS) 35}, | |
| 214 | + year={2022}, | |
| 215 | + doi={10.52202/068431-0037} | |
| 193 | 216 | } |
| 194 | 217 | |
| 195 | 218 | @inproceedings{he2016deep, |
@@ -197,7 +220,8 @@ | ||
| 197 | 220 | author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian}, |
| 198 | 221 | booktitle={IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, |
| 199 | 222 | pages={770--778}, |
| 200 | − year={2016} | |
| 223 | + year={2016}, | |
| 224 | + doi={10.1109/CVPR.2016.90} | |
| 201 | 225 | } |
| 202 | 226 | |
| 203 | 227 | @article{nowak2017textual, |
@@ -207,7 +231,8 @@ | ||
| 207 | 231 | volume={32}, |
| 208 | 232 | number={4}, |
| 209 | 233 | pages={896--918}, |
| 210 | − year={2017} | |
| 234 | + year={2017}, | |
| 235 | + doi={10.1002/jae.2550} | |
| 211 | 236 | } |
| 212 | 237 | |
| 213 | 238 | @article{shen2021information, |
@@ -216,7 +241,8 @@ | ||
| 216 | 241 | journal={Journal of Urban Economics}, |
| 217 | 242 | volume={121}, |
| 218 | 243 | pages={103299}, |
| 219 | − year={2021} | |
| 244 | + year={2021}, | |
| 245 | + doi={10.1016/j.jue.2020.103299} | |
| 220 | 246 | } |
| 221 | 247 | |
| 222 | 248 | @article{johnson2020curb, |
@@ -226,14 +252,19 @@ | ||
| 226 | 252 | volume={60}, |
| 227 | 253 | number={1-2}, |
| 228 | 254 | pages={111--133}, |
| 229 | − year={2020} | |
| 255 | + year={2020}, | |
| 256 | + doi={10.1007/s11146-019-09713-z} | |
| 230 | 257 | } |
| 231 | 258 | |
| 232 | 259 | @article{lindenthal2021architecture, |
| 233 | 260 | title={Machine learning, architectural styles and property values}, |
| 234 | 261 | author={Lindenthal, Thies and Johnson, Erik B.}, |
| 235 | 262 | journal={Journal of Real Estate Finance and Economics}, |
| 236 | − year={2021} | |
| 263 | + volume={71}, | |
| 264 | + number={3}, | |
| 265 | + pages={353--384}, | |
| 266 | + year={2021}, | |
| 267 | + doi={10.1007/s11146-021-09845-1} | |
| 237 | 268 | } |
| 238 | 269 | |
| 239 | 270 | @techreport{glaeser2018vision, |
@@ -242,7 +273,8 @@ | ||
| 242 | 273 | institution={National Bureau of Economic Research}, |
| 243 | 274 | type={Working Paper}, |
| 244 | 275 | number={25174}, |
| 245 | − year={2018} | |
| 276 | + year={2018}, | |
| 277 | + doi={10.3386/w25174} | |
| 246 | 278 | } |
| 247 | 279 | |
| 248 | 280 | @article{kok2017bigdata, |
@@ -252,7 +284,8 @@ | ||
| 252 | 284 | volume={43}, |
| 253 | 285 | number={6}, |
| 254 | 286 | pages={202--211}, |
| 255 | − year={2017} | |
| 287 | + year={2017}, | |
| 288 | + doi={10.3905/jpm.2017.43.6.202} | |
| 256 | 289 | } |
| 257 | 290 | |
| 258 | 291 | @article{hendel2009mls, |
@@ -262,7 +295,8 @@ | ||
| 262 | 295 | volume={99}, |
| 263 | 296 | number={5}, |
| 264 | 297 | pages={1878--1898}, |
| 265 | − year={2009} | |
| 298 | + year={2009}, | |
| 299 | + doi={10.1257/aer.99.5.1878} | |
| 266 | 300 | } |
| 267 | 301 | |
| 268 | 302 | @article{horowitz1992list, |
@@ -272,7 +306,8 @@ | ||
| 272 | 306 | volume={7}, |
| 273 | 307 | number={2}, |
| 274 | 308 | pages={115--129}, |
| 275 | − year={1992} | |
| 309 | + year={1992}, | |
| 310 | + doi={10.1002/jae.3950070202} | |
| 276 | 311 | } |
| 277 | 312 | |
| 278 | 313 | @article{knight2002listing, |
@@ -282,7 +317,8 @@ | ||
| 282 | 317 | volume={30}, |
| 283 | 318 | number={2}, |
| 284 | 319 | pages={213--237}, |
| 285 | − year={2002} | |
| 320 | + year={2002}, | |
| 321 | + doi={10.1111/1540-6229.00038} | |
| 286 | 322 | } |
| 287 | 323 | |
| 288 | 324 | @incollection{han2015microstructure, |
@@ -292,7 +328,8 @@ | ||
| 292 | 328 | volume={5}, |
| 293 | 329 | pages={813--886}, |
| 294 | 330 | publisher={Elsevier}, |
| 295 | − year={2015} | |
| 331 | + year={2015}, | |
| 332 | + doi={10.1016/B978-0-444-59531-7.00013-2} | |
| 296 | 333 | } |
| 297 | 334 | |
| 298 | 335 | @article{hill2013hedonic, |
@@ -302,7 +339,8 @@ | ||
| 302 | 339 | volume={27}, |
| 303 | 340 | number={5}, |
| 304 | 341 | pages={879--914}, |
| 305 | − year={2013} | |
| 342 | + year={2013}, | |
| 343 | + doi={10.1111/j.1467-6419.2012.00731.x} | |
| 306 | 344 | } |
| 307 | 345 | |
| 308 | 346 | @article{cameron2015cluster, |
@@ -312,5 +350,213 @@ | ||
| 312 | 350 | volume={50}, |
| 313 | 351 | number={2}, |
| 314 | 352 | pages={317--372}, |
| 315 | − year={2015} | |
| 353 | + year={2015}, | |
| 354 | + doi={10.3368/jhr.50.2.317} | |
| 355 | +} | |
| 356 | + | |
| 357 | + | |
| 358 | +% --------------------------------------------------------------------------- | |
| 359 | +% References added in the 2026-10-17 revision (all verified via Crossref / arXiv) | |
| 360 | +% --------------------------------------------------------------------------- | |
| 361 | + | |
| 362 | +@article{kennedy1981estimation, | |
| 363 | + title={Estimation with correctly interpreted dummy variables in semilogarithmic equations}, | |
| 364 | + author={Kennedy, Peter E.}, | |
| 365 | + journal={American Economic Review}, | |
| 366 | + volume={71}, | |
| 367 | + number={4}, | |
| 368 | + pages={801}, | |
| 369 | + year={1981} | |
| 370 | +} | |
| 371 | + | |
| 372 | +@article{naik2017computer, | |
| 373 | + title={Computer vision uncovers predictors of physical urban change}, | |
| 374 | + author={Naik, Nikhil and Kominers, Scott Duke and Raskar, Ramesh and Glaeser, Edward L. and Hidalgo, C{\'e}sar A.}, | |
| 375 | + journal={Proceedings of the National Academy of Sciences}, | |
| 376 | + volume={114}, | |
| 377 | + number={29}, | |
| 378 | + pages={7571--7576}, | |
| 379 | + year={2017}, | |
| 380 | + doi={10.1073/pnas.1619003114} | |
| 381 | +} | |
| 382 | + | |
| 383 | +@article{law2019take, | |
| 384 | + title={Take a look around: Using street view and satellite images to estimate house prices}, | |
| 385 | + author={Law, Stephen and Paige, Brooks and Russell, Chris}, | |
| 386 | + journal={ACM Transactions on Intelligent Systems and Technology}, | |
| 387 | + volume={10}, | |
| 388 | + number={5}, | |
| 389 | + pages={1--19}, | |
| 390 | + year={2019}, | |
| 391 | + doi={10.1145/3342240} | |
| 392 | +} | |
| 393 | + | |
| 394 | +@article{zhang2018greenery, | |
| 395 | + title={Impacts of street-visible greenery on housing prices: Evidence from a hedonic price model and a massive street view image dataset in {Beijing}}, | |
| 396 | + author={Zhang, Yonglin and Dong, Rencai}, | |
| 397 | + journal={ISPRS International Journal of Geo-Information}, | |
| 398 | + volume={7}, | |
| 399 | + number={3}, | |
| 400 | + pages={104}, | |
| 401 | + year={2018}, | |
| 402 | + doi={10.3390/ijgi7030104} | |
| 403 | +} | |
| 404 | + | |
| 405 | +@article{kang2021understanding, | |
| 406 | + title={Understanding house price appreciation using multi-source big geo-data and machine learning}, | |
| 407 | + author={Kang, Yuhao and Zhang, Fan and Peng, Wenzhe and Gao, Song and Rao, Jinmeng and Duarte, Fabio and Ratti, Carlo}, | |
| 408 | + journal={Land Use Policy}, | |
| 409 | + volume={111}, | |
| 410 | + pages={104919}, | |
| 411 | + year={2021}, | |
| 412 | + doi={10.1016/j.landusepol.2020.104919} | |
| 413 | +} | |
| 414 | + | |
| 415 | +@inproceedings{bessinger2016quantifying, | |
| 416 | + title={Quantifying curb appeal}, | |
| 417 | + author={Bessinger, Zachary and Jacobs, Nathan}, | |
| 418 | + booktitle={2016 IEEE International Conference on Image Processing (ICIP)}, | |
| 419 | + pages={4388--4392}, | |
| 420 | + year={2016}, | |
| 421 | + doi={10.1109/ICIP.2016.7533189} | |
| 422 | +} | |
| 423 | + | |
| 424 | +@article{nowak2020quality, | |
| 425 | + title={Quality-adjusted house price indexes}, | |
| 426 | + author={Nowak, Adam D. and Smith, Patrick S.}, | |
| 427 | + journal={American Economic Review: Insights}, | |
| 428 | + volume={2}, | |
| 429 | + number={3}, | |
| 430 | + pages={339--356}, | |
| 431 | + year={2020}, | |
| 432 | + doi={10.1257/aeri.20190337} | |
| 433 | +} | |
| 434 | + | |
| 435 | +@article{nowak2021dictionaries, | |
| 436 | + title={Real estate dictionaries across space and time}, | |
| 437 | + author={Nowak, Adam D. and Price, Bradley S. and Smith, Patrick S.}, | |
| 438 | + journal={Journal of Real Estate Finance and Economics}, | |
| 439 | + volume={62}, | |
| 440 | + number={1}, | |
| 441 | + pages={139--163}, | |
| 442 | + year={2021}, | |
| 443 | + doi={10.1007/s11146-019-09740-w} | |
| 444 | +} | |
| 445 | + | |
| 446 | +@article{zhang2024describe, | |
| 447 | + title={Describe the house and {I} will tell you the price: House price prediction with textual description data}, | |
| 448 | + author={Zhang, Hanxiang and Li, Yansong and Branco, Paula}, | |
| 449 | + journal={Natural Language Engineering}, | |
| 450 | + volume={30}, | |
| 451 | + number={4}, | |
| 452 | + pages={661--695}, | |
| 453 | + year={2024}, | |
| 454 | + doi={10.1017/S1351324923000360} | |
| 455 | +} | |
| 456 | + | |
| 457 | +@article{dell2025deep, | |
| 458 | + title={Deep learning for economists}, | |
| 459 | + author={Dell, Melissa}, | |
| 460 | + journal={Journal of Economic Literature}, | |
| 461 | + volume={63}, | |
| 462 | + number={1}, | |
| 463 | + pages={5--58}, | |
| 464 | + year={2025}, | |
| 465 | + doi={10.1257/jel.20241733} | |
| 466 | +} | |
| 467 | + | |
| 468 | +@article{korinek2023generative, | |
| 469 | + title={Generative {AI} for economic research: Use cases and implications for economists}, | |
| 470 | + author={Korinek, Anton}, | |
| 471 | + journal={Journal of Economic Literature}, | |
| 472 | + volume={61}, | |
| 473 | + number={4}, | |
| 474 | + pages={1281--1317}, | |
| 475 | + year={2023}, | |
| 476 | + doi={10.1257/jel.20231736} | |
| 477 | +} | |
| 478 | + | |
| 479 | +@article{gilardi2023chatgpt, | |
| 480 | + title={{ChatGPT} outperforms crowd workers for text-annotation tasks}, | |
| 481 | + author={Gilardi, Fabrizio and Alizadeh, Meysam and Kubli, Ma{\"e}l}, | |
| 482 | + journal={Proceedings of the National Academy of Sciences}, | |
| 483 | + volume={120}, | |
| 484 | + number={30}, | |
| 485 | + pages={e2305016120}, | |
| 486 | + year={2023}, | |
| 487 | + doi={10.1073/pnas.2305016120} | |
| 488 | +} | |
| 489 | + | |
| 490 | +@article{han2016asking, | |
| 491 | + title={What is the role of the asking price for a house?}, | |
| 492 | + author={Han, Lu and Strange, William C.}, | |
| 493 | + journal={Journal of Urban Economics}, | |
| 494 | + volume={93}, | |
| 495 | + pages={115--130}, | |
| 496 | + year={2016}, | |
| 497 | + doi={10.1016/j.jue.2016.03.008} | |
| 498 | +} | |
| 499 | + | |
| 500 | +@article{pace2020examining, | |
| 501 | + title={Examining the information content of residuals from hedonic and spatial models using trees and forests}, | |
| 502 | + author={Pace, R. Kelley and Hayunga, Darren}, | |
| 503 | + journal={Journal of Real Estate Finance and Economics}, | |
| 504 | + volume={60}, | |
| 505 | + number={1--2}, | |
| 506 | + pages={170--180}, | |
| 507 | + year={2020}, | |
| 508 | + doi={10.1007/s11146-019-09724-w} | |
| 509 | +} | |
| 510 | + | |
| 511 | +@article{bourassa2010predicting, | |
| 512 | + title={Predicting house prices with spatial dependence: A comparison of alternative methods}, | |
| 513 | + author={Bourassa, Steven C. and Cantoni, Eva and Hoesli, Martin}, | |
| 514 | + journal={Journal of Real Estate Research}, | |
| 515 | + volume={32}, | |
| 516 | + number={2}, | |
| 517 | + pages={139--160}, | |
| 518 | + year={2010}, | |
| 519 | + doi={10.1080/10835547.2010.12091276} | |
| 520 | +} | |
| 521 | + | |
| 522 | +@article{roberts2017cross, | |
| 523 | + title={Cross-validation strategies for data with temporal, spatial, hierarchical, or phylogenetic structure}, | |
| 524 | + author={Roberts, David R. and Bahn, Volker and Ciuti, Simone and Boyce, Mark S. and Elith, Jane and Guillera-Arroita, Gurutzeta and Hauenstein, Severin and Lahoz-Monfort, Jos{\'e} J. and Schr{\"o}der, Boris and Thuiller, Wilfried and Warton, David I. and Wintle, Brendan A. and Hartig, Florian and Dormann, Carsten F.}, | |
| 525 | + journal={Ecography}, | |
| 526 | + volume={40}, | |
| 527 | + number={8}, | |
| 528 | + pages={913--929}, | |
| 529 | + year={2017}, | |
| 530 | + doi={10.1111/ecog.02881} | |
| 531 | +} | |
| 532 | + | |
| 533 | +@article{abadie2023when, | |
| 534 | + title={When should you adjust standard errors for clustering?}, | |
| 535 | + author={Abadie, Alberto and Athey, Susan and Imbens, Guido W. and Wooldridge, Jeffrey M.}, | |
| 536 | + journal={Quarterly Journal of Economics}, | |
| 537 | + volume={138}, | |
| 538 | + number={1}, | |
| 539 | + pages={1--35}, | |
| 540 | + year={2023}, | |
| 541 | + doi={10.1093/qje/qjac038} | |
| 542 | +} | |
| 543 | + | |
| 544 | +@article{mackinnon2017wild, | |
| 545 | + title={Wild bootstrap inference for wildly different cluster sizes}, | |
| 546 | + author={MacKinnon, James G. and Webb, Matthew D.}, | |
| 547 | + journal={Journal of Applied Econometrics}, | |
| 548 | + volume={32}, | |
| 549 | + number={2}, | |
| 550 | + pages={233--254}, | |
| 551 | + year={2017}, | |
| 552 | + doi={10.1002/jae.2508} | |
| 553 | +} | |
| 554 | + | |
| 555 | +@techreport{boucher2026decoding, | |
| 556 | + title={Decoding real estate descriptions: Semantic embeddings and hedonic pricing of residential properties in {Quebec}}, | |
| 557 | + author={Boucher, Simon-Pierre}, | |
| 558 | + institution={Universit\'e du Qu\'ebec en Outaouais, D\'epartement des sciences administratives}, | |
| 559 | + type={UQO Working Paper}, | |
| 560 | + number={2}, | |
| 561 | + year={2026} | |
| 316 | 562 | } |
modified
paper/sections/benchmark.tex
+87 −62
@@ -8,7 +8,7 @@ coefficients are implicit prices. It is not, however, the most accurate predicto | ||
| 8 | 8 | price. To map the accuracy frontier---and to gauge how much curvature and interaction |
| 9 | 9 | the linear model leaves on the table---we benchmark a ladder of estimators of |
| 10 | 10 | increasing flexibility on the \emph{identical} feature set, under a common |
| 11 | −5-fold cross-validation protocol. All rows of Table~\ref{tab:models} share the same | |
| 11 | +five-fold cross-validation protocol. All rows of Table~\ref{tab:models} share the same | |
| 12 | 12 | folds and random seed, so differences reflect the estimator, not the split. |
| 13 | 13 | |
| 14 | 14 | \subsection{The Estimator Ladder} |
@@ -21,9 +21,9 @@ the interpretable baseline and, mechanically, the least flexible: it imposes con | ||
| 21 | 21 | marginal effects and additive separability. |
| 22 | 22 | |
| 23 | 23 | \paragraph{(2) Random forest.} A bagged ensemble of regression trees |
| 24 | −\citep{mullainathan2017machine}. Trees capture non-linearities and low-order | |
| 25 | −interactions automatically and handle missing values natively, but averaging | |
| 26 | −deep decorrelated trees tends to over-smooth sharp price thresholds. | |
| 24 | +\citep{breiman2001random,mullainathan2017machine}. Trees capture non-linearities and | |
| 25 | +low-order interactions automatically and handle missing values natively, but | |
| 26 | +averaging deep decorrelated trees tends to over-smooth sharp price thresholds. | |
| 27 | 27 | |
| 28 | 28 | \paragraph{(3) Gradient boosting.} A histogram-based gradient-boosted tree ensemble |
| 29 | 29 | (600 boosting iterations, learning rate 0.05, up to 63 leaves, $L_2$ regularization). |
@@ -33,14 +33,17 @@ values directly. It is the strongest single model in our comparison. | ||
| 33 | 33 | |
| 34 | 34 | \paragraph{(4) Neural networks.} A plain multilayer perceptron and a robust |
| 35 | 35 | residual network with entity embeddings, described in |
| 36 | −Section~\ref{subsec:nn}. Neural networks excel when high-cardinality categoricals | |
| 37 | −(here, 195 municipalities) can be represented as dense learned vectors rather than | |
| 38 | −sparse indicators. | |
| 36 | +Section~\ref{subsec:nn}. Neural networks are attractive when high-cardinality | |
| 37 | +categoricals (here, 195 municipalities) can be represented as dense learned vectors | |
| 38 | +rather than sparse indicators. | |
| 39 | 39 | |
| 40 | −\paragraph{(5) Blend.} A simple 50/50 average of the robust neural network and the | |
| 41 | −gradient-boosting predictions. Because the two models make partly decorrelated | |
| 40 | +\paragraph{(5) Blend.} An equally weighted average of the robust neural network and | |
| 41 | +the gradient-boosting predictions. Because the two models make partly decorrelated | |
| 42 | 42 | errors---the network smooths through embeddings while the boosted trees cut sharp |
| 43 | −thresholds---their average cancels idiosyncratic noise, a standard stacking result. | |
| 43 | +thresholds---their average cancels idiosyncratic noise, a standard model-averaging | |
| 44 | +result. The weight of one half was fixed \emph{a priori}; Section~\ref{subsec:bench_results} | |
| 45 | +reports how the result varies with the weight and under a nested choice of the | |
| 46 | +weight. | |
| 44 | 47 | |
| 45 | 48 | \subsection{Formal Definitions} |
| 46 | 49 | \label{subsec:formal} |
@@ -61,7 +64,9 @@ trees, each grown on a bootstrap resample with a random feature subset at every | ||
| 61 | 64 | \label{eq:rf} |
| 62 | 65 | \end{equation} |
| 63 | 66 | % |
| 64 | −where $\Theta_b$ denotes the randomness (resample and split subsets) of tree~$b$. | |
| 67 | +where $\Theta_b$ denotes the randomness (resample and split subsets) of tree~$b$; | |
| 68 | +we use $B=400$ trees, half of the features at each split, and a minimum leaf size | |
| 69 | +of three. | |
| 65 | 70 | |
| 66 | 71 | \paragraph{Gradient boosting \citep{friedman2001greedy}.} A forward stagewise additive |
| 67 | 72 | expansion built by fitting each new tree to the negative gradient of the loss: |
@@ -78,8 +83,8 @@ expansion built by fitting each new tree to the negative gradient of the loss: | ||
| 78 | 83 | \label{eq:gbm} |
| 79 | 84 | \end{equation} |
| 80 | 85 | % |
| 81 | −with learning rate $\nu$ and $L_2$-regularized histogram trees $f_m$; missing values | |
| 82 | −are routed to a learned default direction at each split. | |
| 86 | +with learning rate $\nu$, squared-error loss $L$, and $L_2$-regularized histogram | |
| 87 | +trees $f_m$; missing values are routed to a learned default direction at each split. | |
| 83 | 88 | |
| 84 | 89 | \paragraph{Neural network (robust).} High-cardinality categoricals are mapped to |
| 85 | 90 | learned embeddings \citep{guo2016entity}, concatenated with the batch-normalized |
@@ -119,9 +124,11 @@ Parameters minimize the Huber (smooth-$L_1$) loss, robust to price outliers, | ||
| 119 | 124 | \label{eq:huber} |
| 120 | 125 | \end{equation} |
| 121 | 126 | % |
| 122 | −optimized with AdamW (decoupled weight decay) \citep{loshchilov2019decoupled} under a | |
| 123 | −cosine-annealed learning rate $\eta_t=\tfrac12\eta_0\big(1+\cos(\pi t/T)\big)$, | |
| 124 | −gradient-norm clipping, and early stopping. Three seeds are averaged per fold. | |
| 127 | +on the standardized target, optimized with AdamW (decoupled weight decay) | |
| 128 | +\citep{loshchilov2019decoupled} under a cosine-annealed learning rate | |
| 129 | +$\eta_t=\tfrac12\eta_0\big(1+\cos(\pi t/T)\big)$, gradient-norm clipping, and early | |
| 130 | +stopping on a 10\% validation split of each training fold. Three seeds are averaged | |
| 131 | +per fold. | |
| 125 | 132 | |
| 126 | 133 | \paragraph{Blend.} A convex combination of the two strongest models in log space, |
| 127 | 134 | % |
@@ -141,9 +148,14 @@ accuracy, | ||
| 141 | 148 | R^2_{\text{OOS}} = 1-\frac{\sum_i\big(y_i-\hat y_{-k(i)}\big)^2} |
| 142 | 149 | {\sum_i\big(y_i-\bar y\big)^2}, |
| 143 | 150 | \qquad |
| 144 | − \text{MdAPE}=\operatorname*{median}_i\Big|e^{\,\hat y_{-k(i)}-y_i}-1\Big|. | |
| 151 | + \text{MdAPE}=\operatorname*{median}_i\Big|e^{\,\hat y_{-k(i)}-y_i}-1\Big|, | |
| 145 | 152 | \label{eq:cvmetrics} |
| 146 | 153 | \end{equation} |
| 154 | +% | |
| 155 | +together with the share of listings predicted within $\pm15\%$ and $\pm25\%$ of the | |
| 156 | +asking price. The MdAPE is computed on the ratio of predicted to actual price and is | |
| 157 | +therefore unaffected by the retransformation constant of | |
| 158 | +Equation~\eqref{eq:smearing}. | |
| 147 | 159 | |
| 148 | 160 | \subsection{Results} |
| 149 | 161 | \label{subsec:bench_results} |
@@ -151,37 +163,46 @@ accuracy, | ||
| 151 | 163 | \input{tables/models} |
| 152 | 164 | |
| 153 | 165 | Table~\ref{tab:models} reports the ladder in two panels. In Panel~A (structural, |
| 154 | −amenity, and text features) out-of-sample $R^2$ rises monotonically with flexibility: | |
| 155 | −from 0.628 for OLS, to 0.677 for the random forest, 0.711 for the plain network, and a | |
| 156 | −near-tie at the top between the robust network (0.741) and gradient boosting (0.743); | |
| 157 | −their blend attains $R^2_{\text{OOS}}=0.760$. Panel~B adds the twelve façade vision | |
| 158 | −attributes. Vision lifts \emph{every} estimator---OLS gains 5.8 points | |
| 159 | −(0.628 $\to$ 0.686), the random forest 2.7 (0.677 $\to$ 0.704), and gradient boosting | |
| 160 | −2.7 (0.743 $\to$ 0.770), the single largest increment from any one feature layer at | |
| 161 | −the frontier---and the \textbf{text\,+\,vision blend attains | |
| 162 | −$R^2_{\text{OOS}}=0.779$ with a median absolute error of 14.0\%}, the best model in | |
| 163 | −the study. | |
| 166 | +amenity, room, listing, and text features) out-of-sample $R^2$ rises monotonically | |
| 167 | +with flexibility: from 0.628 for OLS, to 0.677 for the random forest, 0.711 for the | |
| 168 | +plain network, and a near-tie at the top between the robust network (0.741) and | |
| 169 | +gradient boosting (0.743); their blend attains $R^2_{\text{OOS}}=0.760$. Panel~B adds | |
| 170 | +the façade vision layer. Vision lifts every estimator---OLS gains 5.8 points | |
| 171 | +(0.628 $\to$ 0.686), the random forest 2.7 (0.677 $\to$ 0.704), the robust network | |
| 172 | +0.6 (0.741 $\to$ 0.747), and gradient boosting 2.7 (0.743 $\to$ 0.770)---and the | |
| 173 | +text\,$+$\,vision blend attains $R^2_{\text{OOS}}=0.779$ with a median absolute | |
| 174 | +percentage error of 14.0\%, the best model in the study. | |
| 164 | 175 | |
| 165 | 176 | Three lessons follow. First, on the full feature set roughly nine points of |
| 166 | 177 | out-of-sample $R^2$ separate the interpretable linear model (0.686) from the |
| 167 | 178 | predictive frontier (0.779)---the price of interpretability, and a measure of the |
| 168 | 179 | curvature and interactions the hedonic form omits. Notably, the vision layer buys the |
| 169 | −linear model more accuracy (+5.8 points) than switching from OLS to a random forest | |
| 170 | −does (+4.9), so better measurement rivals better estimation. Second, on this tabular | |
| 171 | −problem gradient boosting and a carefully regularized neural network are | |
| 172 | −statistically comparable, consistent with the broader evidence that tree ensembles | |
| 173 | −remain strong baselines on tabular data \citep{grinsztajn2022why}; the gains come | |
| 174 | −from \emph{combining} them. Third, the façade-vision layer is not redundant with the | |
| 175 | −text and structural fields: it moves the frontier more than any other block we add, | |
| 176 | −confirming that image-derived quality is genuinely orthogonal information. | |
| 180 | +linear model more accuracy ($+5.8$ points) than switching from OLS to a random forest | |
| 181 | +does ($+4.9$ points in Panel~A), so better measurement rivals better estimation. | |
| 182 | +Second, on this tabular problem gradient boosting and a carefully regularized neural | |
| 183 | +network are statistically comparable, consistent with the broader evidence that tree | |
| 184 | +ensembles remain strong baselines on tabular data \citep{grinsztajn2022why}; the | |
| 185 | +gains come from \emph{combining} them. Third, the façade-vision layer is not redundant | |
| 186 | +with the text and structural fields: it is the more informative of the two AI layers | |
| 187 | +for every estimator. | |
| 188 | + | |
| 189 | +The equal-weight blend is not the best achievable combination, but it is close. | |
| 190 | +Varying the weight $w$ on gradient boosting in Equation~\eqref{eq:blend} over | |
| 191 | +$\{0.3,0.4,0.5,0.6,0.7\}$ gives out-of-sample $R^2$ of 0.771, 0.776, 0.779, 0.780, | |
| 192 | +and 0.780 for the text\,$+$\,vision models, so $w=0.5$ is within 0.002 of the best | |
| 193 | +weight on the grid; choosing $w$ in a nested fashion---on the four training folds, | |
| 194 | +then applied to the fifth---returns $R^2_{\text{OOS}}=0.775$, slightly below the | |
| 195 | +fixed equal weight, because the fold-specific optimal weights are noisy. For the | |
| 196 | +text-only models the equal weight is exactly the best on the grid (0.760). We | |
| 197 | +therefore keep the fixed equal weight and do not tune it on the test predictions. | |
| 177 | 198 | |
| 178 | 199 | \begin{figure}[htbp] |
| 179 | 200 | \centering |
| 180 | 201 | \includegraphics[width=.72\textwidth]{figures/fig_ablation.pdf} |
| 181 | − \caption{Out-of-sample $R^2$ as feature layers are added (nested, left to right). | |
| 182 | − Each layer improves both the linear and boosted models; the façade-vision layer | |
| 183 | − delivers the largest single jump---about $+5.8$ points for OLS and $+2.7$ for | |
| 184 | − gradient boosting.} | |
| 202 | + \caption{Out-of-sample $R^2$ as feature layers are added (nested, left to right), | |
| 203 | + random five-fold cross-validation. Each layer improves both the linear and boosted | |
| 204 | + models; the façade-vision layer adds about $+5.8$ points for OLS and $+2.7$ for | |
| 205 | + gradient boosting, the text layer $+0.9$ and $+1.4$.} | |
| 185 | 206 | \label{fig:ablation} |
| 186 | 207 | \end{figure} |
| 187 | 208 | |
@@ -189,28 +210,31 @@ confirming that image-derived quality is genuinely orthogonal information. | ||
| 189 | 210 | \label{subsec:ablation} |
| 190 | 211 | |
| 191 | 212 | Table~\ref{tab:ablation} and Figure~\ref{fig:ablation} decompose the accuracy gains |
| 192 | −layer by layer. Reading down the table, room detail and listing signals add the first | |
| 193 | −large increment, the LLM text layer a smaller one, and the vision layer the single | |
| 194 | −largest jump for every estimator---raising OLS from 0.628 to 0.686 and gradient | |
| 195 | −boosting from 0.743 to 0.770 out of sample. The pattern is monotone: no layer degrades | |
| 196 | −fit, and the two AI layers together account for a substantial share of the distance | |
| 197 | −between the structural baseline and the frontier. | |
| 213 | +layer by layer. Reading down the table, the room-detail and listing-signal block adds | |
| 214 | +the largest increment of all (9.8 points for OLS, 3.7 for gradient boosting), which | |
| 215 | +reflects both the information in the Realtor.ca room block and the fact that this | |
| 216 | +block carries the platform's identity; the LLM text layer adds 0.9 and 1.4 points; | |
| 217 | +and the vision layer adds 5.8 and 2.7 points, the largest increment of the two AI | |
| 218 | +layers and the second largest overall. The pattern is monotone: no layer degrades | |
| 219 | +fit. Under spatially grouped folds (Table~\ref{tab:rob_spatial}, | |
| 220 | +Section~\ref{subsec:robust_spatial}) all levels fall by three to five points, but the | |
| 221 | +increments from the text and vision layers are essentially unchanged. | |
| 198 | 222 | |
| 199 | 223 | \input{tables/ablation} |
| 200 | 224 | |
| 201 | 225 | Figure~\ref{fig:importance} aggregates the gradient-boosting permutation importances |
| 202 | 226 | into feature blocks. Structural attributes and location fixed effects dominate, as |
| 203 | −expected, but the \textbf{vision block alone accounts for 13\% of total importance}--- | |
| 204 | −more than the rule-based amenities and the LLM text block combined---reinforcing that | |
| 205 | −the façade photograph is a first-order, not marginal, source of price information. | |
| 206 | −Figure~\ref{fig:calibration} shows the blend is well calibrated across the price range, | |
| 207 | −with an approximately symmetric, tight error distribution centered near zero. | |
| 227 | +expected, but the vision block accounts for 13\% of total importance---more than the | |
| 228 | +rule-based amenities and the LLM text block combined---so the façade photograph is a | |
| 229 | +first-order, not marginal, source of price information in the boosted model. | |
| 230 | +Figure~\ref{fig:calibration} shows that the blend is well calibrated across the price | |
| 231 | +range, with an approximately symmetric error distribution centred near zero. | |
| 208 | 232 | |
| 209 | 233 | \begin{figure}[htbp] |
| 210 | 234 | \centering |
| 211 | 235 | \includegraphics[width=.72\textwidth]{figures/fig_importance.pdf} |
| 212 | 236 | \caption{Share of gradient-boosting permutation importance by feature block |
| 213 | − (text\,+\,vision model). The vision block accounts for 13\% of total importance, | |
| 237 | + (text\,$+$\,vision model). The vision block accounts for 13\% of total importance, | |
| 214 | 238 | exceeding the rule-based amenity and LLM-text blocks.} |
| 215 | 239 | \label{fig:importance} |
| 216 | 240 | \end{figure} |
@@ -218,7 +242,7 @@ with an approximately symmetric, tight error distribution centered near zero. | ||
| 218 | 242 | \begin{figure}[htbp] |
| 219 | 243 | \centering |
| 220 | 244 | \includegraphics[width=\textwidth]{figures/fig_calibration.pdf} |
| 221 | − \caption{Out-of-sample calibration of the text\,+\,vision blend. Left: predicted | |
| 245 | + \caption{Out-of-sample calibration of the text\,$+$\,vision blend. Left: predicted | |
| 222 | 246 | versus actual price (log--log; dashed line is the 45$^\circ$ identity). Right: |
| 223 | 247 | distribution of percentage prediction errors, with median absolute error of 14.0\%.} |
| 224 | 248 | \label{fig:calibration} |
@@ -230,22 +254,23 @@ with an approximately symmetric, tight error distribution centered near zero. | ||
| 230 | 254 | Figure~\ref{fig:nn} details the robust network. High-cardinality categoricals enter |
| 231 | 255 | as learned \textbf{entity embeddings}: each municipality, property type, and source is |
| 232 | 256 | mapped to a dense vector (dimension $\approx 1.6\,C^{0.56}$ in cardinality $C$, so |
| 233 | −about 29 dimensions for the 195 cities). The embeddings are concatenated with the | |
| 234 | −batch-normalized numeric block and projected to a 256-dimensional trunk, which passes | |
| 235 | −through three \textbf{residual blocks} | |
| 236 | −(BatchNorm $\to$ GELU $\to$ Linear$_{512}$ $\to$ Dropout $\to$ Linear$_{256}$, with a | |
| 237 | −skip connection), followed by a normalization head that outputs $\ln(\text{Price})$. | |
| 257 | +about 30 dimensions for the 195 municipalities). The embeddings are concatenated with | |
| 258 | +the batch-normalized numeric block and projected to a 256-dimensional trunk, which | |
| 259 | +passes through three \textbf{residual blocks} (BatchNorm $\to$ Linear$_{512}$ $\to$ | |
| 260 | +GELU $\to$ Dropout $\to$ Linear$_{256}$ $\to$ Dropout, with a skip connection), | |
| 261 | +followed by a normalization head that outputs $\ln(\text{Price})$. | |
| 238 | 262 | |
| 239 | 263 | Robustness comes from the training recipe rather than raw capacity: |
| 240 | 264 | a \textbf{Huber (smooth-$L_1$) loss} that damps the influence of price outliers; |
| 241 | −\textbf{AdamW} with decoupled weight decay and \textbf{cosine-annealed} learning rate; | |
| 265 | +\textbf{AdamW} with decoupled weight decay and a \textbf{cosine-annealed} learning rate; | |
| 242 | 266 | \textbf{gradient-norm clipping} at 5; \textbf{dropout} and batch normalization |
| 243 | −throughout; \textbf{learned missingness indicators} appended to the numeric block so | |
| 267 | +throughout; \textbf{missingness indicators} appended to the numeric block so | |
| 244 | 268 | the network can exploit the non-random pattern of missing fields; and |
| 245 | 269 | \textbf{early stopping} on a held-out 10\% of each training fold. Finally, three |
| 246 | 270 | networks with different random seeds are trained per fold and \textbf{averaged}, which |
| 247 | −reduces prediction variance. The result (0.741) is competitive with gradient boosting | |
| 248 | −and, once blended with it, produces the best model in the study. | |
| 271 | +reduces prediction variance. The result (0.741 with text, 0.747 with text and vision) | |
| 272 | +is competitive with gradient boosting and, once blended with it, produces the best | |
| 273 | +model in the study. | |
| 249 | 274 | |
| 250 | 275 | \begin{figure}[htbp] |
| 251 | 276 | \centering |
@@ -255,6 +280,6 @@ and, once blended with it, produces the best model in the study. | ||
| 255 | 280 | augmented with missingness indicators. The concatenated representation is projected |
| 256 | 281 | to a 256-dimensional trunk, refined by three residual blocks, and mapped to |
| 257 | 282 | $\ln(\text{Price})$. Three seeds are ensembled per fold; the final model blends this |
| 258 | − network 50/50 with gradient boosting.} | |
| 283 | + network equally with gradient boosting.} | |
| 259 | 284 | \label{fig:nn} |
| 260 | 285 | \end{figure} |
modified
paper/sections/conclusion.tex
+36 −29
@@ -6,36 +6,43 @@ | ||
| 6 | 6 | We have estimated a hedonic price model for Quebec houses that augments the standard |
| 7 | 7 | set of structural, locational, and amenity attributes with two machine-generated |
| 8 | 8 | feature layers: structured specifications extracted from free-text descriptions by a |
| 9 | −large language model, and objective visual attributes extracted from façade | |
| 10 | −photographs by a vision--language model. Schema-constrained decoding renders these | |
| 11 | −outputs as ordinary, reproducible econometric variables, obtained at a marginal cost | |
| 12 | −of a fraction of a cent per listing. The central message is methodological: | |
| 13 | −general-purpose AI models, disciplined by strict output schemas, function as a | |
| 14 | −low-cost feature-engineering technology that measurably expands the characteristics | |
| 15 | −set available to hedonic analysis. | |
| 9 | +large language model, and visual attributes extracted from façade photographs by a | |
| 10 | +vision--language model. Schema-constrained decoding renders these outputs as | |
| 11 | +ordinary, auditable econometric variables, obtained at a marginal cost of a fraction | |
| 12 | +of a cent per listing. The central message is methodological: general-purpose AI | |
| 13 | +models, disciplined by strict output schemas, function as a low-cost | |
| 14 | +feature-engineering technology that measurably expands the characteristics set | |
| 15 | +available to hedonic analysis---and the discipline must extend to the input, since | |
| 16 | +the text handed to the model may contain the very price one is trying to explain. | |
| 16 | 17 | |
| 17 | −The gains are economically meaningful. The two AI layers add nearly four points of | |
| 18 | −in-sample $R^2$ to an already rich log--linear specification (0.717 to 0.755 with | |
| 19 | −living area observed), and they raise the out-of-sample accuracy of every estimator | |
| 20 | −in our ladder, from OLS to gradient boosting and an embedding-based residual neural | |
| 21 | −network; the best blend attains an out-of-sample $R^2$ of 0.779 with a median | |
| 22 | −absolute prediction error of 14.0\%. The façade-vision layer alone contributes the | |
| 23 | −largest increment of any feature block (2.7 points for gradient boosting, 5.8 for | |
| 24 | −OLS), confirming that image-derived quality is genuinely orthogonal to text and | |
| 25 | −structured fields. Crucially for hedonic practice, the extracted attributes carry | |
| 26 | −interpretable implicit prices---curb appeal, renovation level, luxury cues, and | |
| 27 | −exterior materials all price sensibly and survive municipality-clustered | |
| 28 | −inference---so the technology augments the classical regression rather than | |
| 29 | −replacing it with a black box. | |
| 18 | +The gains are economically meaningful but unequal across the two layers. Together | |
| 19 | +they add 3.8 points of in-sample $R^2$ to an already rich log-linear specification | |
| 20 | +(0.717 to 0.755 with living area observed), of which 3.0 come from the façade | |
| 21 | +photograph and 0.8 from the text; they raise the out-of-sample accuracy of every | |
| 22 | +estimator in our ladder, from OLS to gradient boosting and an embedding-based | |
| 23 | +residual neural network; and the best blend attains an out-of-sample $R^2$ of 0.779 | |
| 24 | +with a median absolute percentage error of 14.0\% under random folds, 0.734 for | |
| 25 | +gradient boosting when entire postal areas are held out. The vision layer adds more | |
| 26 | +to the linear model than switching from OLS to a random forest does. The extracted | |
| 27 | +attributes carry interpretable implicit prices---curb appeal, renovation level, | |
| 28 | +luxury cues, and exterior materials all price sensibly---that survive | |
| 29 | +municipality-clustered inference, a cluster bootstrap, finer postal-code fixed | |
| 30 | +effects, and a control for the language of the description. The text layer's | |
| 31 | +contribution, by contrast, is modest once keyword amenities are already in the model, | |
| 32 | +and part of its measured gain on the for-sale-by-owner platform reflects the asking | |
| 33 | +price embedded in those descriptions rather than information about the house. | |
| 30 | 34 | |
| 31 | 35 | Three extensions are natural. First, the same schema-constrained approach scales |
| 32 | 36 | from a single façade image to a small panel of interior photographs (kitchen, |
| 33 | −bathroom, living space), which our design already accommodates. Second, the | |
| 34 | −DuProprio coordinates permit continuous spatial features---distance to the urban | |
| 35 | −core, to water, or to amenities---that would refine the geography beyond discrete | |
| 36 | −city effects. Third, and most important for external validity, linking listings to | |
| 37 | −registry transaction prices would establish how much of the AI-measured quality | |
| 38 | −premium survives bargaining. For appraisal, automated valuation, and property-tax | |
| 39 | −assessment---applications that consume hedonic models at scale---the practical | |
| 40 | −implication is immediate: the unstructured majority of a listing's information | |
| 41 | −content is no longer out of reach. | |
| 37 | +bathroom, living space), which our design already accommodates; a repeat extraction | |
| 38 | +of a subsample at a fixed temperature, and a human-labelled validation set, would | |
| 39 | +also quantify the extraction error that we could only measure indirectly. Second, | |
| 40 | +the DuProprio coordinates and the postal codes of all listings permit continuous | |
| 41 | +spatial features---distance to the urban core, to water, or to amenities---that would | |
| 42 | +refine the geography beyond discrete area effects. Third, and most important for | |
| 43 | +external validity, linking listings to registry transaction prices would establish | |
| 44 | +how much of the AI-measured quality premium survives bargaining. For appraisal, | |
| 45 | +automated valuation, and property-tax assessment---applications that consume hedonic | |
| 46 | +models at scale---the practical implication is that the unstructured majority of a | |
| 47 | +listing's information content is no longer out of reach, provided that it is read | |
| 48 | +with the same care as any other regressor. | |
modified
paper/sections/data.tex
+64 −19
@@ -7,25 +7,26 @@ | ||
| 7 | 7 | \label{subsec:data_sources} |
| 8 | 8 | |
| 9 | 9 | We assemble a cross-section of residential listings from two complementary Quebec |
| 10 | −platforms, both retrieved on 3~July~2026 via web-scraping actors. The first, | |
| 10 | +platforms, both retrieved on 3~July~2026 with web-scraping actors. The first, | |
| 11 | 11 | \textbf{Realtor.ca}, is the national Multiple Listing Service (MLS) portal and |
| 12 | 12 | provides broker-listed inventory (27{,}302 raw records). The second, |
| 13 | −\textbf{DuProprio}, is the dominant for-sale-by-owner platform in Quebec (7{,}693 | |
| 14 | −raw records). Pooling the two sources broadens coverage across price segments and | |
| 15 | −sale channels---brokered and FSBO listings differ systematically in seller | |
| 16 | −composition and marketing \citep{hendel2009mls}---and a source indicator absorbs any | |
| 17 | −systematic level difference between them. The price we observe is the \emph{asking} | |
| 18 | −price; Section~\ref{subsec:limits} discusses the interpretation of hedonic | |
| 19 | −coefficients estimated on list rather than transaction prices | |
| 20 | −\citep{horowitz1992list,knight2002listing}. | |
| 13 | +\textbf{DuProprio}, is the dominant for-sale-by-owner (FSBO) platform in Quebec | |
| 14 | +(7{,}693 raw records). Pooling the two sources broadens coverage across price | |
| 15 | +segments and sale channels---brokered and FSBO listings differ systematically in | |
| 16 | +seller composition and marketing \citep{hendel2009mls}---and a source indicator | |
| 17 | +absorbs any systematic level difference between them. The price we observe is the | |
| 18 | +\emph{asking} price; Section~\ref{subsec:limits} discusses the interpretation of | |
| 19 | +hedonic coefficients estimated on list rather than transaction prices | |
| 20 | +\citep{horowitz1992list,knight2002listing,han2016asking}. | |
| 21 | 21 | |
| 22 | −Each record is a structured JSON object containing a price, an address, a | |
| 23 | −property-attribute block, a free-text description, a list of features, and an array | |
| 24 | −of image URLs. The two sources differ in their auxiliary fields: Realtor.ca records | |
| 25 | −include room-by-room dimensions but no geographic coordinates, whereas DuProprio | |
| 26 | −records include coordinates and captioned images but no room block. We construct a | |
| 27 | −unique key by concatenating the source and the listing identifier. Because the data | |
| 28 | −form a single-date cross-section, no time dimension is modeled. | |
| 22 | +Each record is a structured JSON object containing a price, an address with a | |
| 23 | +postal code, a property-attribute block, a free-text description, a list of | |
| 24 | +features, and an array of image URLs. The two sources differ in their auxiliary | |
| 25 | +fields: Realtor.ca records include room-by-room dimensions but no geographic | |
| 26 | +coordinates, whereas DuProprio records include coordinates and captioned images but | |
| 27 | +no room block. We construct a unique key by concatenating the source and the listing | |
| 28 | +identifier. Because the data form a single-date cross-section, no time dimension is | |
| 29 | +modelled and no forward-in-time holdout is possible. | |
| 29 | 30 | |
| 30 | 31 | \subsection{Sample Construction} |
| 31 | 32 | \label{subsec:sample} |
@@ -52,7 +53,47 @@ deleting the observation, preserving sample size. Finally, we trim the | ||
| 52 | 53 | price-per-square-foot distribution at its 0.5th and 99.5th percentiles |
| 53 | 54 | (approximately \$73--\$1{,}276/ft$^2$) among listings with a measured area, removing |
| 54 | 55 | residual price- or area-parsing errors. The cleaned sample contains |
| 55 | −\textbf{19{,}123 houses}, of which 80.3\% originate from Realtor.ca. | |
| 56 | +\textbf{19{,}123 houses}, of which 80.3\% originate from Realtor.ca | |
| 57 | +(Table~\ref{tab:app_flow} in the Appendix summarizes the flow). | |
| 58 | + | |
| 59 | +\subsection{Content and Language of the Descriptions} | |
| 60 | +\label{subsec:text_content} | |
| 61 | + | |
| 62 | +Because the language model reads the description verbatim, what the description | |
| 63 | +contains matters for the interpretation of the text layer. The two platforms differ | |
| 64 | +sharply. A Realtor.ca description is a free-text paragraph written by the listing | |
| 65 | +broker (mean length about 540 characters); only 2.5\% of these descriptions contain any | |
| 66 | +dollar amount, and fewer than 0.3\% mention the municipal assessment. A DuProprio | |
| 67 | +``description,'' as delivered by the crawler, concatenates the owner's comments with | |
| 68 | +the platform's structured property sheet rendered as text: room counts, living and | |
| 69 | +lot area, year of construction, exterior cladding, heating, inclusions, and---in | |
| 70 | +every one of the 3{,}767 DuProprio listings in the cleaned sample---the asking price | |
| 71 | +itself (``Asking Price \$499,999''), which equals the recorded list price in 3{,}761 | |
| 72 | +cases; 46.6\% of DuProprio descriptions also mention the municipal assessment. The | |
| 73 | +language model was therefore shown the dependent variable for 19.7\% of the sample. | |
| 74 | +The extraction schema has no price field, and the prompt instructs the model to | |
| 75 | +report only what the text states about the property, so leakage can operate only | |
| 76 | +indirectly (a model that sees a high price may, for instance, lean towards | |
| 77 | +``like-new'' when the condition is ambiguous). We treat this as a first-order | |
| 78 | +threat to the text layer and address it in Sections~\ref{subsec:robust_leakage} | |
| 79 | +and~\ref{subsec:limits}: all text-layer gains are reported separately for | |
| 80 | +Realtor.ca, where the text contains no price, and for DuProprio. The vision model | |
| 81 | +receives only the image URL and never sees any text or price. | |
| 82 | + | |
| 83 | +Quebec is a bilingual listing market. Classifying each description from counts of | |
| 84 | +French and English stop words (a ratio rule of 1.5, as in \citealp{boucher2026decoding}), | |
| 85 | +44.6\% of descriptions are French, 43.1\% English, and 12.3\% ``mixed''---mostly | |
| 86 | +DuProprio descriptions that juxtapose an automated English translation and the | |
| 87 | +French original. Within Realtor.ca, 57.0\% of descriptions are French and 41.9\% | |
| 88 | +English, and the two groups are priced very differently: the median asking price of | |
| 89 | +English-language Realtor.ca listings is \$749{,}000 against \$524{,}900 for French | |
| 90 | +ones, a raw gap of 0.37 log points that falls to 0.21 within municipalities. English | |
| 91 | +descriptions concentrate in the Montreal West Island and other affluent anglophone | |
| 92 | +municipalities, so language proxies for location and for the clientele targeted by | |
| 93 | +the broker. Because the LLM processes both languages with the same schema, language | |
| 94 | +could also affect the extraction itself. We therefore add language indicators to the | |
| 95 | +hedonic specification and re-estimate the gains from both AI layers within each | |
| 96 | +language group (Section~\ref{subsec:robust_language}). | |
| 56 | 97 | |
| 57 | 98 | \subsection{Summary Statistics} |
| 58 | 99 | \label{subsec:summary_stats} |
@@ -62,13 +103,17 @@ The median list price is \$599{,}900. The distribution of living area is right-s | ||
| 62 | 103 | motivating the logarithmic transformation adopted in Section~\ref{sec:methodology}. |
| 63 | 104 | Living area is reported for only a minority of Realtor.ca listings; where it is |
| 64 | 105 | missing we reconstruct it from room-level dimensions (Section~\ref{subsec:structural}), |
| 65 | −and where neither is available we rely on the area-free specification. | |
| 106 | +and where neither is available we rely on the area-free specification. The room | |
| 107 | +count is available only for Realtor.ca listings (the DuProprio room block is absent | |
| 108 | +and coded as zero rooms, with the source indicator absorbing the level). | |
| 66 | 109 | |
| 67 | 110 | \input{tables/summary_stats} |
| 68 | 111 | |
| 69 | 112 | Table~\ref{tab:ai_summary} previews the machine-generated attributes described in |
| 70 | 113 | Section~\ref{sec:methodology}: roughly a quarter of listings are described as recently |
| 71 | 114 | renovated, the mean visual condition and curb-appeal scores are 7.4 and 7.2 on a |
| 72 | −10-point scale, and 43\% of façades display a visual luxury cue. | |
| 115 | +10-point scale, and 43\% of façades display a visual luxury cue. The text layer | |
| 116 | +covers all 19{,}123 listings and the vision layer all 19{,}123 photographs, of which | |
| 117 | +95.8\% were recognized by the model as exterior shots. | |
| 73 | 118 | |
| 74 | 119 | \input{tables/ai_summary} |
modified
paper/sections/introduction.tex
+86 −59
@@ -11,77 +11,104 @@ performance of hedonic models is bounded by the richness of the characteristics | ||
| 11 | 11 | analyst can measure. A large share of what determines a home's value---its state of |
| 12 | 12 | repair, the quality of its finishes, its curb appeal, the character of its |
| 13 | 13 | street---is recorded not in structured fields but in the free-text description and |
| 14 | −the photographs that accompany each listing. These modalities have historically been | |
| 14 | +the photographs that accompany each listing. These modalities have long been | |
| 15 | 15 | discarded because they were costly to encode at scale, leaving hedonic estimates |
| 16 | −exposed to omitted-quality bias and hedonic predictions short of their potential | |
| 16 | +exposed to omitted-quality bias and hedonic predictions short of their attainable | |
| 17 | 17 | accuracy. |
| 18 | 18 | |
| 19 | 19 | This paper treats general-purpose artificial-intelligence models as a |
| 20 | −\emph{feature-engineering technology} for hedonic analysis, and quantifies the | |
| 20 | +\emph{feature-engineering technology} for hedonic analysis and quantifies the | |
| 21 | 21 | explanatory power that technology adds. We assemble a cross-section of 19{,}123 |
| 22 | −single-family houses and townhouses listed for sale in Quebec, pooling the | |
| 23 | −brokerage-listed MLS inventory from Realtor.ca with the for-sale-by-owner inventory | |
| 24 | −from DuProprio. On top of standard structural, locational, and amenity attributes, | |
| 25 | −we build two machine-generated feature layers. First, a large language model (LLM) | |
| 26 | −reads each free-text description and returns a fixed set of property | |
| 27 | −specifications---state of repair, renovation of the kitchen and bathroom, flooring | |
| 28 | −and countertop materials, heating system, view, and income potential---under a | |
| 29 | −strict JSON schema that guarantees valid, reproducible output. Second, a | |
| 22 | +single-family houses and townhouses listed for sale in Quebec on 3~July~2026, | |
| 23 | +pooling the brokerage-listed MLS inventory from Realtor.ca with the | |
| 24 | +for-sale-by-owner inventory from DuProprio. On top of standard structural, | |
| 25 | +locational, and amenity attributes, we build two machine-generated feature layers. | |
| 26 | +First, a large language model (LLM) reads each free-text description and returns a | |
| 27 | +fixed set of property specifications---state of repair, renovation of the kitchen | |
| 28 | +and bathroom, flooring and countertop materials, heating system, view, and income | |
| 29 | +potential---under a strict JSON schema with closed enumerations. Second, a | |
| 30 | 30 | vision--language model inspects the façade photograph of each property and returns |
| 31 | −objective visual attributes: overall condition, curb appeal, renovation level, | |
| 32 | −exterior materials, landscaping, setting, and a luxury indicator. Because both | |
| 33 | −extractions are schema-constrained, deterministic, and blind to the listing price, | |
| 34 | −their outputs behave as ordinary tabulated regressors rather than as noisy text. | |
| 31 | +visual attributes: overall condition, curb appeal, renovation level, exterior | |
| 32 | +materials, landscaping, setting, and a luxury indicator. Because both extractions | |
| 33 | +are schema-constrained, their outputs enter the hedonic regression as ordinary | |
| 34 | +tabulated regressors with interpretable coefficients rather than as latent scores. | |
| 35 | 35 | |
| 36 | 36 | Our contribution is threefold. First, we show that AI-based feature engineering |
| 37 | −delivers economically meaningful gains in explanatory power over an already rich | |
| 38 | −hedonic specification: the two machine-generated layers raise in-sample $R^2$ from | |
| 39 | −0.717 to 0.755 (nearly four points) in our preferred specification, and raise the | |
| 40 | −out-of-sample $R^2$ of every estimator we consider, with the façade-vision layer | |
| 41 | −alone contributing the largest single increment of any feature block (2.7 points for | |
| 42 | −gradient boosting, 5.8 points for OLS). Second, we show that the extracted | |
| 37 | +delivers gains in explanatory power over an already rich hedonic specification. In | |
| 38 | +our preferred specification---a log-linear model with 195 municipality fixed | |
| 39 | +effects, property-type fixed effects, and fifteen keyword amenities, room-level and | |
| 40 | +listing-quality controls---the two machine-generated layers raise in-sample $R^2$ | |
| 41 | +from 0.717 to 0.755, and they raise the out-of-sample $R^2$ of every estimator we | |
| 42 | +consider, from ordinary least squares to gradient boosting and an embedding-based | |
| 43 | +neural network. Of the two layers, the façade-vision layer is by far the more | |
| 44 | +informative: it adds 3.0 points of in-sample $R^2$ against 0.8 for the text layer, | |
| 45 | +and 5.8 (2.7) points of out-of-sample $R^2$ for OLS (gradient boosting), more than | |
| 46 | +the gain from replacing OLS by a random forest. Second, we show that the extracted | |
| 43 | 47 | attributes carry interpretable implicit prices---a one-point increase in visual curb |
| 44 | 48 | appeal is associated with a 2.3\% higher asking price, a visible luxury cue with |
| 45 | −5.2\%, brick or stone façades with premia of 3--4\% relative to vinyl siding, and a | |
| 46 | −renovated kitchen (read from the text) with 2.6\%---so the approach augments rather | |
| 47 | −than replaces the classical hedonic regression. Third, we document a complete, | |
| 48 | −reproducible pipeline from raw scraped listings to an analysis-ready dataset, | |
| 49 | −including rules-based outlier cleaning, unit harmonization that reconstructs living | |
| 50 | −area from room-level dimensions, and the schema-constrained extraction protocol, | |
| 51 | −with a total AI cost of about \$60 for the full sample---roughly a third of a cent | |
| 52 | −per listing. | |
| 49 | +5.2\%, brick or stone façades with premia of 3--4\% relative to the omitted | |
| 50 | +materials, and a renovated kitchen (read from the text) with 2.6\%---and that these | |
| 51 | +associations survive municipality-clustered inference, a cluster bootstrap, finer | |
| 52 | +postal-code (RTA) fixed effects, and a control for the language of the description. | |
| 53 | +Third, we document a complete and reproducible pipeline from raw scraped listings to | |
| 54 | +an analysis-ready dataset, including rules-based outlier cleaning, unit harmonization | |
| 55 | +that reconstructs living area from room-level dimensions, and the | |
| 56 | +schema-constrained extraction protocol, with a total AI cost of about \$60 for the | |
| 57 | +full sample---roughly a third of a cent per listing. | |
| 53 | 58 | |
| 54 | −Our main findings can be summarized as follows. A log--linear specification with 195 | |
| 55 | −municipality fixed effects, property-type fixed effects, and | |
| 56 | −municipality-clustered standard errors explains 75.5\% of the variation in log | |
| 57 | −asking prices when living area is observed, and 72.5\% on the full sample when it is | |
| 58 | −not. The estimated implicit prices are economically sensible: the living-area | |
| 59 | −elasticity is 0.36, each additional bathroom is associated with a 7.6\% premium, and | |
| 60 | −the age profile traces the familiar depreciation-then-heritage pattern. The | |
| 61 | −municipality effects span a wide range---from roughly $+231$\% in Westmount to about | |
| 62 | −$-30$\% in remote municipalities---and order the province's markets as expected. | |
| 63 | −Benchmarking a ladder of estimators on the identical feature set, an ensemble blend | |
| 64 | −of a robust embedding-based neural network and gradient boosting attains an | |
| 65 | −out-of-sample $R^2$ of 0.779 with a median absolute prediction error of 14.0\%. We | |
| 66 | −interpret all estimates as \emph{predictive} associations rather than causal | |
| 67 | −effects, since listing content is chosen by sellers and correlates with unobserved | |
| 68 | −determinants of value, and we discuss the asking-price nature of the dependent | |
| 69 | −variable at length in Section~\ref{sec:robustness}. | |
| 59 | +The revision reported here (version 2.1) also confronts three threats that a | |
| 60 | +skeptical reader should raise against any ``AI features'' exercise, and we | |
| 61 | +believe the paper is more useful for addressing them explicitly. The first is | |
| 62 | +\emph{information leakage}. Every DuProprio description in our data embeds a | |
| 63 | +structured block that includes the asking price itself (``Asking Price \$599,000''), | |
| 64 | +so the language model read the dependent variable for 19.7\% of the sample. The | |
| 65 | +schema contains no price field, but the text-layer gain is five times larger on | |
| 66 | +DuProprio than on Realtor.ca, whose descriptions never contain the asking price, | |
| 67 | +and we therefore report all gains separately by platform and treat the Realtor.ca | |
| 68 | +estimates as the clean benchmark. The vision model never sees the price. The second | |
| 69 | +is \emph{language}. Forty-three percent of the descriptions are in English, and | |
| 70 | +English-language listings are priced about 7\% higher than French ones conditional | |
| 71 | +on all other attributes and on location; the AI implicit prices are, however, | |
| 72 | +essentially unchanged when language is controlled for, and the gains from both | |
| 73 | +layers are present within the French and within the English subsamples. The third | |
| 74 | +is \emph{spatial dependence in validation}. Random cross-validation folds let a | |
| 75 | +model learn from a neighbour of each held-out house; when folds are formed by | |
| 76 | +forward sortation area instead, all estimators lose three to five points of | |
| 77 | +out-of-sample $R^2$, but the increments from the text and vision layers are | |
| 78 | +preserved. | |
| 70 | 79 | |
| 71 | −Beyond the specific Quebec application, the exercise speaks to a general measurement | |
| 72 | −problem in housing economics. Text- and image-derived quality measures have until | |
| 73 | −now required bespoke supervised models trained on labeled data | |
| 74 | −\citep{nowak2017textual,shen2021information,johnson2020curb}. General-purpose | |
| 75 | −foundation models with schema-constrained decoding lower the fixed cost of that | |
| 76 | −measurement step to nearly zero, produce attributes that are human-readable rather | |
| 77 | −than latent, and can be audited field by field. Our results suggest that this | |
| 78 | −technology moves the effective characteristics frontier of hedonic analysis by | |
| 79 | −enough to matter for appraisal, automated valuation, and assessment applications. | |
| 80 | +Our main findings can be summarized as follows. The preferred specification explains | |
| 81 | +75.5\% of the variation in log asking prices when living area is observed and 72.5\% | |
| 82 | +on the full sample when it is not. The living-area elasticity is 0.36, each | |
| 83 | +additional bathroom is associated with a 7.6\% premium, and the age profile traces | |
| 84 | +the familiar depreciation-then-heritage pattern. The municipality effects range from | |
| 85 | +about $+231$\% in Westmount to about $-30$\% in remote municipalities relative to the | |
| 86 | +pooled group of small municipalities, and order the province's markets as expected. | |
| 87 | +On the identical feature set, an equally weighted blend of a robust embedding-based | |
| 88 | +neural network and gradient boosting attains an out-of-sample $R^2$ of 0.779 with a | |
| 89 | +median absolute percentage error (MdAPE) of 14.0\% under random folds. We interpret | |
| 90 | +all coefficients as \emph{predictive associations} rather than causal effects: listing | |
| 91 | +content is chosen by sellers and their agents and correlates with unobserved | |
| 92 | +determinants of value, and the dependent variable is an asking price, two issues we | |
| 93 | +discuss at length in Section~\ref{sec:robustness}. | |
| 94 | + | |
| 95 | +Beyond the Quebec application, the exercise speaks to a measurement problem in | |
| 96 | +housing economics. Text- and image-derived quality measures have until now required | |
| 97 | +bespoke supervised models trained on labelled data | |
| 98 | +\citep{nowak2017textual,shen2021information,johnson2020curb,lindenthal2021architecture}. | |
| 99 | +General-purpose foundation models with schema-constrained decoding lower the fixed | |
| 100 | +cost of that measurement step to nearly zero, produce attributes that are | |
| 101 | +human-readable rather than latent, and can be audited field by field. Our results | |
| 102 | +suggest that this technology shifts the effective characteristics frontier of hedonic | |
| 103 | +analysis by enough to matter for appraisal, automated valuation, and assessment | |
| 104 | +applications---provided that the text fed to the model is screened for the outcome | |
| 105 | +it is meant to predict. | |
| 80 | 106 | |
| 81 | 107 | The remainder of the paper is organized as follows. Section~\ref{sec:literature} |
| 82 | −reviews the related literature. Section~\ref{sec:data} describes the data sources | |
| 83 | −and cleaning. Section~\ref{sec:methodology} presents the feature-engineering | |
| 84 | −pipeline and the econometric specification. Section~\ref{sec:results} reports the | |
| 85 | −main results. Section~\ref{sec:benchmark} maps the predictive frontier across | |
| 86 | −estimators. Section~\ref{sec:robustness} discusses robustness and limitations. | |
| 108 | +reviews the related literature. Section~\ref{sec:data} describes the data, the | |
| 109 | +cleaning rules, and the content of the descriptions. Section~\ref{sec:methodology} | |
| 110 | +presents the feature-engineering pipeline and the econometric specification. | |
| 111 | +Section~\ref{sec:results} reports the main results. Section~\ref{sec:benchmark} | |
| 112 | +maps the predictive frontier across estimators. Section~\ref{sec:robustness} | |
| 113 | +reports the robustness analyses and discusses limitations. | |
| 87 | 114 | Section~\ref{sec:conclusion} concludes. |
modified
paper/sections/literature.tex
+77 −44
@@ -14,53 +14,84 @@ survey the characteristics most commonly included in hedonic house-price models | ||
| 14 | 14 | document substantial heterogeneity in specification, \citet{malpezzi2003hedonic} |
| 15 | 15 | provides a critical review of functional-form and identification choices, and |
| 16 | 16 | \citet{hill2013hedonic} surveys the use of hedonic methods for house-price |
| 17 | −measurement. A recurring theme in this literature is omitted-variable bias from | |
| 18 | −unmeasured quality: the state of repair, the standard of finishes, and the visual | |
| 19 | −quality of a dwelling are priced by the market but rarely recorded in the structured | |
| 20 | −fields available to the econometrician. Our contribution speaks directly to this | |
| 21 | −measurement problem. Our log--linear specification, with logged continuous attributes | |
| 22 | −and a dependent variable in logs, follows the mainstream of this literature. | |
| 17 | +measurement. A recurring theme is omitted-variable bias from unmeasured quality: | |
| 18 | +the state of repair, the standard of finishes, and the visual quality of a dwelling | |
| 19 | +are priced by the market but rarely recorded in the structured fields available to | |
| 20 | +the econometrician. \citet{nowak2020quality} show that this omission is not | |
| 21 | +innocuous even for aggregate statistics, since quality-adjusted repeat-sales indexes | |
| 22 | +built with information from listing remarks differ materially from conventional | |
| 23 | +ones. Our contribution speaks directly to this measurement problem. Our log-linear | |
| 24 | +specification, with logged continuous attributes and a dependent variable in logs, | |
| 25 | +follows the mainstream of this literature, and we read indicator coefficients with | |
| 26 | +the \citet{halvorsen1980interpretation} transformation; the small-sample refinement | |
| 27 | +of \citet{kennedy1981estimation} is immaterial at our precision. | |
| 23 | 28 | |
| 24 | −The second strand concerns \textbf{spatial structure, functional form, and | |
| 25 | −prediction}. \citet{can1992spatial} and \citet{anselin1988spatial} emphasize that | |
| 26 | −unobserved locational amenities induce spatial dependence that, if ignored, biases | |
| 27 | −coefficient estimates; we absorb the first-order component of this problem through a | |
| 28 | −rich set of municipality fixed effects and cluster inference at the same level. | |
| 29 | −On the prediction side, \citet{bin2004prediction} compares parametric and | |
| 30 | −semi-parametric hedonic predictors, \citet{mullainathan2017machine} frame | |
| 31 | −machine-learning methods as estimators of the conditional expectation | |
| 32 | −$\mathbb{E}[P\mid\mathbf{z}]$ well suited to prediction tasks, and | |
| 33 | −\citet{kok2017bigdata} document the rise of automated valuation models in industry. | |
| 34 | −This literature generally finds that flexible learners beat linear hedonics on | |
| 35 | −accuracy at some cost in interpretability; our estimator ladder | |
| 36 | −(Section~\ref{sec:benchmark}) reproduces that pattern on a common feature set, and | |
| 37 | −our focus is on how much of the gap is closed not by a better \emph{estimator} but by | |
| 38 | −better \emph{measurement}. | |
| 29 | +The second strand concerns \textbf{spatial structure, inference, and prediction}. | |
| 30 | +\citet{can1992spatial} and \citet{anselin1988spatial} emphasize that unobserved | |
| 31 | +locational amenities induce spatial dependence that, if ignored, biases coefficient | |
| 32 | +estimates and understates uncertainty; we absorb the first-order component of this | |
| 33 | +problem through municipality fixed effects, re-estimate with finer forward | |
| 34 | +sortation area (RTA) effects, and cluster inference at the level of the fixed | |
| 35 | +effects \citep{cameron2015cluster,abadie2023when}, complementing the analytical | |
| 36 | +standard errors with a cluster bootstrap because our clusters are of very unequal | |
| 37 | +size \citep{mackinnon2017wild}. The same dependence bears on validation. | |
| 38 | +\citet{bourassa2010predicting} show that spatial structure that is not exploited by | |
| 39 | +the model surfaces in prediction errors, \citet{pace2020examining} find that tree | |
| 40 | +ensembles recover information left in the residuals of hedonic and spatial models, | |
| 41 | +and \citet{roberts2017cross} document that random cross-validation is optimistic | |
| 42 | +whenever observations are spatially clustered, recommending blocked (spatially | |
| 43 | +grouped) folds instead. We report both. On the prediction side, \citet{bin2004prediction} | |
| 44 | +compares parametric and semi-parametric hedonic predictors, \citet{mullainathan2017machine} | |
| 45 | +frame machine-learning methods as estimators of the conditional expectation | |
| 46 | +$\mathbb{E}[P\mid\mathbf{z}]$ suited to prediction tasks, and \citet{kok2017bigdata} | |
| 47 | +document the rise of automated valuation models (AVMs) in industry. This literature | |
| 48 | +generally finds that flexible learners beat linear hedonics on accuracy at some cost | |
| 49 | +in interpretability; our estimator ladder (Section~\ref{sec:benchmark}) reproduces | |
| 50 | +that pattern on a common feature set, and our focus is on how much of the gap is | |
| 51 | +closed not by a better \emph{estimator} but by better \emph{measurement}. | |
| 39 | 52 | |
| 40 | 53 | The third strand is the use of \textbf{unstructured listing content}---text and |
| 41 | 54 | images---in real-estate valuation. \citet{gentzkow2019text} survey text-as-data |
| 42 | −methods in economics. In real estate specifically, \citet{nowak2017textual} show that | |
| 43 | −words in MLS remarks predict transaction prices and reduce hedonic pricing errors, | |
| 44 | −and \citet{shen2021information} extract quality signals from property descriptions | |
| 45 | −with supervised machine learning, finding that the text carries information about | |
| 46 | −unobserved quality that is capitalized into prices. On the image side, | |
| 47 | −\citet{ahmed2016house} combine visual and textual features for price estimation; | |
| 48 | −\citet{poursaeed2018vision} show that learned measures of interior and exterior | |
| 49 | −quality carry independent predictive power; \citet{glaeser2018vision} use street-level | |
| 50 | −imagery of Boston houses to measure exterior quality and study its interaction with | |
| 51 | −incentives; \citet{johnson2020curb} construct a curb-appeal index from Google Street | |
| 52 | −View images and estimate its capitalization into sale prices; and | |
| 53 | −\citet{lindenthal2021architecture} classify architectural styles from photographs and | |
| 54 | −document style premia. Relative to this work, our approach differs in the | |
| 55 | +methods in economics, and \citet{dell2025deep} and \citet{korinek2023generative} | |
| 56 | +survey, respectively, deep learning and generative models as research tools for | |
| 57 | +economists. In real estate specifically, \citet{nowak2017textual} show that words in | |
| 58 | +MLS remarks predict transaction prices and reduce hedonic pricing errors; | |
| 59 | +\citet{nowak2021dictionaries} show that the price-relevant vocabulary is not stable | |
| 60 | +across markets or over time, a warning against transferring word lists; and | |
| 61 | +\citet{shen2021information} extract quality signals from property descriptions with | |
| 62 | +supervised machine learning, finding that the text carries information about | |
| 63 | +unobserved quality that is capitalized into prices. \citet{zhang2024describe} | |
| 64 | +benchmark text encoders for price prediction and find that textual and | |
| 65 | +non-textual features are complementary, and a companion working paper on Quebec | |
| 66 | +listings \citep{boucher2026decoding} documents that semantic embeddings of | |
| 67 | +descriptions carry out-of-sample price information and that the language of the | |
| 68 | +description is a first-order confounder in a bilingual market---a finding we | |
| 69 | +build on here. On the image side, \citet{ahmed2016house} combine visual and | |
| 70 | +textual features for price estimation; \citet{bessinger2016quantifying} and | |
| 71 | +\citet{poursaeed2018vision} show that learned measures of exterior and interior | |
| 72 | +quality carry independent predictive power; \citet{naik2017computer} and | |
| 73 | +\citet{glaeser2018vision} use street-level imagery to measure the physical | |
| 74 | +appearance of neighbourhoods and houses and study how appearance relates to | |
| 75 | +incentives and change; \citet{law2019take} and \citet{kang2021understanding} | |
| 76 | +combine street-view and satellite imagery with structured attributes to predict | |
| 77 | +prices and appreciation; \citet{zhang2018greenery} price street-visible greenery | |
| 78 | +from street-view images; \citet{johnson2020curb} construct a curb-appeal index from | |
| 79 | +Google Street View images and estimate its capitalization into sale prices; and | |
| 80 | +\citet{lindenthal2021architecture} classify architectural styles from photographs | |
| 81 | +and document style premia. Relative to this work, our approach differs in the | |
| 55 | 82 | \emph{technology of measurement}: rather than training bespoke supervised models on |
| 56 | −labeled data---which requires labels, task-specific engineering, and yields opaque | |
| 57 | −scores---we use general-purpose large language and vision--language models with | |
| 58 | −schema-constrained decoding to produce a fixed set of interpretable, human-readable | |
| 59 | −attributes (e.g., ``renovated kitchen,'' ``brick façade,'' a 1--10 curb-appeal score) | |
| 60 | −at a marginal cost of a fraction of a cent per listing, and we embed those attributes | |
| 61 | −in a transparent hedonic regression whose coefficients can be read as implicit | |
| 62 | −prices. The models never observe the price, so the extracted attributes cannot | |
| 63 | −mechanically encode the outcome. | |
| 83 | +labelled data---which requires labels and task-specific engineering, and yields | |
| 84 | +opaque scores---we use general-purpose large language and vision--language models | |
| 85 | +with schema-constrained decoding to produce a fixed set of interpretable, | |
| 86 | +human-readable attributes (``renovated kitchen,'' ``brick façade,'' a 1--10 | |
| 87 | +curb-appeal score) at a marginal cost of a fraction of a cent per listing, and we | |
| 88 | +embed those attributes in a transparent hedonic regression whose coefficients can be | |
| 89 | +read as implicit prices. The reliability of such zero-shot annotation is itself an | |
| 90 | +active research question; \citet{gilardi2023chatgpt} find that general-purpose LLMs | |
| 91 | +match or exceed crowd workers on standard text-annotation tasks, but the extraction | |
| 92 | +error of any particular field must be assessed, which we do by confronting the | |
| 93 | +machine-generated attributes with independent sources | |
| 94 | +(Section~\ref{subsec:validation}). | |
| 64 | 95 | |
| 65 | 96 | The fourth strand is the \textbf{microstructure of listing markets}, which frames two |
| 66 | 97 | institutional features of our data. Our sample pools a brokered MLS platform |
@@ -70,5 +101,7 @@ composition, marketing, and outcomes, motivating our platform indicator and | ||
| 70 | 101 | platform-specific robustness checks. And because we observe asking rather than |
| 71 | 102 | transaction prices, the interpretation of our dependent variable rests on the |
| 72 | 103 | list-price literature: the asking price is a strategic choice that anchors search and |
| 73 | −bargaining \citep{horowitz1992list,knight2002listing,han2015microstructure}. We | |
| 74 | −return to this limitation in Section~\ref{sec:robustness}. | |
| 104 | +bargaining \citep{horowitz1992list,knight2002listing,han2015microstructure}, and | |
| 105 | +\citet{han2016asking} show that it acts simultaneously as a commitment device and | |
| 106 | +as a signal in a directed-search environment. We return to this limitation in | |
| 107 | +Section~\ref{subsec:limits}. | |
modified
paper/sections/methodology.tex
+136 −65
@@ -14,12 +14,12 @@ listings into an analysis-ready design matrix (Sections~\ref{subsec:structural}- | ||
| 14 | 14 | Following \citet{rosen1974hedonic}, a house is a bundle of $K$ characteristics |
| 15 | 15 | $\mathbf{z}=(z_1,\dots,z_K)$, and the market clears through a hedonic price function |
| 16 | 16 | $P(\mathbf{z})$ that equates the marginal bid of buyers to the marginal offer of |
| 17 | −sellers. A buyer with income $y$ and preferences $U(\mathbf{x},\mathbf{z})$ over a | |
| 18 | −numéraire good $\mathbf{x}$ and housing attributes chooses $\mathbf{z}$ to solve | |
| 17 | +sellers. A buyer with income $y$ and preferences $U(x,\mathbf{z})$ over a | |
| 18 | +numéraire good $x$ and housing attributes chooses $\mathbf{z}$ to solve | |
| 19 | 19 | % |
| 20 | 20 | \begin{equation} |
| 21 | − \max_{\mathbf{x},\,\mathbf{z}}\; U(\mathbf{x},\mathbf{z}) | |
| 22 | − \quad\text{s.t.}\quad y = \mathbf{x} + P(\mathbf{z}), | |
| 21 | + \max_{x,\,\mathbf{z}}\; U(x,\mathbf{z}) | |
| 22 | + \quad\text{s.t.}\quad y = x + P(\mathbf{z}), | |
| 23 | 23 | \label{eq:consumer} |
| 24 | 24 | \end{equation} |
| 25 | 25 | % |
@@ -40,7 +40,12 @@ $P(\mathbf{z})$---and hence its gradient---from observed prices and characterist | ||
| 40 | 40 | The linear model of Section~\ref{subsec:econometrics} imposes a parametric form on |
| 41 | 41 | $P(\cdot)$ and reads the implicit prices off its coefficients; the machine-learning |
| 42 | 42 | estimators of Section~\ref{sec:benchmark} approximate $P(\cdot)$ nonparametrically, |
| 43 | −trading the closed-form gradient for predictive flexibility. | |
| 43 | +trading the closed-form gradient for predictive flexibility. Two caveats apply | |
| 44 | +throughout. The observed price is an asking price, so $P(\cdot)$ is the hedonic | |
| 45 | +function of sellers' offers rather than of transactions; and the machine-generated | |
| 46 | +attributes are measured with error and chosen by the seller, so their coefficients | |
| 47 | +are predictive associations rather than structural marginal prices | |
| 48 | +(Section~\ref{subsec:limits}). | |
| 44 | 49 | |
| 45 | 50 | \subsection{Structural and Locational Attributes} |
| 46 | 51 | \label{subsec:structural} |
@@ -60,24 +65,33 @@ median, and each imputed field is accompanied by a ``\texttt{has\_}'' indicator | ||
| 60 | 65 | that the regression can distinguish observed from imputed values. |
| 61 | 66 | |
| 62 | 67 | Location is captured by \textbf{municipality fixed effects}. City names are |
| 63 | −normalized (Realtor.ca appends neighborhood qualifiers in parentheses, which we | |
| 68 | +normalized (Realtor.ca appends neighbourhood qualifiers in parentheses, which we | |
| 64 | 69 | strip), and municipalities with fewer than 20 listings are pooled into a residual |
| 65 | −category, leaving 195 city effects. Property-type fixed effects and a source | |
| 66 | −indicator complete the locational and platform controls. | |
| 70 | +category, leaving 195 city effects; the pooled group of small municipalities is the | |
| 71 | +omitted (reference) category, so every reported municipality effect is a premium or | |
| 72 | +discount relative to a listing in a small municipality. In robustness checks we | |
| 73 | +replace the municipality effects by \textbf{forward sortation area (RTA) effects}, | |
| 74 | +the first three characters of the postal code, which are available for all but one | |
| 75 | +listing: 419 RTAs appear in the sample, of which 250 have at least 20 listings and | |
| 76 | +receive their own effect. Property-type fixed effects and a source indicator complete | |
| 77 | +the locational and platform controls. | |
| 67 | 78 | |
| 68 | 79 | \subsection{Rule-Based Amenities and Room Detail} |
| 69 | 80 | \label{subsec:amenities} |
| 70 | 81 | |
| 71 | −Seventeen amenity indicators are detected by bilingual (French/English) keyword | |
| 82 | +Fifteen amenity indicators are detected by bilingual (French/English) keyword | |
| 72 | 83 | matching over the concatenated feature list, description, and title: swimming pool, |
| 73 | 84 | waterfront, garage, fireplace, central air conditioning or heat pump, finished |
| 74 | −basement, cul-de-sac, proximity to a golf course, ski hill, park, school, highway, | |
| 75 | −and public transit, among others. From the Realtor.ca room block we additionally | |
| 76 | −construct room-detail indicators---presence of a primary bedroom, a basement, an | |
| 77 | −office, a family room, a workshop, a wine cellar, a sunroom, a mezzanine, a library, | |
| 78 | −and a laundry room---together with the room and storey counts. Two listing-quality | |
| 79 | −signals, the number of photographs (capped at~60) and the presence of a virtual | |
| 80 | −tour, proxy for the marketing tier of the listing. | |
| 85 | +basement, proximity to water, cul-de-sac, proximity to a golf course, ski hill, | |
| 86 | +park, school, highway, and public transit, and the absence of rear neighbours. From | |
| 87 | +the Realtor.ca room block we additionally construct room-detail indicators---presence | |
| 88 | +of a primary bedroom, a basement, an office, a family room, a workshop, a wine | |
| 89 | +cellar, a sunroom, a mezzanine, a library, and a laundry room---together with the | |
| 90 | +room and storey counts. Two listing-quality signals, the number of photographs | |
| 91 | +(capped at~60) and the presence of a virtual tour, proxy for the marketing tier of | |
| 92 | +the listing. Finally, following the evidence of Section~\ref{subsec:text_content}, | |
| 93 | +two language indicators (English, mixed; French omitted) and the description length | |
| 94 | +are available as controls. | |
| 81 | 95 | |
| 82 | 96 | \subsection{Language-Model Specifications from Text} |
| 83 | 97 | \label{subsec:llm} |
@@ -87,43 +101,59 @@ extraction: whether the home is turnkey or a fixer-upper, whether the kitchen or | ||
| 87 | 101 | bathroom has been renovated, the flooring and countertop materials, the heating |
| 88 | 102 | system, the presence of a water view, and income potential. We extract these as a |
| 89 | 103 | fixed set of structured specifications using a large language model |
| 90 | −(\texttt{gpt-4o-mini}) with \emph{schema-constrained decoding}: the request specifies | |
| 91 | −a strict JSON schema with closed enumerations and required fields, so the API | |
| 92 | −validates the output at generation time and the model returns exactly the expected | |
| 93 | −fields in the expected value domains. Decoding temperature is set to zero for | |
| 94 | −determinism, and the system instruction constrains the model to report only what the | |
| 95 | −text supports, coding absent information as \texttt{false}/\texttt{unknown}/empty. | |
| 96 | −Each call consumes roughly 600 input and 110 output tokens; the extraction is run in | |
| 97 | −parallel, is resumable through an on-disk cache keyed by the listing identifier, and | |
| 98 | −retries transient errors with exponential backoff, for a total cost of about \$3 | |
| 99 | −across the sample. | |
| 104 | +(\texttt{gpt-4o-mini}, OpenAI, called through the Chat Completions API in July 2026) | |
| 105 | +with \emph{schema-constrained decoding}: the request specifies a strict JSON schema | |
| 106 | +with closed enumerations and required fields, so the API validates the output at | |
| 107 | +generation time and the model returns exactly the expected fields in the expected | |
| 108 | +value domains (Table~\ref{tab:app_features}). Decoding temperature is set to zero, | |
| 109 | +and the system instruction, written in French, constrains the model to rely only on | |
| 110 | +the text and to code absent information as \texttt{false}, \texttt{unknown}, or an | |
| 111 | +empty list. Each call consumes roughly 600 input and 110 output tokens; the | |
| 112 | +extraction is run in parallel, is resumable through an on-disk cache keyed by the | |
| 113 | +listing identifier, and retries transient errors with exponential backoff, for a | |
| 114 | +total cost of about \$3 across the sample. Descriptions are truncated at 4{,}000 | |
| 115 | +characters, which affects only the longest DuProprio property sheets. | |
| 100 | 116 | |
| 101 | 117 | \subsection{Vision Attributes from the Façade Photograph} |
| 102 | 118 | \label{subsec:vision} |
| 103 | 119 | |
| 104 | 120 | To capture the visual quality that neither structured fields nor text convey, we |
| 105 | 121 | analyze one photograph per listing---the façade---with a vision--language model |
| 106 | −(\texttt{claude-haiku-4-5}). For Realtor.ca the first image is the exterior shot; for | |
| 107 | −DuProprio, whose images are captioned, we select the image whose caption is the | |
| 108 | −address rather than a room. The model returns twelve objective attributes under a | |
| 109 | −strict JSON schema: an overall condition score (1--10), a curb-appeal score (1--10), | |
| 110 | −a renovation level, exterior materials, landscaping quality, visible garage, storeys, | |
| 111 | −setting (urban/suburban/rural/waterfront/wooded), a luxury indicator, and photo | |
| 112 | −quality. The system instruction directs the model to ground each score in concrete, | |
| 113 | −reproducible criteria (surface condition, materials, landscaping) rather than | |
| 114 | −subjective taste, and to flag non-exterior images. Images are passed by URL without | |
| 115 | −local download; each call consumes roughly 2{,}470 input and 100 output tokens, for a | |
| 116 | −total cost of about \$57 across the sample. As with the text layer, the pass is | |
| 117 | −parallelized, resumable, and retried. | |
| 118 | − | |
| 119 | −\paragraph{Why schema-constrained decoding matters.} | |
| 122 | +(\texttt{claude-haiku-4-5}, Anthropic, Messages API, July 2026). For Realtor.ca the | |
| 123 | +first image is the exterior shot; for DuProprio, whose images are captioned, we | |
| 124 | +select the first image whose caption is not a room name. The model returns twelve | |
| 125 | +fields under a strict JSON schema: an exterior-shot flag, a visual building type, an | |
| 126 | +overall condition score (1--10), a curb-appeal score (1--10), a renovation level, | |
| 127 | +the list of exterior materials, landscaping quality, a visible-garage flag, the | |
| 128 | +visual storey count, the setting (dense urban, suburban, rural, waterfront, wooded), | |
| 129 | +a photo-quality score, and a luxury indicator. The system instruction directs the | |
| 130 | +model to ground each score in concrete criteria (surface condition, materials, | |
| 131 | +landscaping) rather than taste, and to flag non-exterior images. Images are passed | |
| 132 | +by URL without local download; each call consumes roughly 2{,}470 input and 100 | |
| 133 | +output tokens, for a total cost of about \$57 across the sample. As with the text | |
| 134 | +layer, the pass is parallelized, resumable, and retried. Unlike the text layer, the | |
| 135 | +vision calls did not set a sampling temperature and therefore ran at the API default, | |
| 136 | +so repeated calls could return slightly different scores for borderline images; we | |
| 137 | +did not re-run the extraction to measure this test--retest variability (see | |
| 138 | +Section~\ref{subsec:limits}). | |
| 139 | + | |
| 140 | +\paragraph{From schema fields to regressors.} | |
| 120 | 141 | Imposing a typed schema with enumerations, required fields, and |
| 121 | −\texttt{additionalProperties:false} moves validation into the API layer. The models | |
| 122 | −are forced to emit exactly the expected fields within the expected value domains, so | |
| 123 | −their outputs behave as ordinary tabulated variables---reproducible and free of | |
| 124 | −free-text post-processing. The outputs are then mapped to numeric regressors: | |
| 125 | −booleans to $0/1$, the ordinal condition scale to $0$--$5$, materials to indicator | |
| 126 | −variables, and so on, each with an availability flag. | |
| 142 | +\texttt{additionalProperties:false} moves validation into the API layer, so the | |
| 143 | +outputs are tabulated variables that require no free-text post-processing. They are | |
| 144 | +then mapped to numeric regressors: booleans to $0/1$; the six-level text condition | |
| 145 | +scale to an ordinal score $0$--$5$ (\textit{to renovate} $=0$, \ldots, \textit{new} | |
| 146 | +$=5$, with \textit{unknown} placed at the ``good'' midpoint of~2); the five-level | |
| 147 | +visual renovation scale to $0$--$4$ and landscaping to $0$--$3$; multi-valued | |
| 148 | +fields (flooring, heating, exterior materials) and the setting to one indicator per | |
| 149 | +category. The twelve vision fields thus generate 21 regressors (two scores, the | |
| 150 | +photo-quality score, two ordinal scales, three indicators, five setting indicators, | |
| 151 | +and eight material indicators), and the text schema 18 regressors. A listing whose | |
| 152 | +photograph is not an exterior shot keeps the model's best-effort scores and is | |
| 153 | +flagged by the exterior indicator. Model identifiers are API aliases that resolve to | |
| 154 | +the provider's current snapshot; we record the alias and the extraction date, and | |
| 155 | +the raw JSON outputs are archived so that every regressor can be regenerated from | |
| 156 | +them without new API calls. | |
| 127 | 157 | |
| 128 | 158 | \subsection{Econometric Specification} |
| 129 | 159 | \label{subsec:econometrics} |
@@ -149,26 +179,37 @@ disjoint blocks, | ||
| 149 | 179 | and estimate, by ordinary least squares, |
| 150 | 180 | % |
| 151 | 181 | \begin{equation} |
| 152 | − \ln P_i \;=\; \alpha | |
| 182 | + \begin{aligned} | |
| 183 | + \ln P_i \;=\;& \alpha | |
| 153 | 184 | \;+\; \beta\,\ln\text{Area}_i |
| 154 | 185 | \;+\; \gamma\,\ln\text{Lot}_i |
| 155 | − \;+\; \mathbf{X}_i^{\!\top}\bm{\delta} | |
| 186 | + \;+\; \mathbf{s}_i^{\!\top}\bm{\delta}_s + \mathbf{a}_i^{\!\top}\bm{\delta}_a | |
| 187 | + + \mathbf{r}_i^{\!\top}\bm{\delta}_r + \mathbf{m}_i^{\!\top}\bm{\delta}_m \\ | |
| 188 | + &+ \underbrace{\mathbf{g}_i^{\!\top}\bm{\delta}_g}_{\text{LLM text}} | |
| 189 | + + \underbrace{\mathbf{v}_i^{\!\top}\bm{\delta}_v}_{\text{vision}} | |
| 156 | 190 | \;+\; \underbrace{\mu_{c(i)}}_{\text{city FE}} |
| 157 | 191 | \;+\; \underbrace{\tau_{t(i)}}_{\text{type FE}} |
| 158 | 192 | \;+\; \varepsilon_i , |
| 193 | + \end{aligned} | |
| 159 | 194 | \label{eq:hedonic} |
| 160 | 195 | \end{equation} |
| 161 | 196 | % |
| 162 | 197 | where $c(i)$ and $t(i)$ index the municipality and property type of listing~$i$, and |
| 163 | −$\mu_c$, $\tau_t$ are the corresponding fixed effects that sweep out | |
| 164 | −location- and type-specific price levels. In matrix form | |
| 165 | −$\mathbf{y}=\mathbf{Z}\bm{\theta}+\bm{\varepsilon}$ with | |
| 198 | +$\mu_c$, $\tau_t$ are the corresponding fixed effects that sweep out location- and | |
| 199 | +type-specific price levels. The source indicator is part of $\mathbf{m}_i$. In | |
| 200 | +matrix form $\mathbf{y}=\mathbf{Z}\bm{\theta}+\bm{\varepsilon}$ with | |
| 166 | 201 | $\widehat{\bm{\theta}}=(\mathbf{Z}^{\!\top}\mathbf{Z})^{-1}\mathbf{Z}^{\!\top}\mathbf{y}$. |
| 202 | +The contribution of a feature layer is measured by the change in $R^2$ when its | |
| 203 | +block is added to the specification that contains all preceding blocks; the order | |
| 204 | +is size and structural, amenities, rooms and listing signals, text, vision, so the | |
| 205 | +text layer is credited only with what the keyword amenities do not already capture, | |
| 206 | +and the vision layer only with what neither the text nor the structured fields | |
| 207 | +capture. | |
| 167 | 208 | |
| 168 | 209 | \paragraph{Interpretation of the coefficients.} |
| 169 | 210 | Because the size variables enter in logs, $\beta$ and $\gamma$ are \emph{elasticities}: |
| 170 | 211 | $\partial \ln P/\partial \ln\text{Area}=\beta$. For an indicator regressor $d$ with |
| 171 | −coefficient $b$, the exact percentage price effect is not $b$ but | |
| 212 | +coefficient $b$, the percentage price effect is not $b$ but | |
| 172 | 213 | % |
| 173 | 214 | \begin{equation} |
| 174 | 215 | \%\Delta P \;=\; \big(e^{\,b}-1\big)\times 100, |
@@ -176,10 +217,14 @@ coefficient $b$, the exact percentage price effect is not $b$ but | ||
| 176 | 217 | \end{equation} |
| 177 | 218 | % |
| 178 | 219 | the \citet{halvorsen1980interpretation} correction we apply throughout (for small |
| 179 | −$b$, $e^{b}-1\approx b$). Under Equation~\eqref{eq:hedonic} the implicit price of a | |
| 180 | −continuous attribute $z_k$ from \eqref{eq:implicit} is $p_k=\delta_k\,P/z_k$, so the | |
| 181 | −semi-log form lets the \emph{dollar} marginal price scale with the price level while | |
| 182 | −keeping the \emph{percentage} effect constant. | |
| 220 | +$b$, $e^{b}-1\approx b$; the \citealp{kennedy1981estimation} adjustment | |
| 221 | +$e^{\,b-\frac12\widehat{\mathrm{Var}}(b)}-1$ moves none of our reported effects by | |
| 222 | +more than 0.1 percentage point). For an ordinal score such as curb appeal, $b$ is the | |
| 223 | +log-price difference associated with one step of the scale, holding the other | |
| 224 | +attributes fixed. Under Equation~\eqref{eq:hedonic} the implicit price of a | |
| 225 | +continuous attribute $z_k$ from \eqref{eq:implicit} is $p_k=\delta_k\,P/z_k$, so | |
| 226 | +the semi-log form lets the \emph{dollar} marginal price scale with the price level | |
| 227 | +while keeping the \emph{percentage} effect constant. | |
| 183 | 228 | |
| 184 | 229 | \paragraph{Two-part coverage design.} |
| 185 | 230 | Because living area is reported for only about 38\% of Realtor.ca listings, we |
@@ -194,15 +239,16 @@ estimate two nested versions of \eqref{eq:hedonic} and combine their predictions | ||
| 194 | 239 | \label{eq:twopart} |
| 195 | 240 | \end{equation} |
| 196 | 241 | % |
| 197 | −Model~A includes $\ln\text{Area}$ and is fit on the measured-area subsample; Model~B | |
| 198 | −drops it and is fit on the full cleaned sample, so every listing can be priced. | |
| 242 | +Model~A includes $\ln\text{Area}$ and is fit on the 9{,}446 listings with a measured | |
| 243 | +or reconstructed area; Model~B drops it and is fit on the full cleaned sample, so | |
| 244 | +every listing can be priced. | |
| 199 | 245 | |
| 200 | 246 | \paragraph{Inference.} |
| 201 | 247 | House-price residuals are strongly heteroskedastic, and listings within a |
| 202 | 248 | municipality share unobserved local shocks that induce within-cluster error |
| 203 | 249 | correlation. Our preferred standard errors are therefore clustered at the |
| 204 | 250 | municipality level (195 clusters), the same level as the fixed effects |
| 205 | −\citep{cameron2015cluster}: | |
| 251 | +\citep{cameron2015cluster,abadie2023when}: | |
| 206 | 252 | % |
| 207 | 253 | \begin{equation} |
| 208 | 254 | \widehat{\mathrm{Var}}_{\text{CL}}(\widehat{\bm{\theta}}) |
@@ -215,12 +261,18 @@ municipality level (195 clusters), the same level as the fixed effects | ||
| 215 | 261 | \end{equation} |
| 216 | 262 | % |
| 217 | 263 | where $\mathbf{Z}_c$ and $\hat{\bm{\varepsilon}}_c$ stack the regressors and |
| 218 | −residuals of cluster $c$. As a complement we also compute | |
| 219 | −heteroskedasticity-consistent (HC3) standard errors | |
| 220 | −\citep{white1980heteroskedasticity,mackinnon1985some}, which inflate the | |
| 221 | −contribution of high-leverage points; Section~\ref{subsec:robust} shows that the two | |
| 222 | −choices agree on the significance of the property-level AI attributes and differ | |
| 223 | −only for keyword amenities with a strong spatial component. | |
| 264 | +residuals of cluster $c$. Cluster sizes are very unequal---Montreal alone contributes | |
| 265 | +about one listing in twenty, and the pooled residual category of small municipalities, | |
| 266 | +which is treated as a single cluster, holds about one listing in four (5{,}006 listings from 999 municipalities)---a configuration in which the asymptotic cluster-robust | |
| 267 | +variance can be unreliable \citep{mackinnon2017wild}. We therefore also report a | |
| 268 | +pairs cluster bootstrap that resamples municipalities with replacement | |
| 269 | +($B=299$) and takes the 2.5th and 97.5th percentiles of the resampled coefficients | |
| 270 | +as a confidence interval. As a complement we compute heteroskedasticity-consistent | |
| 271 | +(HC3) standard errors \citep{white1980heteroskedasticity,mackinnon1985some}; | |
| 272 | +Section~\ref{subsec:robust} shows that the three approaches agree on the | |
| 273 | +significance of the property-level AI attributes and differ mainly for keyword | |
| 274 | +amenities with a strong spatial component. When RTA fixed effects replace | |
| 275 | +municipality effects, standard errors are clustered by RTA. | |
| 224 | 276 | |
| 225 | 277 | \paragraph{Retransformation.} |
| 226 | 278 | Predicting the \emph{level} of price requires undoing the log. Because |
@@ -239,3 +291,22 @@ generally Duan's nonparametric smearing estimate \citep{duan1983smearing}: | ||
| 239 | 291 | \underbrace{\frac1n\sum_{j=1}^{n} e^{\hat\varepsilon_j}}_{\text{smearing }\hat\phi}. |
| 240 | 292 | \label{eq:smearing} |
| 241 | 293 | \end{equation} |
| 294 | +% | |
| 295 | +The out-of-sample accuracy metrics of Section~\ref{sec:benchmark} are computed on | |
| 296 | +$\ln P$ (for $R^2$) and on the ratio of predicted to actual price (for the median | |
| 297 | +absolute percentage error), neither of which depends on the retransformation | |
| 298 | +constant. | |
| 299 | + | |
| 300 | +\paragraph{Out-of-sample validation.} | |
| 301 | +All predictive comparisons use five-fold cross-validation with a common seed, so that | |
| 302 | +every estimator and every feature set is evaluated on identical held-out folds. Under | |
| 303 | +\emph{random} folds a held-out house typically has close neighbours in the training | |
| 304 | +folds, which flatters any model that can exploit spatial proximity | |
| 305 | +\citep{roberts2017cross}. We therefore repeat the exercise with \emph{spatially | |
| 306 | +grouped} folds, assigning entire RTAs to folds so that no held-out listing shares | |
| 307 | +its RTA with a training listing; because many small municipalities consist of a | |
| 308 | +single RTA, their municipality indicator is then unobserved in training and the | |
| 309 | +model prices them at the reference level. The spatial design is a deliberately harsh | |
| 310 | +test of how the estimators and feature layers behave for a new area; the random | |
| 311 | +design corresponds to the operational use of an AVM that prices a new listing in a | |
| 312 | +market it already covers. | |
modified
paper/sections/results.tex
+89 −42
@@ -12,69 +12,83 @@ and vision-derived attributes). Model~A, which includes living area and is estim | ||
| 12 | 12 | on the 9{,}446 listings with a measured area, explains 75.5\% of the variation in log |
| 13 | 13 | prices ($R^2=0.755$, adjusted $0.748$). Model~B, the area-free specification estimated |
| 14 | 14 | on all 19{,}123 listings, explains 72.5\% ($R^2=0.725$, adjusted $0.721$). Adding the |
| 15 | −machine-generated feature layers raises Model~A's $R^2$ from 0.717 (structural, | |
| 16 | −amenity, room, and listing attributes only) to 0.725 with the text layer and 0.755 | |
| 17 | −with the vision layer---a cumulative gain of nearly four points from the two | |
| 18 | −AI-generated feature sets, over and above an already rich hedonic specification. | |
| 15 | +machine-generated feature layers in sequence raises Model~A's $R^2$ from 0.717 | |
| 16 | +(structural, amenity, room, and listing attributes only) to 0.725 with the text layer | |
| 17 | +and to 0.755 with the vision layer: 3.8 points in total, of which 0.8 come from the | |
| 18 | +text and 3.0 from the façade photograph. The text increment is small because the | |
| 19 | +fifteen keyword amenities already capture the most frequently mentioned features | |
| 20 | +(garage, pool, fireplace, air conditioning), so the LLM is credited only with what | |
| 21 | +keyword matching misses; Section~\ref{subsec:robust_leakage} shows that on | |
| 22 | +Realtor.ca, where the text contains no price, the increments are 0.65 and 2.4 | |
| 23 | +points. | |
| 19 | 24 | |
| 20 | 25 | The estimated implicit prices are economically sensible and, with few exceptions, |
| 21 | 26 | statistically significant with standard errors clustered by municipality. In |
| 22 | 27 | Model~A, the living-area elasticity is 0.36 (a 10\% larger home commands roughly a |
| 23 | −3.6\% higher price) and the lot-area elasticity is small but precisely estimated. | |
| 24 | −Each additional \textbf{bathroom} is associated with a 7.6\% premium and each parking | |
| 25 | −space with about 1\%. \textbf{Central air conditioning} carries a 5.5\% premium and | |
| 26 | −\textbf{public-transit} proximity 9.4\%, although the transit coefficient---like | |
| 27 | −other keyword amenities with a strong spatial component---is estimated much less | |
| 28 | −precisely once errors are allowed to correlate within municipalities. | |
| 29 | −\textbf{Waterfront} access is associated with a 6.0--6.4\% premium, significant at | |
| 30 | −conventional levels in the full-sample model. Age enters with a small negative linear | |
| 31 | −term and a positive quadratic, tracing the familiar depreciation-then-heritage | |
| 32 | −profile. | |
| 28 | +3.6\% higher price) and the lot-area elasticity is small (0.027) but precisely | |
| 29 | +estimated. Each additional \textbf{bathroom} is associated with a 7.6\% premium and | |
| 30 | +each parking space with about 1\%. \textbf{Central air conditioning} carries a 5.5\% | |
| 31 | +premium and \textbf{public-transit} proximity 9.4\%, although the transit | |
| 32 | +coefficient---like other keyword amenities with a strong spatial component---is | |
| 33 | +estimated much less precisely once errors are allowed to correlate within | |
| 34 | +municipalities. \textbf{Waterfront} access is associated with a 6.0--6.4\% premium, | |
| 35 | +significant at conventional levels in the full-sample model. Age enters with a | |
| 36 | +negative linear term ($-0.4$\% per year) and a small positive quadratic | |
| 37 | +($2.6\times10^{-5}$), so the price--age profile bottoms out at about 70 years and | |
| 38 | +rises for older, heritage-type houses. | |
| 33 | 39 | |
| 34 | 40 | \input{tables/regression} |
| 35 | 41 | |
| 36 | 42 | \subsection{Text- and Vision-Derived Attributes} |
| 37 | 43 | \label{subsec:ai_coeffs} |
| 38 | 44 | |
| 39 | −The two AI feature layers contribute distinct, largely orthogonal signal. | |
| 45 | +The two AI feature layers contribute distinct signal. | |
| 40 | 46 | |
| 41 | 47 | \paragraph{Text (LLM).} Beyond the keyword amenities, the structured specifications |
| 42 | 48 | carry independent information about finish and condition: a \textbf{renovated |
| 43 | 49 | kitchen} is associated with a 2.6\% premium, \textbf{hardwood flooring} with 2.4\%, |
| 44 | 50 | and the ordinal \textbf{condition} scale is positive and significant in both models |
| 45 | −(1.6\% per step). Listings the model reads as \textbf{income properties} sell about | |
| 46 | −1.9\% below otherwise-comparable houses. The \textbf{new-construction} indicator, | |
| 47 | −by contrast, is indistinguishable from zero once age, the visual renovation level, | |
| 48 | −and the condition scales are controlled for---the premium a naive specification | |
| 49 | −would attribute to the label ``new'' is fully absorbed by the measured quality | |
| 50 | −attributes. | |
| 51 | +(1.6\% per step). Listings the model reads as \textbf{income properties} are listed | |
| 52 | +about 1.9\% below otherwise comparable houses. The \textbf{new-construction} | |
| 53 | +indicator, by contrast, is indistinguishable from zero once age, the visual | |
| 54 | +renovation level, and the condition scales are controlled for: the premium a naive | |
| 55 | +specification would attribute to the label ``new'' is absorbed by the measured | |
| 56 | +quality attributes. | |
| 51 | 57 | |
| 52 | 58 | \paragraph{Vision (façade).} The image-derived attributes are jointly significant and |
| 53 | −add the largest single increment to fit. Holding all structural, amenity, and text | |
| 59 | +add the larger increment to fit. Holding all structural, amenity, and text | |
| 54 | 60 | attributes fixed, a one-point increase in \textbf{curb appeal} (1--10) is associated |
| 55 | 61 | with a 2.3\% higher price, and a one-step increase in the visual \textbf{renovation |
| 56 | 62 | level} with 2.4\%. A visible \textbf{luxury} cue adds 5.2\%, a \textbf{visible garage} |
| 57 | 63 | 4.7\%, and each step of \textbf{landscaping} quality 1.5\%. Exterior materials price |
| 58 | 64 | as expected: \textbf{brick} ($+3.4$\%) and \textbf{stone} ($+3.7$\%) command premia, |
| 59 | −while \textbf{vinyl} siding carries a 4.4\% discount. The visual \textbf{rural} | |
| 60 | −setting is associated with an 11.5\% discount relative to the omitted category. That | |
| 61 | −these visual measures remain significant after conditioning on the full text and | |
| 62 | −structural set---and with inference clustered at the municipality level---confirms | |
| 63 | −that the façade photograph carries price-relevant information available in no other | |
| 64 | −field. | |
| 65 | +while \textbf{vinyl} siding carries a 4.4\% discount; because a façade can combine | |
| 66 | +several materials, each indicator is measured relative to façades without that | |
| 67 | +material. The visual \textbf{rural} setting is associated with an 11.5\% discount | |
| 68 | +relative to the other settings even within municipalities, which indicates that the | |
| 69 | +model picks up within-municipality variation in density that the fixed effects | |
| 70 | +cannot. The visual condition score, by contrast, is not significant in Model~A once | |
| 71 | +curb appeal and the renovation level are included; the three scores are highly | |
| 72 | +collinear (the model rates condition, curb appeal and renovation level from the same | |
| 73 | +cues), and their individual coefficients should be read as a joint | |
| 74 | +``visual-quality'' block rather than as three separate prices. That these visual | |
| 75 | +measures remain significant after conditioning on the full text and structural set, | |
| 76 | +with inference clustered at the municipality level, indicates that the façade | |
| 77 | +photograph carries price-relevant information available in no other field. | |
| 65 | 78 | |
| 66 | 79 | \subsection{Validation of Machine-Generated Features} |
| 67 | 80 | \label{subsec:validation} |
| 68 | 81 | |
| 69 | −Before relying on the AI-generated attributes, we check that they order prices in the | |
| 70 | −expected direction. Figure~\ref{fig:validation} plots the median list price against the | |
| 71 | −vision model's curb-appeal and condition scores among listings with a detected | |
| 72 | −exterior shot. Both relationships are strongly monotone: median price rises steadily | |
| 73 | −from the lowest to the highest visual scores, with no reliance on the regression to | |
| 74 | −impose the pattern. Because these scores are produced by a model that never sees the | |
| 75 | −price, the monotonicity is independent evidence that the vision layer extracts a real, | |
| 76 | −price-relevant quality signal rather than noise. Table~\ref{tab:ai_summary} reports the | |
| 77 | −prevalence of the main text- and vision-derived attributes. | |
| 82 | +Before relying on the AI-generated attributes we assess them in two ways. First, we | |
| 83 | +check that the vision scores order prices in the expected direction. | |
| 84 | +Figure~\ref{fig:validation} plots the median list price against the vision model's | |
| 85 | +curb-appeal and condition scores among listings with a detected exterior shot. Both | |
| 86 | +relationships are monotone: median price rises from the lowest to the highest visual | |
| 87 | +scores, with no reliance on the regression to impose the pattern. Because these | |
| 88 | +scores are produced by a model that never sees the price, the monotonicity shows that | |
| 89 | +the vision layer extracts a price-correlated quality signal rather than noise; it | |
| 90 | +does not, of course, establish that the signal is \emph{quality} rather than, say, | |
| 91 | +the marketing budget of the seller (Section~\ref{subsec:limits}). | |
| 78 | 92 | |
| 79 | 93 | \begin{figure}[htbp] |
| 80 | 94 | \centering |
@@ -85,21 +99,54 @@ prevalence of the main text- and vision-derived attributes. | ||
| 85 | 99 | \label{fig:validation} |
| 86 | 100 | \end{figure} |
| 87 | 101 | |
| 102 | +Second, because we do not have human labels, we measure extraction error indirectly | |
| 103 | +by confronting the machine-generated attributes with independent sources | |
| 104 | +(Table~\ref{tab:agreement}). Where the LLM and the bilingual keyword rule read the | |
| 105 | +same text for the same binary feature, agreement is very high for concrete, | |
| 106 | +unambiguous amenities---garage (agreement 98\%, Cohen's $\kappa=0.96$), fireplace | |
| 107 | +($\kappa=0.91$), swimming pool ($\kappa=0.81$)---and lower for features whose | |
| 108 | +definition is fuzzy or whose keywords are ambiguous: central air conditioning | |
| 109 | +($\kappa=0.65$; the keyword rule also fires on ``air exchanger''), finished basement | |
| 110 | +($\kappa=0.56$; the keyword rule fires on any mention of ``basement''), and | |
| 111 | +waterfront ($\kappa=0.50$). For waterfront the LLM flags 22.5\% of listings against | |
| 112 | +9.2\% for the rule, with a recall of 98\% but a precision of only 40\% relative to the | |
| 113 | +rule, which suggests that the model treats water \emph{access} or \emph{views} as | |
| 114 | +waterfront; the regression includes both variables, and the keyword waterfront is the | |
| 115 | +one whose coefficient we report. Across modalities, the vision model's | |
| 116 | +visible-garage flag agrees with the text-based garage indicator for 68\% of exterior | |
| 117 | +shots ($\kappa=0.35$)---a garage need not be visible from the front---and its storey | |
| 118 | +count matches the structured storey field exactly for 60\% of listings and within | |
| 119 | +half a storey for 89\%. Two fields are clearly unreliable: the visual waterfront | |
| 120 | +setting ($\kappa=0.39$ against the keyword) and the visual building type, which | |
| 121 | +labels 12.7\% of façades as row houses when only 3.0\% of listings are townhouses | |
| 122 | +(precision 18\%) and 14.5\% as ``chalets.'' We accordingly use the visual building | |
| 123 | +type and setting only as controls and base no conclusion on them, and we read the | |
| 124 | +reported coefficients of the vision block as prices of \emph{what the model sees} | |
| 125 | +rather than of verified physical attributes. | |
| 126 | + | |
| 127 | +\input{tables/agreement} | |
| 128 | + | |
| 88 | 129 | \subsection{Location Fixed Effects} |
| 89 | 130 | \label{subsec:location} |
| 90 | 131 | |
| 91 | 132 | The 195 municipality fixed effects absorb the dominant locational component of price. |
| 92 | −Relative to the reference city, the largest positive premia are estimated for | |
| 93 | −\textbf{Westmount} ($\approx+231$\%), \textbf{Hampstead} ($+173$\%), and | |
| 94 | −\textbf{Mont-Royal} ($+169$\%), followed by outlying municipalities at the low end | |
| 133 | +Relative to the pooled group of small municipalities, the largest positive premia are | |
| 134 | +estimated for \textbf{Westmount} ($\approx+231$\%), \textbf{Hampstead} ($+173$\%), | |
| 135 | +and \textbf{Mont-Royal} ($+169$\%), followed by remote municipalities at the low end | |
| 95 | 136 | carrying discounts of 23--30\%. Figure~\ref{fig:premia} plots the extreme effects. The |
| 96 | 137 | magnitude and ordering align with well-known patterns in the Quebec housing market and |
| 97 | −lend face validity to the specification. | |
| 138 | +lend face validity to the specification; one apparent anomaly, | |
| 139 | +Sainte-Anne-des-Plaines ($+143$\%), is an artefact of the two-part design: only two | |
| 140 | +of that municipality's 33 listings report a living area and enter Model~A, one of | |
| 141 | +them a \$5.5~million estate on a 100-acre lot, so the effect is identified from two | |
| 142 | +observations. Municipality effects estimated on a single-date cross-section with | |
| 143 | +sparse cells should not be read as permanent location premia. | |
| 98 | 144 | |
| 99 | 145 | \begin{figure}[htbp] |
| 100 | 146 | \centering |
| 101 | 147 | \includegraphics[width=.74\textwidth]{figures/fig_premia.pdf} |
| 102 | 148 | \caption{Estimated municipality fixed effects (Model~A), the twelve largest and eight |
| 103 | − smallest, expressed as percentage premia relative to the reference city.} | |
| 149 | + smallest, expressed as percentage premia relative to the pooled group of | |
| 150 | + municipalities with fewer than 20 listings.} | |
| 104 | 151 | \label{fig:premia} |
| 105 | 152 | \end{figure} |
modified
paper/sections/robustness.tex
+178 −36
@@ -3,10 +3,10 @@ | ||
| 3 | 3 | \label{sec:robustness} |
| 4 | 4 | % ============================================================================ |
| 5 | 5 | |
| 6 | −\subsection{Robustness} | |
| 6 | +\subsection{Inference and Subsample Stability} | |
| 7 | 7 | \label{subsec:robust} |
| 8 | 8 | |
| 9 | −Several features of the design guard against spurious results. The dual | |
| 9 | +Several features of the design guard against spurious results. The two-part | |
| 10 | 10 | specification (Section~\ref{subsec:econometrics}) ensures that estimates are not |
| 11 | 11 | driven by the non-random availability of living area: coefficients on attributes |
| 12 | 12 | common to both models retain their sign and rough magnitude whether or not area is |
@@ -29,41 +29,155 @@ indicators), whereas keyword amenities with a strong spatial component lose | ||
| 29 | 29 | precision (public-transit proximity falls to the 5\% boundary in Model~A and is |
| 30 | 30 | insignificant in Model~B; central air conditioning is insignificant in Model~B; the |
| 31 | 31 | curb-appeal score, precisely estimated in Model~A, loses significance in the broader |
| 32 | −Model~B). | |
| 33 | −Heteroskedasticity-robust (HC3) standard errors | |
| 32 | +Model~B). Heteroskedasticity-robust (HC3) standard errors | |
| 34 | 33 | \citep{white1980heteroskedasticity,mackinnon1985some} yield the same qualitative |
| 35 | −pattern with uniformly smaller intervals. This asymmetry is reassuring for our main | |
| 36 | −claim: the AI-generated attributes capture within-market, property-level quality | |
| 37 | −variation rather than repackaged location effects. | |
| 34 | +pattern with uniformly smaller intervals. The last column of | |
| 35 | +Table~\ref{tab:rob_ai_coefs} reports 95\% intervals from a pairs cluster bootstrap | |
| 36 | +that resamples the 195 municipalities with replacement; they are wider than the | |
| 37 | +analytical ones, as expected with clusters of very unequal size | |
| 38 | +\citep{mackinnon2017wild}, and they exclude zero for curb appeal, the renovation | |
| 39 | +level, the luxury cue, the visible garage, brick, stone, vinyl, the rural setting, | |
| 40 | +the LLM condition scale, and the renovated kitchen; the intervals for landscaping and | |
| 41 | +hardwood flooring include zero by a small margin. This asymmetry between | |
| 42 | +property-level and location-level regressors supports our main claim: the | |
| 43 | +AI-generated attributes capture within-market, property-level quality variation | |
| 44 | +rather than repackaged location effects. | |
| 45 | + | |
| 46 | +\input{tables/rob_ai_coefs} | |
| 38 | 47 | |
| 39 | 48 | Table~\ref{tab:robustness} probes the stability of the predictive blend across |
| 40 | 49 | subsamples. Three patterns stand out. First, accuracy is comparable whether living |
| 41 | −area is observed (median error 13.5\%) or imputed (14.4\%), confirming that the | |
| 42 | −area-free model prices the incomplete listings almost as well as the rich model. | |
| 43 | −Second, the model fits the broker-listed Realtor.ca inventory better | |
| 44 | −($R^2_{\text{OOS}}=0.80$) than the smaller, noisier for-sale-by-owner DuProprio | |
| 45 | −segment (0.58), though median errors are identical at 14.0\%; the gap is consistent | |
| 46 | −with the compositional and marketing differences between brokered and FSBO | |
| 47 | −platforms documented by \citet{hendel2009mls}. Third, the median error is stable | |
| 48 | −across price terciles (11--16\%), lowest in the mid-market and modestly higher in | |
| 49 | −the tails, where idiosyncratic and luxury attributes are harder to capture. (Within | |
| 50 | −a single tercile $R^2$ is uninformative because the price range is restricted; the | |
| 51 | −median error is the comparable metric.) | |
| 50 | +area is observed (median error 13.5\%) or imputed (14.4\%), so the area-free model | |
| 51 | +prices the incomplete listings almost as well as the rich model. Second, the model | |
| 52 | +fits the broker-listed Realtor.ca inventory much better ($R^2_{\text{OOS}}=0.80$) | |
| 53 | +than the smaller for-sale-by-owner DuProprio segment (0.58), though median errors are | |
| 54 | +identical at 14.0\%; the gap is consistent with the compositional and marketing | |
| 55 | +differences between brokered and FSBO platforms documented by \citet{hendel2009mls}, | |
| 56 | +and with the absence of the room block for DuProprio listings. Third, the median | |
| 57 | +error is stable across price terciles (11--16\%), lowest in the mid-market and | |
| 58 | +modestly higher in the tails, where idiosyncratic and luxury attributes are harder | |
| 59 | +to capture. (Within a single tercile $R^2$ is uninformative because the price range | |
| 60 | +is restricted; the median error is the comparable metric.) | |
| 52 | 61 | |
| 53 | 62 | \input{tables/robustness} |
| 54 | 63 | |
| 64 | +\subsection{Language of the Description} | |
| 65 | +\label{subsec:robust_language} | |
| 66 | + | |
| 67 | +Section~\ref{subsec:text_content} showed that English-language listings are | |
| 68 | +substantially more expensive than French ones. Column~(2) of | |
| 69 | +Table~\ref{tab:rob_ai_coefs} adds the two language indicators and the description | |
| 70 | +length to Model~A. The English indicator is large and precisely estimated: an | |
| 71 | +English description is associated with a 7.2\% higher asking price conditional on | |
| 72 | +every structural, amenity, text, and vision attribute and on the municipality | |
| 73 | +(11.8\% in Model~B), and the mixed-language indicator with 4.6\%. We read this as a | |
| 74 | +location and clientele effect within municipalities---English listings cluster in the | |
| 75 | +most expensive parts of large municipalities such as Montreal, and brokers write in | |
| 76 | +the language of the clientele they target---rather than as a price of the language | |
| 77 | +itself. What matters for our purpose is that the AI-derived implicit prices are | |
| 78 | +unchanged to the third decimal when language is controlled for: curb appeal moves | |
| 79 | +from 0.023 to 0.022, the luxury cue stays at 0.051, brick at 0.032--0.033, vinyl | |
| 80 | +at $-0.044$, and the LLM condition and kitchen coefficients at 0.017 and 0.025. The | |
| 81 | +language indicators also leave the explanatory gain of the AI layers intact | |
| 82 | +(Panel~A of Table~\ref{tab:rob_language_source}: 0.719 $\to$ 0.727 $\to$ 0.757 with | |
| 83 | +language controls, against 0.717 $\to$ 0.725 $\to$ 0.755 without). | |
| 84 | + | |
| 85 | +The gains are present within each language group. Re-estimating the nested ablation | |
| 86 | +of Model~A separately on French and English descriptions | |
| 87 | +(Table~\ref{tab:rob_language_source}, Panel~A), the text layer adds 1.5 points of | |
| 88 | +$R^2$ for French listings and 0.6 for English ones, and the vision layer 3.4 and | |
| 89 | +2.2 points; out of sample, gradient boosting gains 1.5 points from the text in both | |
| 90 | +groups and 3.1 and 2.6 from vision (Panel~C). The smaller text gain | |
| 91 | +for English listings is consistent with a specification that already fits English | |
| 92 | +listings better (base $R^2$ of 0.763 against 0.704), so that less is left for the | |
| 93 | +text to explain, rather than with a weaker extraction in English. Adding the | |
| 94 | +language indicators to the gradient-boosting feature set raises its out-of-sample | |
| 95 | +$R^2$ from 0.770 to 0.774, a modest gain that confirms language is informative but | |
| 96 | +largely redundant with location and the other attributes. | |
| 97 | + | |
| 98 | +\input{tables/rob_language_source} | |
| 99 | + | |
| 100 | +\subsection{Information Leakage Through the Text} | |
| 101 | +\label{subsec:robust_leakage} | |
| 102 | + | |
| 103 | +Because every DuProprio description contains the asking price, the clean test of | |
| 104 | +the text layer is the Realtor.ca subsample. The contrast in Panel~A of | |
| 105 | +Table~\ref{tab:rob_language_source} is stark. On Realtor.ca listings the text layer | |
| 106 | +adds 0.6 points of in-sample $R^2$ to Model~A and the vision layer 2.4 points; on | |
| 107 | +DuProprio listings the increments are 3.3 and 4.1 points. Out of sample | |
| 108 | +(Panel~C), gradient boosting gains 1.2 points from the text on Realtor.ca and 3.1 | |
| 109 | +on DuProprio. Three remarks temper the comparison. First, the DuProprio base is much | |
| 110 | +weaker (in-sample $R^2$ of 0.564 against 0.779) because the room block is missing, | |
| 111 | +so every additional block has more left to explain there; the vision layer, which | |
| 112 | +never sees any text, also gains more on DuProprio (4.1 against 2.4 points), and the | |
| 113 | +ratio of the DuProprio to the Realtor.ca gain is about 1.7 for vision against 5 for | |
| 114 | +text. Second, the DuProprio ``description'' also embeds structured fields (cladding, | |
| 115 | +heating, inclusions) that the LLM can read verbatim and that are genuinely | |
| 116 | +informative, so part of the excess text gain is legitimate. Third, the asking price | |
| 117 | +itself cannot be reproduced by any field of the schema; what the price can do is tilt | |
| 118 | +the model's reading of ambiguous fields (condition, turnkey, luxury-type highlights) | |
| 119 | +towards the expensive or the cheap end. We cannot separate these channels without | |
| 120 | +re-running the extraction on descriptions purged of the price, which we recommend as | |
| 121 | +the first step of any replication and which the archived raw text makes possible | |
| 122 | +at a cost of about \$1. Until then, we regard the Realtor.ca increments---0.6 points | |
| 123 | +of in-sample $R^2$ and 0.6 (OLS) to 1.2 (gradient boosting) points out of sample for | |
| 124 | +the text layer---as the credible estimate of what the LLM specifications add beyond | |
| 125 | +keyword amenities, and we note that none of the paper's conclusions about the | |
| 126 | +vision layer is affected, since the vision model is exposed neither to the text nor | |
| 127 | +to the price. Column~(4) of Table~\ref{tab:rob_ai_coefs} re-estimates Model~A on | |
| 128 | +Realtor.ca listings alone with RTA fixed effects and language controls: curb appeal | |
| 129 | +(0.021), the renovation level (0.041), the luxury cue (0.042), the visible garage | |
| 130 | +(0.041), stone ($0.030$), vinyl ($-0.051$), landscaping (0.027), and the renovated | |
| 131 | +kitchen (0.030) retain their magnitude and significance, whereas brick, the rural | |
| 132 | +setting, the LLM condition scale, and hardwood flooring keep their sign but lose | |
| 133 | +significance in this smaller sample of 5{,}781 listings. | |
| 134 | + | |
| 135 | +\subsection{Finer Location Controls and Spatial Validation} | |
| 136 | +\label{subsec:robust_spatial} | |
| 137 | + | |
| 138 | +Municipalities are coarse spatial units: Montreal, Quebec City, Laval, and Gatineau | |
| 139 | +each contain neighbourhoods whose price levels differ by a factor of two or more. | |
| 140 | +Column~(3) of Table~\ref{tab:rob_ai_coefs} replaces the 195 municipality effects by | |
| 141 | +250 RTA effects. In-sample fit improves (Model~A $R^2$ from 0.755 to 0.764, | |
| 142 | +Model~B from 0.725 to 0.726), and the AI coefficients are stable: curb appeal 0.016, | |
| 143 | +renovation level 0.029, luxury 0.045, garage 0.037, brick 0.031, stone 0.037, vinyl | |
| 144 | +$-0.047$, rural $-0.122$, LLM condition 0.015, renovated kitchen 0.019, hardwood | |
| 145 | +0.016, all significant at the 5\% level with standard errors clustered by RTA. The | |
| 146 | +in-sample increments from the two AI layers under RTA effects are 0.7 and 3.2 | |
| 147 | +points (Table~\ref{tab:rob_language_source}, last row of Panel~A). Finer location | |
| 148 | +controls therefore do not absorb the AI-measured quality, which is what one expects | |
| 149 | +if the layers measure property-level rather than neighbourhood-level attributes. | |
| 150 | + | |
| 151 | +Random cross-validation folds let every held-out listing borrow strength from | |
| 152 | +neighbours in the training folds. Table~\ref{tab:rob_spatial} repeats the nested | |
| 153 | +ablation with folds formed by RTA, so that an entire postal area is predicted from a | |
| 154 | +model that has never seen it. All levels fall, as they must: the full | |
| 155 | +text\,$+$\,vision OLS drops from 0.686 to 0.638 and gradient boosting from 0.770 | |
| 156 | +to 0.734, with median absolute errors rising by about 1.5 percentage points. The | |
| 157 | +increments from the AI layers, however, are preserved almost exactly---the text layer | |
| 158 | +adds 0.7 (OLS) and 1.3 (gradient boosting) points under spatial folds against 0.9 | |
| 159 | +and 1.4 under random folds, and the vision layer 7.0 and 3.1 points against 5.8 and | |
| 160 | +2.7. If anything, the vision layer is \emph{more} valuable when location is poorly | |
| 161 | +measured, which is consistent with the façade carrying information about the | |
| 162 | +neighbourhood (density, setting, housing vintage) as well as about the house. We | |
| 163 | +regard the random-fold numbers as the relevant ones for an AVM operating within its | |
| 164 | +coverage area, and the spatial-fold numbers as the relevant ones for extrapolation to | |
| 165 | +new areas. | |
| 166 | + | |
| 167 | +\input{tables/rob_spatial} | |
| 168 | + | |
| 55 | 169 | \subsection{Limitations} |
| 56 | 170 | \label{subsec:limits} |
| 57 | 171 | |
| 58 | −Five limitations qualify the interpretation of our estimates. | |
| 172 | +Seven limitations qualify the interpretation of our estimates. | |
| 59 | 173 | |
| 60 | 174 | \emph{Asking prices.} The dependent variable is the asking price of properties |
| 61 | 175 | listed for sale, not the transaction price. The list price is a strategic choice |
| 62 | 176 | that anchors buyer search and bargaining |
| 63 | −\citep{horowitz1992list,knight2002listing,han2015microstructure}: it is set with | |
| 64 | −sale in mind and is highly correlated with the eventual transaction price, but | |
| 65 | −list-to-sale ratios vary systematically with market conditions and overpricing is | |
| 66 | −more common in thin segments. Two implications follow. First, our implicit prices | |
| 177 | +\citep{horowitz1992list,knight2002listing,han2015microstructure,han2016asking}: it is | |
| 178 | +set with sale in mind and is highly correlated with the eventual transaction price, | |
| 179 | +but list-to-sale ratios vary systematically with market conditions and overpricing | |
| 180 | +is more common in thin segments. Two implications follow. First, our implicit prices | |
| 67 | 181 | measure how sellers and their agents \emph{price} attributes into the ask, which |
| 68 | 182 | converges to buyers' valuation only insofar as the market disciplines the ask; the |
| 69 | 183 | economically sensible magnitudes and the monotone validation of |
@@ -72,28 +186,56 @@ attribute that shifts the list-to-sale ratio itself (e.g., attributes of hard-to | ||
| 72 | 186 | properties) will carry a coefficient that mixes valuation and listing strategy. |
| 73 | 187 | Replicating the analysis on registry transaction prices is the natural next step. |
| 74 | 188 | |
| 189 | +\emph{Price in the text.} For the 19.7\% of listings from DuProprio, the language | |
| 190 | +model read the asking price as part of the description. The text-layer gains on | |
| 191 | +that platform are therefore an upper bound, and the Realtor.ca gains the credible | |
| 192 | +estimate (Section~\ref{subsec:robust_leakage}). The vision layer is unaffected. | |
| 193 | + | |
| 75 | 194 | \emph{Non-causality and content endogeneity.} Descriptions and photographs are |
| 76 | 195 | marketing instruments chosen by sellers and agents. Richer descriptions, more |
| 77 | 196 | photographs, and higher visual quality correlate with higher-end listing agents and |
| 78 | 197 | more valuable properties \citep{nowak2017textual}. The coefficients are therefore |
| 79 | 198 | \emph{predictive} associations, not causal effects; they should not be read as the |
| 80 | 199 | price change from physically adding a given attribute. We control for two observable |
| 81 | −dimensions of marketing effort (photo count and virtual tours), but cannot rule out | |
| 82 | −that residual marketing quality loads on the AI-derived attributes. | |
| 200 | +dimensions of marketing effort (photo count and virtual tours) and for the photo | |
| 201 | +quality score, but cannot rule out that residual marketing quality loads on the | |
| 202 | +AI-derived attributes, and the three visual quality scores are collinear enough that | |
| 203 | +only their joint contribution is well identified. | |
| 204 | + | |
| 205 | +\emph{Machine-generated features and their reproducibility.} LLM and vision outputs | |
| 206 | +contain errors. Strict schemas and closed enumerations bound the \emph{form} of the | |
| 207 | +output but not its accuracy, and the agreement analysis of | |
| 208 | +Section~\ref{subsec:validation} shows that accuracy varies widely across fields: | |
| 209 | +high for concrete amenities, low for waterfront, the visual setting, and the visual | |
| 210 | +building type. We have no human-labelled validation set; a few hundred manually | |
| 211 | +coded listings would allow field-level precision and recall against ground truth | |
| 212 | +and are the obvious next step. Classical measurement error in the extracted scores | |
| 213 | +biases their coefficients towards zero, which makes our implicit prices | |
| 214 | +conservative, but errors correlated with price (through the leakage channel above, | |
| 215 | +or because the model rates expensive-looking houses more generously on every | |
| 216 | +dimension) need not. The text extraction ran at temperature zero, the vision | |
| 217 | +extraction at the API default temperature, and both model identifiers are provider | |
| 218 | +aliases rather than pinned snapshots; the raw outputs are archived, so the | |
| 219 | +regressors are exactly reproducible from them, but a fresh extraction with a later | |
| 220 | +model version could return different scores, and we have not measured test--retest | |
| 221 | +variability. The vision layer judges each property from a single façade photograph | |
| 222 | +and ignores interiors. | |
| 83 | 223 | |
| 84 | −\emph{Machine-generated features.} LLM and vision outputs can contain errors. | |
| 85 | −Zero-temperature decoding, strict schemas, and closed enumerations bound this risk | |
| 86 | −and make it reproducible, and classical measurement error in the extracted scores | |
| 87 | −would bias their coefficients toward zero---making our estimates conservative---but | |
| 88 | −we do not perform systematic human validation, and the visual layer judges each | |
| 89 | −property from a single façade photograph, ignoring interiors. | |
| 224 | +\emph{Language.} The LLM processes French and English descriptions with the same | |
| 225 | +French-language instruction and schema. We find no evidence that the extraction is | |
| 226 | +weaker in either language and the implicit prices are robust to language controls, | |
| 227 | +but the English indicator itself carries a large conditional premium that we can | |
| 228 | +interpret only as a proxy for unobserved location and clientele. | |
| 90 | 229 | |
| 91 | 230 | \emph{Selection.} Listed properties are not a random sample of the housing stock, |
| 92 | 231 | and listings with missing area or room detail are not missing at random (they tend |
| 93 | −to be less complete listings). The ``\texttt{has\_}'' indicators and the two-part | |
| 94 | −design mitigate, but do not eliminate, the second concern. | |
| 232 | +to be less complete listings, and all DuProprio listings lack the room block). The | |
| 233 | +``\texttt{has\_}'' indicators and the two-part design mitigate, but do not eliminate, | |
| 234 | +the second concern, and the markedly worse fit for DuProprio shows that the pooled | |
| 235 | +model is not equally adequate on both platforms. | |
| 95 | 236 | |
| 96 | 237 | \emph{Cross-section.} The data are a single-date snapshot, so the model captures no |
| 97 | −market dynamics and the location premia are fixed as of 3~July~2026. Municipalities | |
| 98 | −with fewer than 20 listings are pooled, reducing spatial resolution where data are | |
| 99 | −sparse. | |
| 238 | +market dynamics, no forward-in-time holdout is possible, and the location premia are | |
| 239 | +fixed as of 3~July~2026. Municipalities with fewer than 20 listings are pooled, | |
| 240 | +reducing spatial resolution where data are sparse, and some municipality effects in | |
| 241 | +Model~A rest on very few observations (Section~\ref{subsec:location}). | |
modified
paper/tables/ablation.tex
+3 −1
@@ -21,7 +21,9 @@ | ||
| 21 | 21 | with a common seed. ``\# feats'' counts numeric/indicator features before the city, |
| 22 | 22 | type, and source fixed effects (added in every specification). The blend averages |
| 23 | 23 | the robust neural network and gradient boosting and is reported where both were |
| 24 | − trained. GBM handles missing living area natively; OLS uses median imputation. | |
| 24 | + trained. GBM handles missing living area natively; OLS uses within-type median imputation. | |
| 25 | + The gain from a layer is the difference between consecutive rows; the room and listing | |
| 26 | + block includes the Realtor.ca room detail and therefore also carries platform identity. | |
| 25 | 27 | \end{tablenotes} |
| 26 | 28 | \end{threeparttable} |
| 27 | 29 | \end{table} |
added
paper/tables/agreement.tex
+37 −0
@@ -0,0 +1,37 @@ | ||
| 1 | +% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 2 | +\begin{table}[htbp] | |
| 3 | + \centering | |
| 4 | + \begin{threeparttable} | |
| 5 | + \caption{Agreement Between Machine-Generated Attributes and Independent Sources} | |
| 6 | + \label{tab:agreement} | |
| 7 | + \footnotesize | |
| 8 | + \setlength{\tabcolsep}{3.5pt} | |
| 9 | + \begin{tabular}{@{}lccccccc@{}} | |
| 10 | + \toprule | |
| 11 | + Attribute & $N$ & Share (AI) & Share (ref.) & Agreement & $\kappa$ & Precision & Recall \\ | |
| 12 | + \midrule | |
| 13 | + \multicolumn{8}{@{}l}{\textit{Panel A: LLM text layer vs.\ bilingual keyword rule on the same text}} \\[2pt] | |
| 14 | + Garage & 19{,}123 & 40.8\% & 41.0\% & 98.2\% & 0.96 & 98.0\% & 97.6\% \\ | |
| 15 | + Swimming pool & 19{,}123 & 17.9\% & 23.9\% & 93.5\% & 0.81 & 98.8\% & 73.9\% \\ | |
| 16 | + Waterfront & 19{,}123 & 22.5\% & 9.2\% & 86.2\% & 0.50 & 39.8\% & 97.7\% \\ | |
| 17 | + Fireplace & 19{,}123 & 21.9\% & 23.6\% & 96.7\% & 0.91 & 96.3\% & 89.4\% \\ | |
| 18 | + Central A/C or heat pump & 19{,}123 & 11.5\% & 18.9\% & 90.8\% & 0.65 & 92.5\% & 56.0\% \\ | |
| 19 | + Finished basement & 19{,}123 & 35.5\% & 31.9\% & 80.5\% & 0.56 & 67.5\% & 75.0\% \\ | |
| 20 | + \addlinespace | |
| 21 | + \multicolumn{8}{@{}l}{\textit{Panel B: Façade vision layer vs.\ text or structured fields (exterior shots only)}} \\[2pt] | |
| 22 | + Garage visible vs.\ garage (LLM) & 18{,}314 & 47.5\% & 41.0\% & 67.6\% & 0.35 & 59.0\% & 68.4\% \\ | |
| 23 | + Garage visible vs.\ garage (keyword) & 18{,}314 & 47.5\% & 41.1\% & 67.4\% & 0.34 & 59.0\% & 68.1\% \\ | |
| 24 | + Waterfront setting vs.\ waterfront (keyword) & 18{,}314 & 6.5\% & 9.1\% & 91.1\% & 0.39 & 51.7\% & 37.2\% \\ | |
| 25 | + Row house vs.\ townhouse (listing type) & 18{,}314 & 12.7\% & 3.0\% & 89.0\% & 0.26 & 18.5\% & 79.0\% \\ | |
| 26 | + \bottomrule | |
| 27 | + \end{tabular} | |
| 28 | + \begin{tablenotes}[flushleft] | |
| 29 | + \footnotesize | |
| 30 | + \item \textit{Notes:} ``Share (AI)'' is the prevalence of the attribute according to the AI layer, ``Share (ref.)'' | |
| 31 | + according to the reference source; ``Agreement'' is the share of listings on which the two coincide, $\kappa$ is | |
| 32 | + Cohen's kappa, and precision and recall treat the reference as ground truth (it is not: keyword rules miss | |
| 33 | + negations and synonyms, and a garage need not be visible on the façade photograph). Visual storey count agrees | |
| 34 | + exactly with the structured storey field for 60.5\% of 18{,}065 listings and within half a storey for 88.7\%. | |
| 35 | + \end{tablenotes} | |
| 36 | + \end{threeparttable} | |
| 37 | +\end{table} | |
modified
paper/tables/models.tex
+5 −3
@@ -29,11 +29,13 @@ | ||
| 29 | 29 | common seed (identical folds across rows). $R^2_{\text{OOS}}$ is on |
| 30 | 30 | $\ln(\text{Price})$; ``Median AE'' is the median absolute percentage error in |
| 31 | 31 | levels (Equation~\ref{eq:cvmetrics}). Panel~A uses structural, amenity, room-detail, |
| 32 | − listing-signal, and LLM text-derived features; Panel~B adds the twelve façade | |
| 33 | − vision attributes. City, type, and source enter as one-hot indicators for the | |
| 32 | + listing-signal, and LLM text-derived features; Panel~B adds the façade | |
| 33 | + vision layer (21 regressors derived from the twelve schema fields). City, type, and source enter as one-hot indicators for the | |
| 34 | 34 | linear and tree models and as learned embeddings for the neural networks. The tree |
| 35 | 35 | and neural models handle missing living area natively; OLS uses within-type median |
| 36 | − imputation. The best model is the text\,+\,vision blend. | |
| 36 | + imputation. The blend weights the two models equally (weight fixed a priori). The best | |
| 37 | + model is the text\,+\,vision blend. Entries may differ by $\pm0.001$ from | |
| 38 | + Tables~\ref{tab:ablation} and~\ref{tab:rob_spatial}, which come from separate runs. | |
| 37 | 39 | \end{tablenotes} |
| 38 | 40 | \end{threeparttable} |
| 39 | 41 | \end{table} |
added
paper/tables/rob_ai_coefs.tex
+62 −0
@@ -0,0 +1,62 @@ | ||
| 1 | +% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 2 | +\begin{table}[htbp] | |
| 3 | + \centering | |
| 4 | + \begin{threeparttable} | |
| 5 | + \caption{Robustness of the AI-Derived Implicit Prices (Model~A)} | |
| 6 | + \label{tab:rob_ai_coefs} | |
| 7 | + \footnotesize | |
| 8 | + \setlength{\tabcolsep}{4pt} | |
| 9 | + \begin{tabular}{@{}lccccc@{}} | |
| 10 | + \toprule | |
| 11 | + & (1) & (2) & (3) & (4) & (5) \\ | |
| 12 | + & Baseline & $+$Language & RTA FE & Realtor.ca only & Cluster bootstrap \\ | |
| 13 | + & & & $+$Language & RTA FE $+$Lang. & 95\% CI \\ | |
| 14 | + \midrule | |
| 15 | + Curb appeal (1--10) & 0.023$^{***}$ & 0.022$^{**}$ & 0.016$^{***}$ & 0.021$^{**}$ & [$0.001$, $0.035$] \\ | |
| 16 | + & (0.009) & (0.009) & (0.006) & (0.010) & \\[2pt] | |
| 17 | + Renovation level (ord.) & 0.024$^{**}$ & 0.024$^{***}$ & 0.029$^{***}$ & 0.041$^{**}$ & [$0.010$, $0.046$] \\ | |
| 18 | + & (0.010) & (0.009) & (0.009) & (0.018) & \\[2pt] | |
| 19 | + Luxury (visual) & 0.051$^{***}$ & 0.051$^{***}$ & 0.045$^{***}$ & 0.042$^{***}$ & [$0.019$, $0.066$] \\ | |
| 20 | + & (0.012) & (0.012) & (0.010) & (0.015) & \\[2pt] | |
| 21 | + Garage visible & 0.046$^{***}$ & 0.046$^{***}$ & 0.037$^{***}$ & 0.041$^{***}$ & [$0.029$, $0.055$] \\ | |
| 22 | + & (0.006) & (0.006) & (0.006) & (0.009) & \\[2pt] | |
| 23 | + Brick façade & 0.033$^{***}$ & 0.032$^{***}$ & 0.031$^{***}$ & 0.024 & [$0.001$, $0.044$] \\ | |
| 24 | + & (0.009) & (0.009) & (0.010) & (0.017) & \\[2pt] | |
| 25 | + Stone façade & 0.036$^{***}$ & 0.037$^{***}$ & 0.037$^{***}$ & 0.030$^{***}$ & [$0.022$, $0.049$] \\ | |
| 26 | + & (0.008) & (0.008) & (0.009) & (0.010) & \\[2pt] | |
| 27 | + Vinyl façade & $-$0.045$^{***}$ & $-$0.044$^{***}$ & $-$0.047$^{***}$ & $-$0.051$^{**}$ & [$-0.067$, $-0.007$] \\ | |
| 28 | + & (0.015) & (0.015) & (0.018) & (0.021) & \\[2pt] | |
| 29 | + Rural setting & $-$0.122$^{***}$ & $-$0.120$^{***}$ & $-$0.122$^{***}$ & $-$0.119 & [$-0.176$, $-0.029$] \\ | |
| 30 | + & (0.032) & (0.033) & (0.042) & (0.087) & \\[2pt] | |
| 31 | + Landscaping (ord.) & 0.015$^{**}$ & 0.015$^{**}$ & 0.013$^{**}$ & 0.027$^{***}$ & [$-0.000$, $0.025$] \\ | |
| 32 | + & (0.006) & (0.006) & (0.006) & (0.007) & \\[2pt] | |
| 33 | + Condition (LLM, ord.) & 0.016$^{***}$ & 0.017$^{***}$ & 0.015$^{***}$ & 0.012 & [$0.002$, $0.024$] \\ | |
| 34 | + & (0.006) & (0.006) & (0.005) & (0.009) & \\[2pt] | |
| 35 | + Reno.\ kitchen (LLM) & 0.026$^{***}$ & 0.025$^{***}$ & 0.019$^{**}$ & 0.030$^{**}$ & [$0.010$, $0.039$] \\ | |
| 36 | + & (0.007) & (0.007) & (0.009) & (0.012) & \\[2pt] | |
| 37 | + Hardwood floor (LLM) & 0.024$^{**}$ & 0.026$^{***}$ & 0.016$^{**}$ & $-$0.001 & [$-0.003$, $0.036$] \\ | |
| 38 | + & (0.009) & (0.009) & (0.007) & (0.013) & \\[2pt] | |
| 39 | + English description & & 0.070$^{***}$ & 0.090$^{***}$ & 0.082$^{**}$ & \\ | |
| 40 | + & & (0.011) & (0.034) & (0.042) & \\[2pt] | |
| 41 | + Mixed-language description & & 0.045$^{***}$ & 0.067$^{**}$ & 0.181$^{***}$ & \\ | |
| 42 | + & & (0.011) & (0.030) & (0.042) & \\[2pt] | |
| 43 | + \midrule | |
| 44 | + Fixed effects & Municipality & Municipality & RTA & RTA & Municipality \\ | |
| 45 | + Observations & 9{,}446 & 9{,}446 & 9{,}446 & 5{,}781 & 9{,}446 \\ | |
| 46 | + $R^2$ & 0.755 & 0.757 & 0.764 & 0.802 & \\ | |
| 47 | + \bottomrule | |
| 48 | + \end{tabular} | |
| 49 | + \begin{tablenotes}[flushleft] | |
| 50 | + \footnotesize | |
| 51 | + \item \textit{Notes:} OLS estimates of Equation~\eqref{eq:hedonic} on the measured-area subsample with the full | |
| 52 | + control set (coefficients of the controls not shown). Column~(1) is the baseline of Table~\ref{tab:regression}. | |
| 53 | + Column~(2) adds indicators for English and mixed-language descriptions and the description length (thousands of | |
| 54 | + characters). Column~(3) replaces the 195 municipality fixed effects by 250 forward-sortation-area (RTA) fixed | |
| 55 | + effects (RTAs with at least 20 listings; the remainder pooled). Column~(4) restricts the sample to Realtor.ca | |
| 56 | + listings, whose descriptions never contain the asking price. Standard errors in parentheses are clustered at the | |
| 57 | + level of the fixed effects. Column~(5) reports the 2.5th and 97.5th percentiles of a pairs cluster bootstrap | |
| 58 | + (299 replications, resampling the 195 municipalities with replacement) for the baseline | |
| 59 | + specification. $^{***}$, $^{**}$, $^{*}$: significance at 1\%, 5\%, 10\%. | |
| 60 | + \end{tablenotes} | |
| 61 | + \end{threeparttable} | |
| 62 | +\end{table} | |
added
paper/tables/rob_language_source.tex
+52 −0
@@ -0,0 +1,52 @@ | ||
| 1 | +% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 2 | +\begin{table}[htbp] | |
| 3 | + \centering | |
| 4 | + \begin{threeparttable} | |
| 5 | + \caption{Gains from the AI Feature Layers by Language, Platform, and Presence of a Price in the Text} | |
| 6 | + \label{tab:rob_language_source} | |
| 7 | + \small | |
| 8 | + \begin{tabular}{@{}lcccc@{}} | |
| 9 | + \toprule | |
| 10 | + Subsample & $N$ & $R^2$ base & $\Delta R^2$ text (pp) & $\Delta R^2$ vision (pp) \\ | |
| 11 | + \midrule | |
| 12 | + \multicolumn{5}{@{}l}{\textit{Panel A: In-sample $R^2$, Model~A (measured area), municipality FE}} \\[2pt] | |
| 13 | + All listings & 9{,}446 & 0.717 & +0.8 & +3.0 \\ | |
| 14 | + \quad French descriptions & 2{,}619 & 0.704 & +1.5 & +3.4 \\ | |
| 15 | + \quad English descriptions & 4{,}815 & 0.763 & +0.6 & +2.2 \\ | |
| 16 | + \quad Mixed / bilingual & 2{,}012 & 0.579 & +3.2 & +4.8 \\ | |
| 17 | + \quad Realtor.ca (no asking price in text) & 5{,}781 & 0.779 & +0.6 & +2.4 \\ | |
| 18 | + \quad DuProprio (asking price in text) & 3{,}665 & 0.564 & +3.3 & +4.1 \\ | |
| 19 | + \quad Realtor.ca, no dollar amount in text & 5{,}640 & 0.780 & +0.6 & +2.4 \\ | |
| 20 | + All listings, RTA fixed effects & 9{,}446 & 0.722 & +0.7 & +3.2 \\ | |
| 21 | + \addlinespace | |
| 22 | + \multicolumn{5}{@{}l}{\textit{Panel B: Out-of-sample $R^2$ (5-fold, random), OLS, full sample}} \\[2pt] | |
| 23 | + All listings & 19{,}123 & 0.619 & +0.8 & +5.8 \\ | |
| 24 | + \quad French & 8{,}529 & 0.622 & +1.2 & +4.8 \\ | |
| 25 | + \quad English & 8{,}250 & 0.562 & +0.7 & +7.9 \\ | |
| 26 | + \quad Realtor.ca & 15{,}356 & 0.701 & +0.6 & +3.9 \\ | |
| 27 | + \quad DuProprio & 3{,}767 & $-0.083$ & +2.8 & +22.8 \\ | |
| 28 | + \addlinespace | |
| 29 | + \multicolumn{5}{@{}l}{\textit{Panel C: Out-of-sample $R^2$ (5-fold, random), gradient boosting, full sample}} \\[2pt] | |
| 30 | + All listings & 19{,}123 & 0.729 & +1.4 & +2.7 \\ | |
| 31 | + \quad French & 8{,}529 & 0.680 & +1.5 & +3.1 \\ | |
| 32 | + \quad English & 8{,}250 & 0.737 & +1.5 & +2.6 \\ | |
| 33 | + \quad Realtor.ca & 15{,}356 & 0.748 & +1.2 & +2.6 \\ | |
| 34 | + \quad DuProprio & 3{,}767 & 0.564 & +3.1 & +2.8 \\ | |
| 35 | + \bottomrule | |
| 36 | + \end{tabular} | |
| 37 | + \begin{tablenotes}[flushleft] | |
| 38 | + \footnotesize | |
| 39 | + \item \textit{Notes:} Panel~A re-estimates the nested in-sample ablation of Model~A (structural, amenity, room, and | |
| 40 | + listing controls with municipality and type fixed effects; then $+$ LLM text layer; then $+$ façade vision layer) on | |
| 41 | + each subsample; ``$\Delta R^2$'' is the gain, in percentage points, from adding the layer. Language is classified | |
| 42 | + from French and English stop-word counts (ratio rule of 1.5; ``mixed'' listings are mostly DuProprio descriptions that | |
| 43 | + concatenate an English translation and the French original). Every DuProprio description contains the asking price | |
| 44 | + (``Asking Price \$\dots''); 2.5\% of Realtor.ca | |
| 45 | + descriptions contain some dollar amount (usually a municipal assessment, a renovation budget, or a tax; the 141 | |
| 46 | + Model~A listings concerned are too few for a separate regression). Panels~B and | |
| 47 | + C evaluate the full-sample cross-validated predictions (Table~\ref{tab:ablation}, identical folds) within each | |
| 48 | + subsample; the base is the structural $+$ amenity $+$ rooms $+$ listing specification. Within-subsample $R^2$ | |
| 49 | + values can be negative (DuProprio, OLS) when the pooled model is miscalibrated for the subsample. | |
| 50 | + \end{tablenotes} | |
| 51 | + \end{threeparttable} | |
| 52 | +\end{table} | |
added
paper/tables/rob_spatial.tex
+29 −0
@@ -0,0 +1,29 @@ | ||
| 1 | +% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 2 | +\begin{table}[htbp] | |
| 3 | + \centering | |
| 4 | + \begin{threeparttable} | |
| 5 | + \caption{Random versus Spatial (RTA-Grouped) Cross-Validation} | |
| 6 | + \label{tab:rob_spatial} | |
| 7 | + \small | |
| 8 | + \begin{tabular}{@{}lcccc@{\hskip 0.8cm}cccc@{}} | |
| 9 | + \toprule | |
| 10 | + & \multicolumn{4}{c}{Random 5-fold} & \multicolumn{4}{c}{Spatial 5-fold (RTA groups)} \\ | |
| 11 | + \cmidrule(lr){2-5}\cmidrule(lr){6-9} | |
| 12 | + Estimator & Base & $+$Text & $+$Vision & MdAPE & Base & $+$Text & $+$Vision & MdAPE \\ | |
| 13 | + \midrule | |
| 14 | + OLS (linear hedonic) & 0.619 & 0.628 & 0.686 & 16.9\% & 0.561 & 0.568 & 0.638 & 18.5\% \\ | |
| 15 | + Gradient boosting & 0.729 & 0.743 & 0.770 & 14.5\% & 0.690 & 0.703 & 0.734 & 15.9\% \\ | |
| 16 | + \bottomrule | |
| 17 | + \end{tabular} | |
| 18 | + \begin{tablenotes}[flushleft] | |
| 19 | + \footnotesize | |
| 20 | + \item \textit{Notes:} Out-of-sample $R^2$ on $\ln(\text{Price})$ and median absolute percentage error (MdAPE, for the | |
| 21 | + full text\,$+$\,vision specification). ``Base'' is the structural $+$ amenity $+$ rooms $+$ listing specification; the | |
| 22 | + next two columns add the LLM text layer and the façade vision layer. In the spatial design the 420 forward | |
| 23 | + sortation areas (RTA, first three characters of the postal code) are assigned to five folds by \texttt{GroupKFold}, so | |
| 24 | + no listing is predicted from a model that has seen a listing of the same RTA; municipality indicators of RTAs held | |
| 25 | + out in their entirety are unobserved in training and the model falls back on the reference category. Random-fold | |
| 26 | + entries may differ by $\pm0.001$ from Table~\ref{tab:ablation}, which comes from a separate run. $N=$19{,}123. | |
| 27 | + \end{tablenotes} | |
| 28 | + \end{threeparttable} | |
| 29 | +\end{table} | |
added
results/revision_2026-10-17.json
+1643 −0
@@ -0,0 +1,1643 @@ | ||
| 1 | +{ | |
| 2 | + "text_leakage": { | |
| 3 | + "n": 19123, | |
| 4 | + "asking_price_in_text": 3767, | |
| 5 | + "asking_price_equals_list_price": 3761, | |
| 6 | + "asking_by_source": { | |
| 7 | + "duproprio": 3767, | |
| 8 | + "realtor": 0 | |
| 9 | + }, | |
| 10 | + "dollar_amount_in_text": 4150, | |
| 11 | + "dollar_by_source": { | |
| 12 | + "duproprio": 1.0, | |
| 13 | + "realtor": 0.0249 | |
| 14 | + }, | |
| 15 | + "assessment_mention": 1796, | |
| 16 | + "assessment_by_source": { | |
| 17 | + "duproprio": 0.4659, | |
| 18 | + "realtor": 0.0027 | |
| 19 | + }, | |
| 20 | + "realtor_dollar_share": 0.02494139098723626 | |
| 21 | + }, | |
| 22 | + "language": { | |
| 23 | + "by_source": [ | |
| 24 | + { | |
| 25 | + "source": "duproprio", | |
| 26 | + "lang": "en", | |
| 27 | + "n": 1813, | |
| 28 | + "median_price": 625000.0, | |
| 29 | + "mean_lnp": 13.33569162585933, | |
| 30 | + "desc_len": 3.2069260893546607 | |
| 31 | + }, | |
| 32 | + { | |
| 33 | + "source": "duproprio", | |
| 34 | + "lang": "fr", | |
| 35 | + "n": 5, | |
| 36 | + "median_price": 679000.0, | |
| 37 | + "mean_lnp": 13.417860336206633, | |
| 38 | + "desc_len": 4.3304 | |
| 39 | + }, | |
| 40 | + { | |
| 41 | + "source": "duproprio", | |
| 42 | + "lang": "mixed", | |
| 43 | + "n": 1949, | |
| 44 | + "median_price": 595000.0, | |
| 45 | + "mean_lnp": 13.28764506220431, | |
| 46 | + "desc_len": 4.836105695228322 | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + "source": "realtor", | |
| 50 | + "lang": "en", | |
| 51 | + "n": 6437, | |
| 52 | + "median_price": 749000.0, | |
| 53 | + "mean_lnp": 13.603230702848846, | |
| 54 | + "desc_len": 0.5437955569364611 | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + "source": "realtor", | |
| 58 | + "lang": "fr", | |
| 59 | + "n": 8524, | |
| 60 | + "median_price": 524900.0, | |
| 61 | + "mean_lnp": 13.171599912716486, | |
| 62 | + "desc_len": 0.5476710464570624 | |
| 63 | + }, | |
| 64 | + { | |
| 65 | + "source": "realtor", | |
| 66 | + "lang": "mixed", | |
| 67 | + "n": 395, | |
| 68 | + "median_price": 579000.0, | |
| 69 | + "mean_lnp": 13.252576586101583, | |
| 70 | + "desc_len": 0.048329113924050635 | |
| 71 | + } | |
| 72 | + ], | |
| 73 | + "share_en_overall": 0.4314176645923757, | |
| 74 | + "share_en_realtor": 0.4191846835113311, | |
| 75 | + "share_by_lang": { | |
| 76 | + "fr": 0.446, | |
| 77 | + "en": 0.4314, | |
| 78 | + "mixed": 0.1226 | |
| 79 | + }, | |
| 80 | + "raw_gap_en_cityFE": 0.2143026513746558, | |
| 81 | + "raw_gap_en_nocontrols": 0.37269268462471317 | |
| 82 | + }, | |
| 83 | + "coverage": { | |
| 84 | + "specs": 19123, | |
| 85 | + "facade": 19123, | |
| 86 | + "is_exterior": 18314, | |
| 87 | + "n": 19123 | |
| 88 | + }, | |
| 89 | + "fsa": { | |
| 90 | + "n_fsa_raw": 419, | |
| 91 | + "n_fsa_fe": 250, | |
| 92 | + "n_city_fe": 195 | |
| 93 | + }, | |
| 94 | + "ols": { | |
| 95 | + "A": { | |
| 96 | + "r2": 0.7552103110293897, | |
| 97 | + "n": 9446, | |
| 98 | + "coef": { | |
| 99 | + "v_curb": { | |
| 100 | + "b": 0.023017903057222053, | |
| 101 | + "se": 0.00865392944591846, | |
| 102 | + "p": 0.007818219565022228 | |
| 103 | + }, | |
| 104 | + "v_reno": { | |
| 105 | + "b": 0.023593099837373357, | |
| 106 | + "se": 0.009529503385428685, | |
| 107 | + "p": 0.013293976823549589 | |
| 108 | + }, | |
| 109 | + "v_luxury": { | |
| 110 | + "b": 0.051004755970147975, | |
| 111 | + "se": 0.01193275620932702, | |
| 112 | + "p": 1.9169718790851146e-05 | |
| 113 | + }, | |
| 114 | + "v_garage_vis": { | |
| 115 | + "b": 0.04626239493911488, | |
| 116 | + "se": 0.005814520452429011, | |
| 117 | + "p": 1.7718006522120285e-15 | |
| 118 | + }, | |
| 119 | + "v_mat_brique": { | |
| 120 | + "b": 0.033343794442161366, | |
| 121 | + "se": 0.00914381589542974, | |
| 122 | + "p": 0.0002657381339896736 | |
| 123 | + }, | |
| 124 | + "v_mat_pierre": { | |
| 125 | + "b": 0.036151980964813646, | |
| 126 | + "se": 0.008011891510533968, | |
| 127 | + "p": 6.413130561176702e-06 | |
| 128 | + }, | |
| 129 | + "v_mat_vinyle": { | |
| 130 | + "b": -0.04493374989991618, | |
| 131 | + "se": 0.015100349535057013, | |
| 132 | + "p": 0.0029234340682950024 | |
| 133 | + }, | |
| 134 | + "v_set_rural": { | |
| 135 | + "b": -0.12230705352270166, | |
| 136 | + "se": 0.0321849710016236, | |
| 137 | + "p": 0.00014462056903144396 | |
| 138 | + }, | |
| 139 | + "v_land": { | |
| 140 | + "b": 0.015079214851206849, | |
| 141 | + "se": 0.0062394992136159825, | |
| 142 | + "p": 0.01566042254639302 | |
| 143 | + }, | |
| 144 | + "g_cond": { | |
| 145 | + "b": 0.016168128372665236, | |
| 146 | + "se": 0.0058314343073788385, | |
| 147 | + "p": 0.005561354758418819 | |
| 148 | + }, | |
| 149 | + "g_renovated_kitchen": { | |
| 150 | + "b": 0.02608983576575613, | |
| 151 | + "se": 0.006899975364888895, | |
| 152 | + "p": 0.00015610612944890796 | |
| 153 | + }, | |
| 154 | + "g_hardwood": { | |
| 155 | + "b": 0.02365468450221908, | |
| 156 | + "se": 0.00932507643698107, | |
| 157 | + "p": 0.011191092284736665 | |
| 158 | + }, | |
| 159 | + "g_income_property": { | |
| 160 | + "b": -0.019168272989677937, | |
| 161 | + "se": 0.009252803603397662, | |
| 162 | + "p": 0.03830109511353034 | |
| 163 | + } | |
| 164 | + } | |
| 165 | + }, | |
| 166 | + "A_lang": { | |
| 167 | + "r2": 0.7567348777632339, | |
| 168 | + "n": 9446, | |
| 169 | + "coef": { | |
| 170 | + "v_curb": { | |
| 171 | + "b": 0.0220282046381, | |
| 172 | + "se": 0.008674581574151156, | |
| 173 | + "p": 0.011104380250457709 | |
| 174 | + }, | |
| 175 | + "v_reno": { | |
| 176 | + "b": 0.02399647790026045, | |
| 177 | + "se": 0.009084098521880597, | |
| 178 | + "p": 0.008251750232457736 | |
| 179 | + }, | |
| 180 | + "v_luxury": { | |
| 181 | + "b": 0.05137576904637699, | |
| 182 | + "se": 0.012091590235267013, | |
| 183 | + "p": 2.1483774749896047e-05 | |
| 184 | + }, | |
| 185 | + "v_garage_vis": { | |
| 186 | + "b": 0.046255811432241944, | |
| 187 | + "se": 0.005799162639961236, | |
| 188 | + "p": 1.5079561537175714e-15 | |
| 189 | + }, | |
| 190 | + "v_mat_brique": { | |
| 191 | + "b": 0.03226528382664501, | |
| 192 | + "se": 0.008884270781382892, | |
| 193 | + "p": 0.0002815262245350303 | |
| 194 | + }, | |
| 195 | + "v_mat_pierre": { | |
| 196 | + "b": 0.0369047947749403, | |
| 197 | + "se": 0.008449900660313994, | |
| 198 | + "p": 1.2568676032209342e-05 | |
| 199 | + }, | |
| 200 | + "v_mat_vinyle": { | |
| 201 | + "b": -0.043735965072819655, | |
| 202 | + "se": 0.015191301814047412, | |
| 203 | + "p": 0.003989210850339842 | |
| 204 | + }, | |
| 205 | + "v_set_rural": { | |
| 206 | + "b": -0.12002666538429863, | |
| 207 | + "se": 0.03301891648600372, | |
| 208 | + "p": 0.0002778858194579655 | |
| 209 | + }, | |
| 210 | + "v_land": { | |
| 211 | + "b": 0.015267192969310894, | |
| 212 | + "se": 0.006239374073719944, | |
| 213 | + "p": 0.014408641917175714 | |
| 214 | + }, | |
| 215 | + "g_cond": { | |
| 216 | + "b": 0.01676521632569178, | |
| 217 | + "se": 0.0057271291357884, | |
| 218 | + "p": 0.0034188218673600174 | |
| 219 | + }, | |
| 220 | + "g_renovated_kitchen": { | |
| 221 | + "b": 0.024655303780972332, | |
| 222 | + "se": 0.0069227344505953785, | |
| 223 | + "p": 0.00036874514498707776 | |
| 224 | + }, | |
| 225 | + "g_hardwood": { | |
| 226 | + "b": 0.02617810938024412, | |
| 227 | + "se": 0.008972271748477777, | |
| 228 | + "p": 0.0035265971560858537 | |
| 229 | + }, | |
| 230 | + "g_income_property": { | |
| 231 | + "b": -0.020691265306062245, | |
| 232 | + "se": 0.008971390971810616, | |
| 233 | + "p": 0.021090475166125118 | |
| 234 | + }, | |
| 235 | + "lang_en": { | |
| 236 | + "b": 0.06965266990700705, | |
| 237 | + "se": 0.010757367405508223, | |
| 238 | + "p": 9.488692166328437e-11 | |
| 239 | + }, | |
| 240 | + "lang_mixed": { | |
| 241 | + "b": 0.04502633023718461, | |
| 242 | + "se": 0.011249579206348023, | |
| 243 | + "p": 6.267927171514527e-05 | |
| 244 | + } | |
| 245 | + } | |
| 246 | + }, | |
| 247 | + "B": { | |
| 248 | + "r2": 0.7250019979121326, | |
| 249 | + "n": 19123, | |
| 250 | + "coef": { | |
| 251 | + "v_curb": { | |
| 252 | + "b": 0.01595794997397919, | |
| 253 | + "se": 0.013160921694536032, | |
| 254 | + "p": 0.22531138001340867 | |
| 255 | + }, | |
| 256 | + "v_reno": { | |
| 257 | + "b": 0.019980004053515125, | |
| 258 | + "se": 0.008625974658909864, | |
| 259 | + "p": 0.020544051694801335 | |
| 260 | + }, | |
| 261 | + "v_luxury": { | |
| 262 | + "b": 0.06166029483028444, | |
| 263 | + "se": 0.00869771753262625, | |
| 264 | + "p": 1.3484065717025971e-12 | |
| 265 | + }, | |
| 266 | + "v_garage_vis": { | |
| 267 | + "b": 0.04651267305323856, | |
| 268 | + "se": 0.006720574480616525, | |
| 269 | + "p": 4.486657807636773e-12 | |
| 270 | + }, | |
| 271 | + "v_mat_brique": { | |
| 272 | + "b": 0.04403606617653332, | |
| 273 | + "se": 0.011001756372450839, | |
| 274 | + "p": 6.263967385428824e-05 | |
| 275 | + }, | |
| 276 | + "v_mat_pierre": { | |
| 277 | + "b": 0.04658529674360948, | |
| 278 | + "se": 0.004986368566239516, | |
| 279 | + "p": 9.405939222760319e-21 | |
| 280 | + }, | |
| 281 | + "v_mat_vinyle": { | |
| 282 | + "b": -0.0618081668156812, | |
| 283 | + "se": 0.012339743471281481, | |
| 284 | + "p": 5.475063125324791e-07 | |
| 285 | + }, | |
| 286 | + "v_set_rural": { | |
| 287 | + "b": -0.07600759882542366, | |
| 288 | + "se": 0.028985068114089782, | |
| 289 | + "p": 0.008733802916506193 | |
| 290 | + }, | |
| 291 | + "v_land": { | |
| 292 | + "b": 0.025364605559561076, | |
| 293 | + "se": 0.004475099360767159, | |
| 294 | + "p": 1.4452250155049804e-08 | |
| 295 | + }, | |
| 296 | + "g_cond": { | |
| 297 | + "b": 0.016317524818281637, | |
| 298 | + "se": 0.005198405151324424, | |
| 299 | + "p": 0.0016955538138231493 | |
| 300 | + }, | |
| 301 | + "g_renovated_kitchen": { | |
| 302 | + "b": 0.02694519585553197, | |
| 303 | + "se": 0.009635624404475364, | |
| 304 | + "p": 0.005167314672211995 | |
| 305 | + }, | |
| 306 | + "g_hardwood": { | |
| 307 | + "b": 0.029508607751222216, | |
| 308 | + "se": 0.010501088270171847, | |
| 309 | + "p": 0.004953344261642659 | |
| 310 | + }, | |
| 311 | + "g_income_property": { | |
| 312 | + "b": -0.012880740908551014, | |
| 313 | + "se": 0.007646640747975008, | |
| 314 | + "p": 0.09208572167015686 | |
| 315 | + } | |
| 316 | + } | |
| 317 | + }, | |
| 318 | + "B_lang": { | |
| 319 | + "r2": 0.7294706327446184, | |
| 320 | + "n": 19123, | |
| 321 | + "coef": { | |
| 322 | + "v_curb": { | |
| 323 | + "b": 0.014140409984109793, | |
| 324 | + "se": 0.012613533533211005, | |
| 325 | + "p": 0.26226630268571227 | |
| 326 | + }, | |
| 327 | + "v_reno": { | |
| 328 | + "b": 0.021452819122661136, | |
| 329 | + "se": 0.00809144238940101, | |
| 330 | + "p": 0.008018323350468072 | |
| 331 | + }, | |
| 332 | + "v_luxury": { | |
| 333 | + "b": 0.061499675154300534, | |
| 334 | + "se": 0.008400292138243528, | |
| 335 | + "p": 2.458818030231777e-13 | |
| 336 | + }, | |
| 337 | + "v_garage_vis": { | |
| 338 | + "b": 0.047583395448239, | |
| 339 | + "se": 0.006708938616990217, | |
| 340 | + "p": 1.3167540880058334e-12 | |
| 341 | + }, | |
| 342 | + "v_mat_brique": { | |
| 343 | + "b": 0.04270872969142887, | |
| 344 | + "se": 0.010761547590495083, | |
| 345 | + "p": 7.228338107064312e-05 | |
| 346 | + }, | |
| 347 | + "v_mat_pierre": { | |
| 348 | + "b": 0.047530408479713834, | |
| 349 | + "se": 0.005227275353296171, | |
| 350 | + "p": 9.654802277297552e-20 | |
| 351 | + }, | |
| 352 | + "v_mat_vinyle": { | |
| 353 | + "b": -0.059391516825136194, | |
| 354 | + "se": 0.011539624897825134, | |
| 355 | + "p": 2.6504399622334076e-07 | |
| 356 | + }, | |
| 357 | + "v_set_rural": { | |
| 358 | + "b": -0.07285861233369789, | |
| 359 | + "se": 0.028764862151562362, | |
| 360 | + "p": 0.011312217666697268 | |
| 361 | + }, | |
| 362 | + "v_land": { | |
| 363 | + "b": 0.024365920822358444, | |
| 364 | + "se": 0.00434483530483999, | |
| 365 | + "p": 2.046550527173117e-08 | |
| 366 | + }, | |
| 367 | + "g_cond": { | |
| 368 | + "b": 0.01670923929962092, | |
| 369 | + "se": 0.005120433745030281, | |
| 370 | + "p": 0.0011014353593805713 | |
| 371 | + }, | |
| 372 | + "g_renovated_kitchen": { | |
| 373 | + "b": 0.02463755558525975, | |
| 374 | + "se": 0.008759011578689791, | |
| 375 | + "p": 0.0049108563812810075 | |
| 376 | + }, | |
| 377 | + "g_hardwood": { | |
| 378 | + "b": 0.033418913488580115, | |
| 379 | + "se": 0.011154095621616887, | |
| 380 | + "p": 0.0027344648221796965 | |
| 381 | + }, | |
| 382 | + "g_income_property": { | |
| 383 | + "b": -0.015281082928718548, | |
| 384 | + "se": 0.007369131187798335, | |
| 385 | + "p": 0.03811076806327996 | |
| 386 | + }, | |
| 387 | + "lang_en": { | |
| 388 | + "b": 0.1117961062255265, | |
| 389 | + "se": 0.028766842224795294, | |
| 390 | + "p": 0.00010179059625158188 | |
| 391 | + }, | |
| 392 | + "lang_mixed": { | |
| 393 | + "b": 0.053708392373144176, | |
| 394 | + "se": 0.018882514235156286, | |
| 395 | + "p": 0.004450277756183304 | |
| 396 | + } | |
| 397 | + } | |
| 398 | + }, | |
| 399 | + "A_fsa": { | |
| 400 | + "r2": 0.7613601578784245, | |
| 401 | + "n": 9446, | |
| 402 | + "coef": { | |
| 403 | + "v_curb": { | |
| 404 | + "b": 0.017181245734599684, | |
| 405 | + "se": 0.006213488488310514, | |
| 406 | + "p": 0.005689611946087438 | |
| 407 | + }, | |
| 408 | + "v_reno": { | |
| 409 | + "b": 0.02913062835600555, | |
| 410 | + "se": 0.00866518471552936, | |
| 411 | + "p": 0.0007743585263284946 | |
| 412 | + }, | |
| 413 | + "v_luxury": { | |
| 414 | + "b": 0.04423659509281494, | |
| 415 | + "se": 0.010353820853101102, | |
| 416 | + "p": 1.9330230571668745e-05 | |
| 417 | + }, | |
| 418 | + "v_garage_vis": { | |
| 419 | + "b": 0.03734060333608957, | |
| 420 | + "se": 0.0060003239199587066, | |
| 421 | + "p": 4.874329300926464e-10 | |
| 422 | + }, | |
| 423 | + "v_mat_brique": { | |
| 424 | + "b": 0.03238723283442161, | |
| 425 | + "se": 0.010519113380586495, | |
| 426 | + "p": 0.0020777074106452464 | |
| 427 | + }, | |
| 428 | + "v_mat_pierre": { | |
| 429 | + "b": 0.03634362862612156, | |
| 430 | + "se": 0.008664004648796565, | |
| 431 | + "p": 2.731316639733451e-05 | |
| 432 | + }, | |
| 433 | + "v_mat_vinyle": { | |
| 434 | + "b": -0.04840783002433969, | |
| 435 | + "se": 0.018446653047869965, | |
| 436 | + "p": 0.008685106631411392 | |
| 437 | + }, | |
| 438 | + "v_set_rural": { | |
| 439 | + "b": -0.12639182908614943, | |
| 440 | + "se": 0.04328081185117937, | |
| 441 | + "p": 0.003497237648930978 | |
| 442 | + }, | |
| 443 | + "v_land": { | |
| 444 | + "b": 0.012681103312182654, | |
| 445 | + "se": 0.005537781242784083, | |
| 446 | + "p": 0.022025668911288897 | |
| 447 | + }, | |
| 448 | + "g_cond": { | |
| 449 | + "b": 0.014042986971437271, | |
| 450 | + "se": 0.005092267362968359, | |
| 451 | + "p": 0.005820814958749212 | |
| 452 | + }, | |
| 453 | + "g_renovated_kitchen": { | |
| 454 | + "b": 0.01954704770829435, | |
| 455 | + "se": 0.00928173697158564, | |
| 456 | + "p": 0.03520706974827266 | |
| 457 | + }, | |
| 458 | + "g_hardwood": { | |
| 459 | + "b": 0.013896176008893368, | |
| 460 | + "se": 0.006666798086296709, | |
| 461 | + "p": 0.037125132793963206 | |
| 462 | + }, | |
| 463 | + "g_income_property": { | |
| 464 | + "b": -0.012788089560278326, | |
| 465 | + "se": 0.012751573385642126, | |
| 466 | + "p": 0.31592664823176597 | |
| 467 | + } | |
| 468 | + } | |
| 469 | + }, | |
| 470 | + "A_fsa_lang": { | |
| 471 | + "r2": 0.7636495766633198, | |
| 472 | + "n": 9446, | |
| 473 | + "coef": { | |
| 474 | + "v_curb": { | |
| 475 | + "b": 0.016248935580446572, | |
| 476 | + "se": 0.006266364786650203, | |
| 477 | + "p": 0.009513165983223961 | |
| 478 | + }, | |
| 479 | + "v_reno": { | |
| 480 | + "b": 0.029235212598072574, | |
| 481 | + "se": 0.008624780791463442, | |
| 482 | + "p": 0.0006997526996340517 | |
| 483 | + }, | |
| 484 | + "v_luxury": { | |
| 485 | + "b": 0.04475794826074414, | |
| 486 | + "se": 0.010335676031969747, | |
| 487 | + "p": 1.48816703394419e-05 | |
| 488 | + }, | |
| 489 | + "v_garage_vis": { | |
| 490 | + "b": 0.03704006371810917, | |
| 491 | + "se": 0.006307305401601367, | |
| 492 | + "p": 4.29102234235383e-09 | |
| 493 | + }, | |
| 494 | + "v_mat_brique": { | |
| 495 | + "b": 0.03097446907959662, | |
| 496 | + "se": 0.010197993272572073, | |
| 497 | + "p": 0.0023869966760450994 | |
| 498 | + }, | |
| 499 | + "v_mat_pierre": { | |
| 500 | + "b": 0.037413728935033974, | |
| 501 | + "se": 0.008538160274934682, | |
| 502 | + "p": 1.1762575781059087e-05 | |
| 503 | + }, | |
| 504 | + "v_mat_vinyle": { | |
| 505 | + "b": -0.04717895540837608, | |
| 506 | + "se": 0.017800053118632878, | |
| 507 | + "p": 0.008037386860489196 | |
| 508 | + }, | |
| 509 | + "v_set_rural": { | |
| 510 | + "b": -0.12237916860417042, | |
| 511 | + "se": 0.04215648416880492, | |
| 512 | + "p": 0.003696375714822433 | |
| 513 | + }, | |
| 514 | + "v_land": { | |
| 515 | + "b": 0.012748126858161887, | |
| 516 | + "se": 0.005568057347587657, | |
| 517 | + "p": 0.022049697114484807 | |
| 518 | + }, | |
| 519 | + "g_cond": { | |
| 520 | + "b": 0.014548282942941665, | |
| 521 | + "se": 0.005098494623085869, | |
| 522 | + "p": 0.004324777443249617 | |
| 523 | + }, | |
| 524 | + "g_renovated_kitchen": { | |
| 525 | + "b": 0.01880486827485789, | |
| 526 | + "se": 0.009270238446950178, | |
| 527 | + "p": 0.04250715821797065 | |
| 528 | + }, | |
| 529 | + "g_hardwood": { | |
| 530 | + "b": 0.015526162898754026, | |
| 531 | + "se": 0.006910168275374136, | |
| 532 | + "p": 0.024649140377487517 | |
| 533 | + }, | |
| 534 | + "g_income_property": { | |
| 535 | + "b": -0.014139484159004345, | |
| 536 | + "se": 0.012486591753120405, | |
| 537 | + "p": 0.2574774898168585 | |
| 538 | + }, | |
| 539 | + "lang_en": { | |
| 540 | + "b": 0.08951918575974482, | |
| 541 | + "se": 0.03446376644438621, | |
| 542 | + "p": 0.009390867133295603 | |
| 543 | + }, | |
| 544 | + "lang_mixed": { | |
| 545 | + "b": 0.06682706837252739, | |
| 546 | + "se": 0.030328238917951333, | |
| 547 | + "p": 0.027562326919126412 | |
| 548 | + } | |
| 549 | + } | |
| 550 | + }, | |
| 551 | + "B_fsa": { | |
| 552 | + "r2": 0.7263545294217424, | |
| 553 | + "n": 19123, | |
| 554 | + "coef": { | |
| 555 | + "v_curb": { | |
| 556 | + "b": 0.014414483272076815, | |
| 557 | + "se": 0.006752978595693768, | |
| 558 | + "p": 0.03279884099969961 | |
| 559 | + }, | |
| 560 | + "v_reno": { | |
| 561 | + "b": 0.02362309974851571, | |
| 562 | + "se": 0.006386987651381948, | |
| 563 | + "p": 0.0002167669061224354 | |
| 564 | + }, | |
| 565 | + "v_luxury": { | |
| 566 | + "b": 0.05522265404408447, | |
| 567 | + "se": 0.011801488738274954, | |
| 568 | + "p": 2.878622062546483e-06 | |
| 569 | + }, | |
| 570 | + "v_garage_vis": { | |
| 571 | + "b": 0.04488665381680389, | |
| 572 | + "se": 0.005673121074707837, | |
| 573 | + "p": 2.529566272762449e-15 | |
| 574 | + }, | |
| 575 | + "v_mat_brique": { | |
| 576 | + "b": 0.047093395958372516, | |
| 577 | + "se": 0.0145662424954123, | |
| 578 | + "p": 0.0012247595790037217 | |
| 579 | + }, | |
| 580 | + "v_mat_pierre": { | |
| 581 | + "b": 0.04852774521254276, | |
| 582 | + "se": 0.005333025621243613, | |
| 583 | + "p": 9.076766303267039e-20 | |
| 584 | + }, | |
| 585 | + "v_mat_vinyle": { | |
| 586 | + "b": -0.06523612504184213, | |
| 587 | + "se": 0.016693566121318202, | |
| 588 | + "p": 9.311710177370299e-05 | |
| 589 | + }, | |
| 590 | + "v_set_rural": { | |
| 591 | + "b": -0.07095781352495395, | |
| 592 | + "se": 0.055364077824565636, | |
| 593 | + "p": 0.199962642707183 | |
| 594 | + }, | |
| 595 | + "v_land": { | |
| 596 | + "b": 0.019606183535763017, | |
| 597 | + "se": 0.004473568939205577, | |
| 598 | + "p": 1.1723276112067005e-05 | |
| 599 | + }, | |
| 600 | + "g_cond": { | |
| 601 | + "b": 0.015734770445255054, | |
| 602 | + "se": 0.004859055192010304, | |
| 603 | + "p": 0.0012027101480981657 | |
| 604 | + }, | |
| 605 | + "g_renovated_kitchen": { | |
| 606 | + "b": 0.022079231334420107, | |
| 607 | + "se": 0.0064739961517580125, | |
| 608 | + "p": 0.0006485609932588853 | |
| 609 | + }, | |
| 610 | + "g_hardwood": { | |
| 611 | + "b": 0.01714089477691072, | |
| 612 | + "se": 0.006270000021361955, | |
| 613 | + "p": 0.006260900898443002 | |
| 614 | + }, | |
| 615 | + "g_income_property": { | |
| 616 | + "b": -0.01014885437918328, | |
| 617 | + "se": 0.01070211622945107, | |
| 618 | + "p": 0.3429749647833692 | |
| 619 | + } | |
| 620 | + } | |
| 621 | + }, | |
| 622 | + "A_realtor_fsa_lang": { | |
| 623 | + "r2": 0.8019629333671822, | |
| 624 | + "n": 5781, | |
| 625 | + "coef": { | |
| 626 | + "v_curb": { | |
| 627 | + "b": 0.021367211208677767, | |
| 628 | + "se": 0.009612912797527693, | |
| 629 | + "p": 0.026231895289707187 | |
| 630 | + }, | |
| 631 | + "v_reno": { | |
| 632 | + "b": 0.04129900476874043, | |
| 633 | + "se": 0.017928231499329213, | |
| 634 | + "p": 0.021246578714016275 | |
| 635 | + }, | |
| 636 | + "v_luxury": { | |
| 637 | + "b": 0.04203233411432983, | |
| 638 | + "se": 0.014712814498368115, | |
| 639 | + "p": 0.00427865237046459 | |
| 640 | + }, | |
| 641 | + "v_garage_vis": { | |
| 642 | + "b": 0.04066858689843098, | |
| 643 | + "se": 0.008806843246547272, | |
| 644 | + "p": 3.877563337776636e-06 | |
| 645 | + }, | |
| 646 | + "v_mat_brique": { | |
| 647 | + "b": 0.023721189498116607, | |
| 648 | + "se": 0.017447575657522845, | |
| 649 | + "p": 0.17396623551628632 | |
| 650 | + }, | |
| 651 | + "v_mat_pierre": { | |
| 652 | + "b": 0.02993286402615017, | |
| 653 | + "se": 0.01021427196812345, | |
| 654 | + "p": 0.003384233894502081 | |
| 655 | + }, | |
| 656 | + "v_mat_vinyle": { | |
| 657 | + "b": -0.050884217991728764, | |
| 658 | + "se": 0.02101648171689293, | |
| 659 | + "p": 0.015471161025246786 | |
| 660 | + }, | |
| 661 | + "v_set_rural": { | |
| 662 | + "b": -0.11889877957340445, | |
| 663 | + "se": 0.0868560204710719, | |
| 664 | + "p": 0.17102487343264272 | |
| 665 | + }, | |
| 666 | + "v_land": { | |
| 667 | + "b": 0.026578661718596436, | |
| 668 | + "se": 0.007339042464912785, | |
| 669 | + "p": 0.00029285052198313205 | |
| 670 | + }, | |
| 671 | + "g_cond": { | |
| 672 | + "b": 0.012038030803227698, | |
| 673 | + "se": 0.008798811347968356, | |
| 674 | + "p": 0.17126736734969095 | |
| 675 | + }, | |
| 676 | + "g_renovated_kitchen": { | |
| 677 | + "b": 0.030471254734996567, | |
| 678 | + "se": 0.011934169854197565, | |
| 679 | + "p": 0.010671424721548424 | |
| 680 | + }, | |
| 681 | + "g_hardwood": { | |
| 682 | + "b": -0.0010674440390479045, | |
| 683 | + "se": 0.013197890742933791, | |
| 684 | + "p": 0.9355374677428574 | |
| 685 | + }, | |
| 686 | + "g_income_property": { | |
| 687 | + "b": -0.030563244373362275, | |
| 688 | + "se": 0.02091115359756968, | |
| 689 | + "p": 0.14385738078865717 | |
| 690 | + }, | |
| 691 | + "lang_en": { | |
| 692 | + "b": 0.08209491651353809, | |
| 693 | + "se": 0.041682106904610224, | |
| 694 | + "p": 0.048890179126368095 | |
| 695 | + }, | |
| 696 | + "lang_mixed": { | |
| 697 | + "b": 0.1810730294836176, | |
| 698 | + "se": 0.041883938233998004, | |
| 699 | + "p": 1.537757500291537e-05 | |
| 700 | + } | |
| 701 | + } | |
| 702 | + } | |
| 703 | + }, | |
| 704 | + "ablation_A": { | |
| 705 | + "all": { | |
| 706 | + "base": 0.7168982211740982, | |
| 707 | + "plus_text": 0.7252251732782795, | |
| 708 | + "plus_text_vision": 0.7552103110293897, | |
| 709 | + "n": 9446, | |
| 710 | + "d_text": 0.008326952104181329, | |
| 711 | + "d_vision": 0.029985137751110225 | |
| 712 | + }, | |
| 713 | + "fr": { | |
| 714 | + "base": 0.704191925205909, | |
| 715 | + "plus_text": 0.7196528232071896, | |
| 716 | + "plus_text_vision": 0.7534024100015527, | |
| 717 | + "n": 2619, | |
| 718 | + "d_text": 0.015460898001280587, | |
| 719 | + "d_vision": 0.03374958679436313 | |
| 720 | + }, | |
| 721 | + "en": { | |
| 722 | + "base": 0.7633876402412476, | |
| 723 | + "plus_text": 0.7697083706514656, | |
| 724 | + "plus_text_vision": 0.7921900184144034, | |
| 725 | + "n": 4815, | |
| 726 | + "d_text": 0.006320730410217967, | |
| 727 | + "d_vision": 0.022481647762937818 | |
| 728 | + }, | |
| 729 | + "mixed": { | |
| 730 | + "base": 0.5788853289018507, | |
| 731 | + "plus_text": 0.6110278423736797, | |
| 732 | + "plus_text_vision": 0.6590466596511697, | |
| 733 | + "n": 2012, | |
| 734 | + "d_text": 0.03214251347182895, | |
| 735 | + "d_vision": 0.04801881727749002 | |
| 736 | + }, | |
| 737 | + "realtor": { | |
| 738 | + "base": 0.7792712016051034, | |
| 739 | + "plus_text": 0.7857284989543681, | |
| 740 | + "plus_text_vision": 0.8097641057720486, | |
| 741 | + "n": 5781, | |
| 742 | + "d_text": 0.006457297349264701, | |
| 743 | + "d_vision": 0.024035606817680466 | |
| 744 | + }, | |
| 745 | + "duproprio": { | |
| 746 | + "base": 0.5641360338178396, | |
| 747 | + "plus_text": 0.5975909670433623, | |
| 748 | + "plus_text_vision": 0.6387544773609131, | |
| 749 | + "n": 3665, | |
| 750 | + "d_text": 0.03345493322552273, | |
| 751 | + "d_vision": 0.04116351031755072 | |
| 752 | + }, | |
| 753 | + "realtor_no_dollar": { | |
| 754 | + "base": 0.7804575160736943, | |
| 755 | + "plus_text": 0.7868051788991395, | |
| 756 | + "plus_text_vision": 0.8105017890993039, | |
| 757 | + "n": 5640, | |
| 758 | + "d_text": 0.006347662825445188, | |
| 759 | + "d_vision": 0.023696610200164447 | |
| 760 | + }, | |
| 761 | + "realtor_dollar": { | |
| 762 | + "base": 0.9203905155093728, | |
| 763 | + "plus_text": 0.9663686451614234, | |
| 764 | + "plus_text_vision": 0.9981623795399744, | |
| 765 | + "n": 141, | |
| 766 | + "d_text": 0.045978129652050614, | |
| 767 | + "d_vision": 0.03179373437855104 | |
| 768 | + }, | |
| 769 | + "with_lang": { | |
| 770 | + "base": 0.7188023071488996, | |
| 771 | + "plus_text": 0.7274109943432802, | |
| 772 | + "plus_text_vision": 0.7567348777632339 | |
| 773 | + }, | |
| 774 | + "fsa_fe": { | |
| 775 | + "base": 0.7224359228022387, | |
| 776 | + "plus_text": 0.7298409617480321, | |
| 777 | + "plus_text_vision": 0.7613601578784245, | |
| 778 | + "n": 9446, | |
| 779 | + "d_text": 0.007405038945793474, | |
| 780 | + "d_vision": 0.031519196130392335 | |
| 781 | + } | |
| 782 | + }, | |
| 783 | + "cluster_bootstrap_A": { | |
| 784 | + "B": 299, | |
| 785 | + "n_clusters": 195, | |
| 786 | + "ci95": { | |
| 787 | + "v_curb": [ | |
| 788 | + 0.0008207600301133864, | |
| 789 | + 0.03531138785517337 | |
| 790 | + ], | |
| 791 | + "v_reno": [ | |
| 792 | + 0.009861320035016418, | |
| 793 | + 0.04639780248828285 | |
| 794 | + ], | |
| 795 | + "v_luxury": [ | |
| 796 | + 0.018702682550024947, | |
| 797 | + 0.06587201000970766 | |
| 798 | + ], | |
| 799 | + "v_garage_vis": [ | |
| 800 | + 0.029489483851641338, | |
| 801 | + 0.05546454216073049 | |
| 802 | + ], | |
| 803 | + "v_mat_brique": [ | |
| 804 | + 0.001091429965688582, | |
| 805 | + 0.04435286993426672 | |
| 806 | + ], | |
| 807 | + "v_mat_pierre": [ | |
| 808 | + 0.02208144167342061, | |
| 809 | + 0.04941585568306584 | |
| 810 | + ], | |
| 811 | + "v_mat_vinyle": [ | |
| 812 | + -0.06693216723701244, | |
| 813 | + -0.007135683318845551 | |
| 814 | + ], | |
| 815 | + "v_set_rural": [ | |
| 816 | + -0.1756530215378054, | |
| 817 | + -0.02915765109659804 | |
| 818 | + ], | |
| 819 | + "v_land": [ | |
| 820 | + -0.0003849727417672886, | |
| 821 | + 0.024962880210475685 | |
| 822 | + ], | |
| 823 | + "g_cond": [ | |
| 824 | + 0.002359303173937946, | |
| 825 | + 0.024318565020234856 | |
| 826 | + ], | |
| 827 | + "g_renovated_kitchen": [ | |
| 828 | + 0.009756118491580604, | |
| 829 | + 0.03945200625378577 | |
| 830 | + ], | |
| 831 | + "g_hardwood": [ | |
| 832 | + -0.0027363742113989285, | |
| 833 | + 0.03581234933965173 | |
| 834 | + ], | |
| 835 | + "g_income_property": [ | |
| 836 | + -0.040193714643788465, | |
| 837 | + -0.0016888306322588513 | |
| 838 | + ] | |
| 839 | + }, | |
| 840 | + "se": { | |
| 841 | + "v_curb": 0.009179049835986632, | |
| 842 | + "v_reno": 0.009511910131603225, | |
| 843 | + "v_luxury": 0.01319348004117406, | |
| 844 | + "v_garage_vis": 0.007007886945506273, | |
| 845 | + "v_mat_brique": 0.011943996189678436, | |
| 846 | + "v_mat_pierre": 0.007469085731764851, | |
| 847 | + "v_mat_vinyle": 0.016653171942833497, | |
| 848 | + "v_set_rural": 0.03679888572279241, | |
| 849 | + "v_land": 0.006913416315742771, | |
| 850 | + "g_cond": 0.006157267193711723, | |
| 851 | + "g_renovated_kitchen": 0.0075529847838382794, | |
| 852 | + "g_hardwood": 0.010951468962615583, | |
| 853 | + "g_income_property": 0.009957463462929536 | |
| 854 | + } | |
| 855 | + }, | |
| 856 | + "agreement": { | |
| 857 | + "llm_vs_keyword": { | |
| 858 | + "garage": { | |
| 859 | + "agreement": 0.981906604612247, | |
| 860 | + "kappa": 0.9625804939313405, | |
| 861 | + "precision_vs_ref": 0.9797721162463193, | |
| 862 | + "recall_vs_ref": 0.9760234663945925, | |
| 863 | + "share_a": 0.4084610155310359, | |
| 864 | + "share_ref": 0.41002980703864456, | |
| 865 | + "n": 19123 | |
| 866 | + }, | |
| 867 | + "pool": { | |
| 868 | + "agreement": 0.9353657898865241, | |
| 869 | + "kappa": 0.8055621562739752, | |
| 870 | + "precision_vs_ref": 0.9880081895291021, | |
| 871 | + "recall_vs_ref": 0.7386835775202274, | |
| 872 | + "share_a": 0.1787899388171312, | |
| 873 | + "share_ref": 0.23913611880981017, | |
| 874 | + "n": 19123 | |
| 875 | + }, | |
| 876 | + "waterfront": { | |
| 877 | + "agreement": 0.8622078125817079, | |
| 878 | + "kappa": 0.5007327488879811, | |
| 879 | + "precision_vs_ref": 0.3984230055658627, | |
| 880 | + "recall_vs_ref": 0.9766913018760659, | |
| 881 | + "share_a": 0.22548763269361502, | |
| 882 | + "share_ref": 0.09198347539611985, | |
| 883 | + "n": 19123 | |
| 884 | + }, | |
| 885 | + "fireplace": { | |
| 886 | + "agreement": 0.9667416200386969, | |
| 887 | + "kappa": 0.9053787374931429, | |
| 888 | + "precision_vs_ref": 0.9627329192546584, | |
| 889 | + "recall_vs_ref": 0.893569844789357, | |
| 890 | + "share_a": 0.21889870836165873, | |
| 891 | + "share_ref": 0.23584165664383203, | |
| 892 | + "n": 19123 | |
| 893 | + }, | |
| 894 | + "central_ac": { | |
| 895 | + "agreement": 0.9081734037546411, | |
| 896 | + "kappa": 0.6475279894680741, | |
| 897 | + "precision_vs_ref": 0.9247606019151847, | |
| 898 | + "recall_vs_ref": 0.5603757944183476, | |
| 899 | + "share_a": 0.1146786592061915, | |
| 900 | + "share_ref": 0.18924854886785547, | |
| 901 | + "n": 19123 | |
| 902 | + }, | |
| 903 | + "finished_basement": { | |
| 904 | + "agreement": 0.8048423364534854, | |
| 905 | + "kappa": 0.5638469085392556, | |
| 906 | + "precision_vs_ref": 0.6745762711864407, | |
| 907 | + "recall_vs_ref": 0.750204884445173, | |
| 908 | + "share_a": 0.3548083459708205, | |
| 909 | + "share_ref": 0.3190398995973435, | |
| 910 | + "n": 19123 | |
| 911 | + } | |
| 912 | + }, | |
| 913 | + "vision_vs_text": { | |
| 914 | + "garage_visible_vs_llm_garage": { | |
| 915 | + "agreement": 0.675930981762586, | |
| 916 | + "kappa": 0.3459617653055207, | |
| 917 | + "precision_vs_ref": 0.5904805702460336, | |
| 918 | + "recall_vs_ref": 0.6839792249300839, | |
| 919 | + "share_a": 0.4749372065086819, | |
| 920 | + "share_ref": 0.4100141967893415, | |
| 921 | + "n": 18314 | |
| 922 | + }, | |
| 923 | + "garage_visible_vs_keyword_garage": { | |
| 924 | + "agreement": 0.6736922572895053, | |
| 925 | + "kappa": 0.34154176184060453, | |
| 926 | + "precision_vs_ref": 0.5896757875373649, | |
| 927 | + "recall_vs_ref": 0.6805997876857749, | |
| 928 | + "share_a": 0.4749372065086819, | |
| 929 | + "share_ref": 0.411488478759419, | |
| 930 | + "n": 18314 | |
| 931 | + }, | |
| 932 | + "waterfront_setting_vs_keyword": { | |
| 933 | + "agreement": 0.9114884787594191, | |
| 934 | + "kappa": 0.38599787805522834, | |
| 935 | + "precision_vs_ref": 0.5167224080267558, | |
| 936 | + "recall_vs_ref": 0.3720650210716436, | |
| 937 | + "share_a": 0.06530523097084198, | |
| 938 | + "share_ref": 0.09069564267773288, | |
| 939 | + "n": 18314 | |
| 940 | + } | |
| 941 | + }, | |
| 942 | + "vision_storeys_vs_structured": { | |
| 943 | + "n": 18065, | |
| 944 | + "exact": 0.604705231109881, | |
| 945 | + "within_half_storey": 0.8871851646830888 | |
| 946 | + }, | |
| 947 | + "vision_rowhouse_vs_listing_type": { | |
| 948 | + "agreement": 0.8902478977831167, | |
| 949 | + "kappa": 0.2637713396198635, | |
| 950 | + "precision_vs_ref": 0.18451612903225806, | |
| 951 | + "recall_vs_ref": 0.7900552486187845, | |
| 952 | + "share_a": 0.12695205853445451, | |
| 953 | + "share_ref": 0.02964944850933712, | |
| 954 | + "n": 18314 | |
| 955 | + }, | |
| 956 | + "vision_building_type_dist": { | |
| 957 | + "maison_detachee": 0.676, | |
| 958 | + "chalet": 0.145, | |
| 959 | + "rangee": 0.127, | |
| 960 | + "jumele": 0.028, | |
| 961 | + "autre": 0.011, | |
| 962 | + "terrain": 0.008, | |
| 963 | + "condo_immeuble": 0.005 | |
| 964 | + } | |
| 965 | + }, | |
| 966 | + "cv": { | |
| 967 | + "random": { | |
| 968 | + "L2": { | |
| 969 | + "ols": { | |
| 970 | + "all": { | |
| 971 | + "r2": 0.6193226824222091, | |
| 972 | + "mdape": 18.059509413349794, | |
| 973 | + "n": 19123 | |
| 974 | + }, | |
| 975 | + "fr": { | |
| 976 | + "r2": 0.6222349135800598, | |
| 977 | + "mdape": 17.639819430710666, | |
| 978 | + "n": 8529 | |
| 979 | + }, | |
| 980 | + "en": { | |
| 981 | + "r2": 0.5617725991605782, | |
| 982 | + "mdape": 18.41895835751976, | |
| 983 | + "n": 8250 | |
| 984 | + }, | |
| 985 | + "mixed": { | |
| 986 | + "r2": 0.515890303878296, | |
| 987 | + "mdape": 18.312344553455468, | |
| 988 | + "n": 2344 | |
| 989 | + }, | |
| 990 | + "realtor": { | |
| 991 | + "r2": 0.7008096863999596, | |
| 992 | + "mdape": 17.771964295157733, | |
| 993 | + "n": 15356 | |
| 994 | + }, | |
| 995 | + "duproprio": { | |
| 996 | + "r2": -0.08256652477430992, | |
| 997 | + "mdape": 19.121574375743567, | |
| 998 | + "n": 3767 | |
| 999 | + }, | |
| 1000 | + "realtor_no_dollar": { | |
| 1001 | + "r2": 0.7019679871863057, | |
| 1002 | + "mdape": 17.76991387527135, | |
| 1003 | + "n": 14973 | |
| 1004 | + }, | |
| 1005 | + "realtor_dollar": { | |
| 1006 | + "r2": 0.6265270737923495, | |
| 1007 | + "mdape": 18.149953869938827, | |
| 1008 | + "n": 383 | |
| 1009 | + } | |
| 1010 | + }, | |
| 1011 | + "gbm": { | |
| 1012 | + "all": { | |
| 1013 | + "r2": 0.7288688475138769, | |
| 1014 | + "mdape": 15.95094002848213, | |
| 1015 | + "n": 19123 | |
| 1016 | + }, | |
| 1017 | + "fr": { | |
| 1018 | + "r2": 0.6796449615633335, | |
| 1019 | + "mdape": 15.91046276057202, | |
| 1020 | + "n": 8529 | |
| 1021 | + }, | |
| 1022 | + "en": { | |
| 1023 | + "r2": 0.7373780823763605, | |
| 1024 | + "mdape": 16.027535537677895, | |
| 1025 | + "n": 8250 | |
| 1026 | + }, | |
| 1027 | + "mixed": { | |
| 1028 | + "r2": 0.5912440590283798, | |
| 1029 | + "mdape": 16.015730662547156, | |
| 1030 | + "n": 2344 | |
| 1031 | + }, | |
| 1032 | + "realtor": { | |
| 1033 | + "r2": 0.7478808437303475, | |
| 1034 | + "mdape": 15.945941339063008, | |
| 1035 | + "n": 15356 | |
| 1036 | + }, | |
| 1037 | + "duproprio": { | |
| 1038 | + "r2": 0.5636061847477183, | |
| 1039 | + "mdape": 15.984568849587589, | |
| 1040 | + "n": 3767 | |
| 1041 | + }, | |
| 1042 | + "realtor_no_dollar": { | |
| 1043 | + "r2": 0.7489442194125158, | |
| 1044 | + "mdape": 15.940505502981694, | |
| 1045 | + "n": 14973 | |
| 1046 | + }, | |
| 1047 | + "realtor_dollar": { | |
| 1048 | + "r2": 0.6805734307104678, | |
| 1049 | + "mdape": 16.252144564034566, | |
| 1050 | + "n": 383 | |
| 1051 | + } | |
| 1052 | + } | |
| 1053 | + }, | |
| 1054 | + "L3": { | |
| 1055 | + "ols": { | |
| 1056 | + "all": { | |
| 1057 | + "r2": 0.6277548901387373, | |
| 1058 | + "mdape": 17.877027385198495, | |
| 1059 | + "n": 19123 | |
| 1060 | + }, | |
| 1061 | + "fr": { | |
| 1062 | + "r2": 0.6339927443036132, | |
| 1063 | + "mdape": 17.5684715187848, | |
| 1064 | + "n": 8529 | |
| 1065 | + }, | |
| 1066 | + "en": { | |
| 1067 | + "r2": 0.5683785039724047, | |
| 1068 | + "mdape": 18.372824236151033, | |
| 1069 | + "n": 8250 | |
| 1070 | + }, | |
| 1071 | + "mixed": { | |
| 1072 | + "r2": 0.5297335176583204, | |
| 1073 | + "mdape": 17.62364511137402, | |
| 1074 | + "n": 2344 | |
| 1075 | + }, | |
| 1076 | + "realtor": { | |
| 1077 | + "r2": 0.7069455112941738, | |
| 1078 | + "mdape": 17.708227920321868, | |
| 1079 | + "n": 15356 | |
| 1080 | + }, | |
| 1081 | + "duproprio": { | |
| 1082 | + "r2": -0.05437331891905939, | |
| 1083 | + "mdape": 18.468988905900087, | |
| 1084 | + "n": 3767 | |
| 1085 | + }, | |
| 1086 | + "realtor_no_dollar": { | |
| 1087 | + "r2": 0.7080450135924478, | |
| 1088 | + "mdape": 17.70580384822257, | |
| 1089 | + "n": 14973 | |
| 1090 | + }, | |
| 1091 | + "realtor_dollar": { | |
| 1092 | + "r2": 0.6360774250740133, | |
| 1093 | + "mdape": 17.911209797858852, | |
| 1094 | + "n": 383 | |
| 1095 | + } | |
| 1096 | + }, | |
| 1097 | + "gbm": { | |
| 1098 | + "all": { | |
| 1099 | + "r2": 0.7428875872402715, | |
| 1100 | + "mdape": 15.421354827745482, | |
| 1101 | + "n": 19123 | |
| 1102 | + }, | |
| 1103 | + "fr": { | |
| 1104 | + "r2": 0.6944195218234042, | |
| 1105 | + "mdape": 15.28189314238566, | |
| 1106 | + "n": 8529 | |
| 1107 | + }, | |
| 1108 | + "en": { | |
| 1109 | + "r2": 0.7521933355011332, | |
| 1110 | + "mdape": 15.624521878883318, | |
| 1111 | + "n": 8250 | |
| 1112 | + }, | |
| 1113 | + "mixed": { | |
| 1114 | + "r2": 0.6133358277852637, | |
| 1115 | + "mdape": 15.255826448803095, | |
| 1116 | + "n": 2344 | |
| 1117 | + }, | |
| 1118 | + "realtor": { | |
| 1119 | + "r2": 0.759893059204194, | |
| 1120 | + "mdape": 15.486886827978152, | |
| 1121 | + "n": 15356 | |
| 1122 | + }, | |
| 1123 | + "duproprio": { | |
| 1124 | + "r2": 0.5949464270750067, | |
| 1125 | + "mdape": 15.275745119720096, | |
| 1126 | + "n": 3767 | |
| 1127 | + }, | |
| 1128 | + "realtor_no_dollar": { | |
| 1129 | + "r2": 0.7605925812873651, | |
| 1130 | + "mdape": 15.477011341450542, | |
| 1131 | + "n": 14973 | |
| 1132 | + }, | |
| 1133 | + "realtor_dollar": { | |
| 1134 | + "r2": 0.7126936210198105, | |
| 1135 | + "mdape": 15.743669623374457, | |
| 1136 | + "n": 383 | |
| 1137 | + } | |
| 1138 | + } | |
| 1139 | + }, | |
| 1140 | + "L4": { | |
| 1141 | + "ols": { | |
| 1142 | + "all": { | |
| 1143 | + "r2": 0.6862361284601308, | |
| 1144 | + "mdape": 16.886250549053305, | |
| 1145 | + "n": 19123 | |
| 1146 | + }, | |
| 1147 | + "fr": { | |
| 1148 | + "r2": 0.6817811040288533, | |
| 1149 | + "mdape": 16.549619270034732, | |
| 1150 | + "n": 8529 | |
| 1151 | + }, | |
| 1152 | + "en": { | |
| 1153 | + "r2": 0.6475580327790671, | |
| 1154 | + "mdape": 17.346864270432572, | |
| 1155 | + "n": 8250 | |
| 1156 | + }, | |
| 1157 | + "mixed": { | |
| 1158 | + "r2": 0.5785067390470824, | |
| 1159 | + "mdape": 16.704384854470554, | |
| 1160 | + "n": 2344 | |
| 1161 | + }, | |
| 1162 | + "realtor": { | |
| 1163 | + "r2": 0.7457133652165874, | |
| 1164 | + "mdape": 16.72452985313236, | |
| 1165 | + "n": 15356 | |
| 1166 | + }, | |
| 1167 | + "duproprio": { | |
| 1168 | + "r2": 0.1736323411744387, | |
| 1169 | + "mdape": 17.501692059965524, | |
| 1170 | + "n": 3767 | |
| 1171 | + }, | |
| 1172 | + "realtor_no_dollar": { | |
| 1173 | + "r2": 0.7461598824670772, | |
| 1174 | + "mdape": 16.719729060070964, | |
| 1175 | + "n": 14973 | |
| 1176 | + }, | |
| 1177 | + "realtor_dollar": { | |
| 1178 | + "r2": 0.7116091455076672, | |
| 1179 | + "mdape": 17.533352727465633, | |
| 1180 | + "n": 383 | |
| 1181 | + } | |
| 1182 | + }, | |
| 1183 | + "gbm": { | |
| 1184 | + "all": { | |
| 1185 | + "r2": 0.7695283346486282, | |
| 1186 | + "mdape": 14.51330744579874, | |
| 1187 | + "n": 19123 | |
| 1188 | + }, | |
| 1189 | + "fr": { | |
| 1190 | + "r2": 0.7253479216543696, | |
| 1191 | + "mdape": 14.46031369865064, | |
| 1192 | + "n": 8529 | |
| 1193 | + }, | |
| 1194 | + "en": { | |
| 1195 | + "r2": 0.778264514148376, | |
| 1196 | + "mdape": 14.643620058858497, | |
| 1197 | + "n": 8250 | |
| 1198 | + }, | |
| 1199 | + "mixed": { | |
| 1200 | + "r2": 0.6545270741350956, | |
| 1201 | + "mdape": 14.378728382901501, | |
| 1202 | + "n": 2344 | |
| 1203 | + }, | |
| 1204 | + "realtor": { | |
| 1205 | + "r2": 0.7863682394550251, | |
| 1206 | + "mdape": 14.525707627069483, | |
| 1207 | + "n": 15356 | |
| 1208 | + }, | |
| 1209 | + "duproprio": { | |
| 1210 | + "r2": 0.6232264858455447, | |
| 1211 | + "mdape": 14.47846798385848, | |
| 1212 | + "n": 3767 | |
| 1213 | + }, | |
| 1214 | + "realtor_no_dollar": { | |
| 1215 | + "r2": 0.7868299233238455, | |
| 1216 | + "mdape": 14.47554680491181, | |
| 1217 | + "n": 14973 | |
| 1218 | + }, | |
| 1219 | + "realtor_dollar": { | |
| 1220 | + "r2": 0.7530456374467777, | |
| 1221 | + "mdape": 16.399813913922358, | |
| 1222 | + "n": 383 | |
| 1223 | + } | |
| 1224 | + } | |
| 1225 | + }, | |
| 1226 | + "L4+lang": { | |
| 1227 | + "ols": { | |
| 1228 | + "all": { | |
| 1229 | + "r2": 0.6918219402558234, | |
| 1230 | + "mdape": 17.05842969137551, | |
| 1231 | + "n": 19123 | |
| 1232 | + }, | |
| 1233 | + "fr": { | |
| 1234 | + "r2": 0.6848202625030179, | |
| 1235 | + "mdape": 16.44751046246582, | |
| 1236 | + "n": 8529 | |
| 1237 | + }, | |
| 1238 | + "en": { | |
| 1239 | + "r2": 0.6556500054964745, | |
| 1240 | + "mdape": 17.969645215659618, | |
| 1241 | + "n": 8250 | |
| 1242 | + }, | |
| 1243 | + "mixed": { | |
| 1244 | + "r2": 0.5873961733720046, | |
| 1245 | + "mdape": 16.318174197559664, | |
| 1246 | + "n": 2344 | |
| 1247 | + }, | |
| 1248 | + "realtor": { | |
| 1249 | + "r2": 0.7491992618321922, | |
| 1250 | + "mdape": 16.889568595460148, | |
| 1251 | + "n": 15356 | |
| 1252 | + }, | |
| 1253 | + "duproprio": { | |
| 1254 | + "r2": 0.19727097971713214, | |
| 1255 | + "mdape": 17.623612689876687, | |
| 1256 | + "n": 3767 | |
| 1257 | + }, | |
| 1258 | + "realtor_no_dollar": { | |
| 1259 | + "r2": 0.7497042048836837, | |
| 1260 | + "mdape": 16.866036879518553, | |
| 1261 | + "n": 14973 | |
| 1262 | + }, | |
| 1263 | + "realtor_dollar": { | |
| 1264 | + "r2": 0.7120793153718732, | |
| 1265 | + "mdape": 18.12518321567541, | |
| 1266 | + "n": 383 | |
| 1267 | + } | |
| 1268 | + }, | |
| 1269 | + "gbm": { | |
| 1270 | + "all": { | |
| 1271 | + "r2": 0.7739919121365599, | |
| 1272 | + "mdape": 14.660130306531617, | |
| 1273 | + "n": 19123 | |
| 1274 | + }, | |
| 1275 | + "fr": { | |
| 1276 | + "r2": 0.7315945900254126, | |
| 1277 | + "mdape": 14.340490957027995, | |
| 1278 | + "n": 8529 | |
| 1279 | + }, | |
| 1280 | + "en": { | |
| 1281 | + "r2": 0.7829445306690427, | |
| 1282 | + "mdape": 15.041590592111891, | |
| 1283 | + "n": 8250 | |
| 1284 | + }, | |
| 1285 | + "mixed": { | |
| 1286 | + "r2": 0.6540433100870278, | |
| 1287 | + "mdape": 14.606359395894236, | |
| 1288 | + "n": 2344 | |
| 1289 | + }, | |
| 1290 | + "realtor": { | |
| 1291 | + "r2": 0.7911014627627309, | |
| 1292 | + "mdape": 14.672233578074334, | |
| 1293 | + "n": 15356 | |
| 1294 | + }, | |
| 1295 | + "duproprio": { | |
| 1296 | + "r2": 0.625414636946326, | |
| 1297 | + "mdape": 14.607433277890847, | |
| 1298 | + "n": 3767 | |
| 1299 | + }, | |
| 1300 | + "realtor_no_dollar": { | |
| 1301 | + "r2": 0.7916939317014717, | |
| 1302 | + "mdape": 14.613188884594253, | |
| 1303 | + "n": 14973 | |
| 1304 | + }, | |
| 1305 | + "realtor_dollar": { | |
| 1306 | + "r2": 0.750907388936689, | |
| 1307 | + "mdape": 16.528013917646, | |
| 1308 | + "n": 383 | |
| 1309 | + } | |
| 1310 | + } | |
| 1311 | + } | |
| 1312 | + }, | |
| 1313 | + "spatial_fsa": { | |
| 1314 | + "L2": { | |
| 1315 | + "ols": { | |
| 1316 | + "all": { | |
| 1317 | + "r2": 0.561152632188157, | |
| 1318 | + "mdape": 19.8122629574087, | |
| 1319 | + "n": 19123 | |
| 1320 | + }, | |
| 1321 | + "fr": { | |
| 1322 | + "r2": 0.5436228623065937, | |
| 1323 | + "mdape": 19.850036519194923, | |
| 1324 | + "n": 8529 | |
| 1325 | + }, | |
| 1326 | + "en": { | |
| 1327 | + "r2": 0.5093877463581487, | |
| 1328 | + "mdape": 20.06619110315462, | |
| 1329 | + "n": 8250 | |
| 1330 | + }, | |
| 1331 | + "mixed": { | |
| 1332 | + "r2": 0.45214336918664666, | |
| 1333 | + "mdape": 18.980286279205327, | |
| 1334 | + "n": 2344 | |
| 1335 | + }, | |
| 1336 | + "realtor": { | |
| 1337 | + "r2": 0.6383752583912143, | |
| 1338 | + "mdape": 19.80884641164214, | |
| 1339 | + "n": 15356 | |
| 1340 | + }, | |
| 1341 | + "duproprio": { | |
| 1342 | + "r2": -0.10464893757308857, | |
| 1343 | + "mdape": 19.82009565718741, | |
| 1344 | + "n": 3767 | |
| 1345 | + }, | |
| 1346 | + "realtor_no_dollar": { | |
| 1347 | + "r2": 0.6404969934965723, | |
| 1348 | + "mdape": 19.802748905552157, | |
| 1349 | + "n": 14973 | |
| 1350 | + }, | |
| 1351 | + "realtor_dollar": { | |
| 1352 | + "r2": 0.5096440585931159, | |
| 1353 | + "mdape": 20.478078816372538, | |
| 1354 | + "n": 383 | |
| 1355 | + } | |
| 1356 | + }, | |
| 1357 | + "gbm": { | |
| 1358 | + "all": { | |
| 1359 | + "r2": 0.6900603053345207, | |
| 1360 | + "mdape": 17.36473761406859, | |
| 1361 | + "n": 19123 | |
| 1362 | + }, | |
| 1363 | + "fr": { | |
| 1364 | + "r2": 0.6421621168538105, | |
| 1365 | + "mdape": 17.42109930626754, | |
| 1366 | + "n": 8529 | |
| 1367 | + }, | |
| 1368 | + "en": { | |
| 1369 | + "r2": 0.688718243018579, | |
| 1370 | + "mdape": 17.578917479700877, | |
| 1371 | + "n": 8250 | |
| 1372 | + }, | |
| 1373 | + "mixed": { | |
| 1374 | + "r2": 0.5626362403363072, | |
| 1375 | + "mdape": 16.720707329024247, | |
| 1376 | + "n": 2344 | |
| 1377 | + }, | |
| 1378 | + "realtor": { | |
| 1379 | + "r2": 0.7084391615866306, | |
| 1380 | + "mdape": 17.589008031592723, | |
| 1381 | + "n": 15356 | |
| 1382 | + }, | |
| 1383 | + "duproprio": { | |
| 1384 | + "r2": 0.5299069645374576, | |
| 1385 | + "mdape": 16.726463097764288, | |
| 1386 | + "n": 3767 | |
| 1387 | + }, | |
| 1388 | + "realtor_no_dollar": { | |
| 1389 | + "r2": 0.7096364090475892, | |
| 1390 | + "mdape": 17.51468334836437, | |
| 1391 | + "n": 14973 | |
| 1392 | + }, | |
| 1393 | + "realtor_dollar": { | |
| 1394 | + "r2": 0.6323550861606284, | |
| 1395 | + "mdape": 19.93521616887506, | |
| 1396 | + "n": 383 | |
| 1397 | + } | |
| 1398 | + } | |
| 1399 | + }, | |
| 1400 | + "L3": { | |
| 1401 | + "ols": { | |
| 1402 | + "all": { | |
| 1403 | + "r2": 0.5683290219864456, | |
| 1404 | + "mdape": 19.696362770568044, | |
| 1405 | + "n": 19123 | |
| 1406 | + }, | |
| 1407 | + "fr": { | |
| 1408 | + "r2": 0.5575537822847219, | |
| 1409 | + "mdape": 19.696362770568044, | |
| 1410 | + "n": 8529 | |
| 1411 | + }, | |
| 1412 | + "en": { | |
| 1413 | + "r2": 0.5117836597388852, | |
| 1414 | + "mdape": 20.17205138796668, | |
| 1415 | + "n": 8250 | |
| 1416 | + }, | |
| 1417 | + "mixed": { | |
| 1418 | + "r2": 0.4651719300088949, | |
| 1419 | + "mdape": 18.382741889852255, | |
| 1420 | + "n": 2344 | |
| 1421 | + }, | |
| 1422 | + "realtor": { | |
| 1423 | + "r2": 0.6447326358277227, | |
| 1424 | + "mdape": 19.770188248697007, | |
| 1425 | + "n": 15356 | |
| 1426 | + }, | |
| 1427 | + "duproprio": { | |
| 1428 | + "r2": -0.09039036304700909, | |
| 1429 | + "mdape": 19.168513527868257, | |
| 1430 | + "n": 3767 | |
| 1431 | + }, | |
| 1432 | + "realtor_no_dollar": { | |
| 1433 | + "r2": 0.6466015938683551, | |
| 1434 | + "mdape": 19.77069646918952, | |
| 1435 | + "n": 14973 | |
| 1436 | + }, | |
| 1437 | + "realtor_dollar": { | |
| 1438 | + "r2": 0.5298926526744645, | |
| 1439 | + "mdape": 19.47742298405968, | |
| 1440 | + "n": 383 | |
| 1441 | + } | |
| 1442 | + }, | |
| 1443 | + "gbm": { | |
| 1444 | + "all": { | |
| 1445 | + "r2": 0.703325356512492, | |
| 1446 | + "mdape": 16.92646835300644, | |
| 1447 | + "n": 19123 | |
| 1448 | + }, | |
| 1449 | + "fr": { | |
| 1450 | + "r2": 0.6552480572864873, | |
| 1451 | + "mdape": 17.055597496403728, | |
| 1452 | + "n": 8529 | |
| 1453 | + }, | |
| 1454 | + "en": { | |
| 1455 | + "r2": 0.7028836188129218, | |
| 1456 | + "mdape": 17.028422588392417, | |
| 1457 | + "n": 8250 | |
| 1458 | + }, | |
| 1459 | + "mixed": { | |
| 1460 | + "r2": 0.5870853107740306, | |
| 1461 | + "mdape": 16.184764318197765, | |
| 1462 | + "n": 2344 | |
| 1463 | + }, | |
| 1464 | + "realtor": { | |
| 1465 | + "r2": 0.7198598672622852, | |
| 1466 | + "mdape": 17.108202343453787, | |
| 1467 | + "n": 15356 | |
| 1468 | + }, | |
| 1469 | + "duproprio": { | |
| 1470 | + "r2": 0.5590966224265139, | |
| 1471 | + "mdape": 16.19589147436422, | |
| 1472 | + "n": 3767 | |
| 1473 | + }, | |
| 1474 | + "realtor_no_dollar": { | |
| 1475 | + "r2": 0.7208304950463407, | |
| 1476 | + "mdape": 17.067268687449612, | |
| 1477 | + "n": 14973 | |
| 1478 | + }, | |
| 1479 | + "realtor_dollar": { | |
| 1480 | + "r2": 0.6564547166743768, | |
| 1481 | + "mdape": 18.835113176242313, | |
| 1482 | + "n": 383 | |
| 1483 | + } | |
| 1484 | + } | |
| 1485 | + }, | |
| 1486 | + "L4": { | |
| 1487 | + "ols": { | |
| 1488 | + "all": { | |
| 1489 | + "r2": 0.6381422132480896, | |
| 1490 | + "mdape": 18.49345368946045, | |
| 1491 | + "n": 19123 | |
| 1492 | + }, | |
| 1493 | + "fr": { | |
| 1494 | + "r2": 0.6211566818465292, | |
| 1495 | + "mdape": 18.3535836331989, | |
| 1496 | + "n": 8529 | |
| 1497 | + }, | |
| 1498 | + "en": { | |
| 1499 | + "r2": 0.6003735880556736, | |
| 1500 | + "mdape": 18.942228673010565, | |
| 1501 | + "n": 8250 | |
| 1502 | + }, | |
| 1503 | + "mixed": { | |
| 1504 | + "r2": 0.5290156505057976, | |
| 1505 | + "mdape": 17.651464780500543, | |
| 1506 | + "n": 2344 | |
| 1507 | + }, | |
| 1508 | + "realtor": { | |
| 1509 | + "r2": 0.6962614111103841, | |
| 1510 | + "mdape": 18.543247515599763, | |
| 1511 | + "n": 15356 | |
| 1512 | + }, | |
| 1513 | + "duproprio": { | |
| 1514 | + "r2": 0.13678723222681555, | |
| 1515 | + "mdape": 18.1567191029959, | |
| 1516 | + "n": 3767 | |
| 1517 | + }, | |
| 1518 | + "realtor_no_dollar": { | |
| 1519 | + "r2": 0.6969711627496079, | |
| 1520 | + "mdape": 18.54890748611919, | |
| 1521 | + "n": 14973 | |
| 1522 | + }, | |
| 1523 | + "realtor_dollar": { | |
| 1524 | + "r2": 0.6460055512251979, | |
| 1525 | + "mdape": 18.517320831845442, | |
| 1526 | + "n": 383 | |
| 1527 | + } | |
| 1528 | + }, | |
| 1529 | + "gbm": { | |
| 1530 | + "all": { | |
| 1531 | + "r2": 0.734096966551949, | |
| 1532 | + "mdape": 15.888054640539362, | |
| 1533 | + "n": 19123 | |
| 1534 | + }, | |
| 1535 | + "fr": { | |
| 1536 | + "r2": 0.6911138535952995, | |
| 1537 | + "mdape": 15.919851278981433, | |
| 1538 | + "n": 8529 | |
| 1539 | + }, | |
| 1540 | + "en": { | |
| 1541 | + "r2": 0.7340026687012777, | |
| 1542 | + "mdape": 15.992640300870665, | |
| 1543 | + "n": 8250 | |
| 1544 | + }, | |
| 1545 | + "mixed": { | |
| 1546 | + "r2": 0.6274103220648997, | |
| 1547 | + "mdape": 15.54977512173467, | |
| 1548 | + "n": 2344 | |
| 1549 | + }, | |
| 1550 | + "realtor": { | |
| 1551 | + "r2": 0.7503670054946096, | |
| 1552 | + "mdape": 16.021849103126563, | |
| 1553 | + "n": 15356 | |
| 1554 | + }, | |
| 1555 | + "duproprio": { | |
| 1556 | + "r2": 0.5923896983212749, | |
| 1557 | + "mdape": 15.366955189063702, | |
| 1558 | + "n": 3767 | |
| 1559 | + }, | |
| 1560 | + "realtor_no_dollar": { | |
| 1561 | + "r2": 0.7509438656783993, | |
| 1562 | + "mdape": 16.011707563208976, | |
| 1563 | + "n": 14973 | |
| 1564 | + }, | |
| 1565 | + "realtor_dollar": { | |
| 1566 | + "r2": 0.7094120414845118, | |
| 1567 | + "mdape": 17.180879411943394, | |
| 1568 | + "n": 383 | |
| 1569 | + } | |
| 1570 | + } | |
| 1571 | + } | |
| 1572 | + }, | |
| 1573 | + "spatial_groups": 420 | |
| 1574 | + }, | |
| 1575 | + "blend": { | |
| 1576 | + "gbm_v5_r2": 0.7695283346486282, | |
| 1577 | + "nn_v5_r2_recovered": 0.7469006651629047, | |
| 1578 | + "blend_v5_r2_file": 0.7785721006736874, | |
| 1579 | + "gbm_v4_r2": 0.7428875872402715, | |
| 1580 | + "nn_v4_r2": 0.7411448851921381, | |
| 1581 | + "grid_v5": { | |
| 1582 | + "0.0": 0.7469006651629047, | |
| 1583 | + "0.3": 0.7707893506536754, | |
| 1584 | + "0.4": 0.7754950296943983, | |
| 1585 | + "0.5": 0.7785721006736874, | |
| 1586 | + "0.6": 0.780020563591543, | |
| 1587 | + "0.7": 0.7798404184479648, | |
| 1588 | + "1.0": 0.7695283346486282 | |
| 1589 | + }, | |
| 1590 | + "grid_v4": { | |
| 1591 | + "0.0": 0.7411448851921381, | |
| 1592 | + "0.3": 0.7570425008571054, | |
| 1593 | + "0.4": 0.7594131717834227, | |
| 1594 | + "0.5": 0.7603195755620706, | |
| 1595 | + "0.6": 0.7597617121930493, | |
| 1596 | + "0.7": 0.7577395816763588, | |
| 1597 | + "1.0": 0.7428875872402715 | |
| 1598 | + }, | |
| 1599 | + "blend_v5_by_group": { | |
| 1600 | + "all": { | |
| 1601 | + "r2": 0.7785721006736874, | |
| 1602 | + "mdape": 13.983708727480337, | |
| 1603 | + "n": 19123 | |
| 1604 | + }, | |
| 1605 | + "fr": { | |
| 1606 | + "r2": 0.7454923406571599, | |
| 1607 | + "mdape": 13.773788135957732, | |
| 1608 | + "n": 8529 | |
| 1609 | + }, | |
| 1610 | + "en": { | |
| 1611 | + "r2": 0.779432498811204, | |
| 1612 | + "mdape": 14.17923446423391, | |
| 1613 | + "n": 8250 | |
| 1614 | + }, | |
| 1615 | + "mixed": { | |
| 1616 | + "r2": 0.669968204605575, | |
| 1617 | + "mdape": 13.83430917757124, | |
| 1618 | + "n": 2344 | |
| 1619 | + }, | |
| 1620 | + "realtor": { | |
| 1621 | + "r2": 0.8016868730465586, | |
| 1622 | + "mdape": 13.985264681378295, | |
| 1623 | + "n": 15356 | |
| 1624 | + }, | |
| 1625 | + "duproprio": { | |
| 1626 | + "r2": 0.5785377526665498, | |
| 1627 | + "mdape": 13.958402264967651, | |
| 1628 | + "n": 3767 | |
| 1629 | + }, | |
| 1630 | + "realtor_no_dollar": { | |
| 1631 | + "r2": 0.8018784945115782, | |
| 1632 | + "mdape": 13.974096909707988, | |
| 1633 | + "n": 14973 | |
| 1634 | + }, | |
| 1635 | + "realtor_dollar": { | |
| 1636 | + "r2": 0.7835409769902336, | |
| 1637 | + "mdape": 15.124945766929043, | |
| 1638 | + "n": 383 | |
| 1639 | + } | |
| 1640 | + }, | |
| 1641 | + "nested_weight_r2": 0.7752721723613206 | |
| 1642 | + } | |
| 1643 | +} | |
| \ No newline at end of file | ||
modified
scripts/11_extras_v5_robustness.py
+1 −1
@@ -7,7 +7,7 @@ warnings.filterwarnings("ignore") | ||
| 7 | 7 | plt.rcParams.update({"font.family":"serif","font.size":10,"axes.grid":True, |
| 8 | 8 | "grid.alpha":0.25,"axes.axisbelow":True,"figure.dpi":150,"savefig.bbox":"tight"}) |
| 9 | 9 | C1,C2,C3="#3B6EA5","#C4462E","#4A8C5B" |
| 10 | −exec(open("v5_ml.py").read().split("kf=KFold")[0]) | |
| 10 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 11 | 11 | amen_=list(AMEN.keys()) |
| 12 | 12 | bl=np.load("data/processed/v5_blend_oos.npy"); price=df["price"].values; y=np.log(price) |
| 13 | 13 | from sklearn.metrics import r2_score |
modified
scripts/12_ablation_extras.py
+1 −1
@@ -9,7 +9,7 @@ from sklearn.model_selection import KFold, cross_val_predict | ||
| 9 | 9 | from sklearn.metrics import r2_score |
| 10 | 10 | warnings.filterwarnings("ignore") |
| 11 | 11 | |
| 12 | −exec(open("v5_ml.py").read().split("kf=KFold")[0]) | |
| 12 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 13 | 13 | kf = KFold(n_splits=5, shuffle=True, random_state=42) |
| 14 | 14 | amen_ = list(AMEN.keys()) |
| 15 | 15 | |
modified
scripts/13_revision_extras.py
+1 −1
@@ -17,7 +17,7 @@ from sklearn.metrics import r2_score | ||
| 17 | 17 | warnings.filterwarnings("ignore") |
| 18 | 18 | |
| 19 | 19 | # pipeline v5 jusqu'avant la CV (construit df, AMEN, rv, gv, vv, NUM_v4, NUM_v5, MISS, cats, y, kf) |
| 20 | −exec(open("v5_ml.py").read().split("kf=KFold")[0]) | |
| 20 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 21 | 21 | amen_ = list(AMEN.keys()) |
| 22 | 22 | out = {} |
| 23 | 23 | |
modified
scripts/14_figures_v5.py
+1 −1
@@ -16,7 +16,7 @@ plt.rcParams.update({"font.family":"serif","font.size":10,"axes.grid":True, | ||
| 16 | 16 | C_OLS,C_GBM,C_BL="#3B6EA5","#C4462E","#4A8C5B" |
| 17 | 17 | |
| 18 | 18 | # build df via v5_ml prefix |
| 19 | −exec(open("v5_ml.py").read().split("kf=KFold")[0]) | |
| 19 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 20 | 20 | kf=KFold(n_splits=5,shuffle=True,random_state=42) |
| 21 | 21 | onehot=pd.get_dummies(df[cats],dtype=float).reset_index(drop=True) |
| 22 | 22 | |
modified
scripts/16_make_tables_v5.py
+3 −3
@@ -4,7 +4,7 @@ | ||
| 4 | 4 | import numpy as np, pandas as pd, statsmodels.formula.api as smf, warnings |
| 5 | 5 | warnings.filterwarnings("ignore") |
| 6 | 6 | # construire df via le pipeline de v5_ml (jusqu'avant la CV) |
| 7 | −exec(open("v5_ml.py").read().split("kf=KFold")[0]) | |
| 7 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 8 | 8 | amen_=list(AMEN.keys()) |
| 9 | 9 | df["ln_price"]=np.log(df["price"]) |
| 10 | 10 | df["ln_sqft"]=np.log(df["sqft_final"].fillna(df.groupby("ptype")["sqft_final"].transform("median")).fillna(df["sqft_final"].median())) |
@@ -111,8 +111,8 @@ models=r"""% Auto-generated v5 | ||
| 111 | 111 | common seed (identical folds across rows). $R^2_{\text{OOS}}$ is on |
| 112 | 112 | $\ln(\text{Price})$; ``Median AE'' is the median absolute percentage error in |
| 113 | 113 | levels (Equation~\ref{eq:cvmetrics}). Panel~A uses structural, amenity, room-detail, |
| 114 | − listing-signal, and LLM text-derived features; Panel~B adds the twelve façade | |
| 115 | − vision attributes. City, type, and source enter as one-hot indicators for the | |
| 114 | + listing-signal, and LLM text-derived features; Panel~B adds the façade | |
| 115 | + vision layer (21 regressors derived from the twelve schema fields). City, type, and source enter as one-hot indicators for the | |
| 116 | 116 | linear and tree models and as learned embeddings for the neural networks. The tree |
| 117 | 117 | and neural models handle missing living area natively. The best model is the |
| 118 | 118 | text\,+\,vision blend. |
added
scripts/18_revision_language_leakage_spatial.py
+284 −0
@@ -0,0 +1,284 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +# -*- coding: utf-8 -*- | |
| 3 | +"""Révision scientifique 2026-10-17 (editorial board) — réanalyses locales, sans appel API. | |
| 4 | + | |
| 5 | + (a) langue de la description (FR / EN / mixte, règle de stop-words comme WP 2) et indicatrice de langue ; | |
| 6 | + (b) fuite d'information : prix demandé et évaluation municipale présents dans le texte lu par le LLM | |
| 7 | + (100 % des descriptions DuProprio contiennent « Asking Price $… ») -> gains de la couche texte par source, | |
| 8 | + par présence d'un montant en dollars ; | |
| 9 | + (c) effets fixes plus fins (RTA = 3 premiers caractères du code postal) et validation spatiale | |
| 10 | + (GroupKFold par RTA) vs 5-fold aléatoire ; | |
| 11 | + (d) bootstrap en grappes (municipalités) des coefficients IA du modèle A ; | |
| 12 | + (e) accord inter-sources des extractions (LLM vs mots-clés / champs structurés ; vision vs texte / structuré) ; | |
| 13 | + (f) sensibilité du blend au poids w et vérification du 50/50. | |
| 14 | + | |
| 15 | +Résultats -> results/revision_2026-10-17.json ; les tables LaTeX (paper/tables/rob_*.tex, agreement.tex) sont ensuite | |
| 16 | +générées par scripts/19_make_revision_tables.py à partir du JSON. | |
| 17 | +Exécution : ~3 min sur un Mac Apple Silicon M-series (9 validations croisées GBM, 299 réplications bootstrap). | |
| 18 | +""" | |
| 19 | +import json, re, time, warnings | |
| 20 | +import numpy as np, pandas as pd | |
| 21 | +import statsmodels.formula.api as smf | |
| 22 | +from sklearn.linear_model import LinearRegression | |
| 23 | +from sklearn.ensemble import HistGradientBoostingRegressor | |
| 24 | +from sklearn.model_selection import KFold, GroupKFold, cross_val_predict | |
| 25 | +from sklearn.metrics import r2_score | |
| 26 | +warnings.filterwarnings("ignore") | |
| 27 | +T0 = time.time() | |
| 28 | + | |
| 29 | +# pipeline v5 jusqu'avant la CV : df, y, data, specs, facade, AMEN, rv, gv, vv, NUM_v4, NUM_v5, cats | |
| 30 | +exec(open("scripts/09_v5_ml_text_vision.py").read().split("kf=KFold")[0]) | |
| 31 | +amen_ = list(AMEN.keys()) | |
| 32 | +y32 = y.copy() # float32, exactly as in scripts 09/12 (keeps the GBM fits identical to the paper's tables) | |
| 33 | +y = y.astype(np.float64) | |
| 34 | +OUT = {} | |
| 35 | + | |
| 36 | +# ------------------------------------------------------------------ texte, langue, code postal | |
| 37 | +meta = {} | |
| 38 | +for d in data: | |
| 39 | + uid = f"{d.get('source')}:{d.get('listingId')}" | |
| 40 | + meta[uid] = ((d.get("description") or ""), ((d.get("address") or {}).get("postalCode") or "")) | |
| 41 | +desc = df["uid"].map(lambda u: meta[u][0]) | |
| 42 | +pc = df["uid"].map(lambda u: meta[u][1]).str.upper().str.replace(" ", "", regex=False) | |
| 43 | +df["fsa"] = pc.str[:3].where(pc.str.len() >= 3, "") | |
| 44 | + | |
| 45 | +EN = set("the and with this that for from has have is are of to in on your you its it be by".split()) | |
| 46 | +FR = set("le la les et avec cette ce pour des une un du au aux est sont vous votre dans sur qui que".split()) | |
| 47 | +def detect_language(t): | |
| 48 | + w = re.findall(r"[a-zàâçéèêëîïôûùüÿœ']+", t.lower()) | |
| 49 | + e = sum(1 for x in w if x in EN); f = sum(1 for x in w if x in FR) | |
| 50 | + if e == 0 and f == 0: return "mixed" | |
| 51 | + if e >= 1.5 * f: return "en" | |
| 52 | + if f >= 1.5 * e: return "fr" | |
| 53 | + return "mixed" | |
| 54 | +df["lang"] = [detect_language(t) for t in desc] | |
| 55 | +df["lang_en"] = (df["lang"] == "en").astype(int); df["lang_mixed"] = (df["lang"] == "mixed").astype(int) | |
| 56 | +df["desc_len"] = desc.str.len().clip(upper=6000) / 1000.0 | |
| 57 | + | |
| 58 | +DOLLAR = re.compile(r"\d[\d\s,.]{3,}\s?\$|\$\s?\d[\d,.]{3,}") | |
| 59 | +ASSESS = re.compile(r"(évaluation municipale|evaluation municipale|valeur municipale|municipal assessment|municipal (evaluation|valuation)|évalu[ée]e? à|assessed at)", re.I) | |
| 60 | +ASKING = re.compile(r"Asking Price\s*\$?\s*([\d,]+)", re.I) | |
| 61 | +df["price_in_text"] = [int(bool(DOLLAR.search(t))) for t in desc] | |
| 62 | +df["assess_in_text"] = [int(bool(ASSESS.search(t))) for t in desc] | |
| 63 | +ask = [ASKING.search(t) for t in desc] | |
| 64 | +df["asking_in_text"] = [int(m is not None) for m in ask] | |
| 65 | +eq = sum(1 for m, p in zip(ask, df["price"]) if m and int(m.group(1).replace(",", "")) == int(p)) | |
| 66 | +OUT["text_leakage"] = { | |
| 67 | + "n": int(len(df)), | |
| 68 | + "asking_price_in_text": int(df["asking_in_text"].sum()), | |
| 69 | + "asking_price_equals_list_price": int(eq), | |
| 70 | + "asking_by_source": df.groupby("source")["asking_in_text"].sum().astype(int).to_dict(), | |
| 71 | + "dollar_amount_in_text": int(df["price_in_text"].sum()), | |
| 72 | + "dollar_by_source": df.groupby("source")["price_in_text"].mean().round(4).to_dict(), | |
| 73 | + "assessment_mention": int(df["assess_in_text"].sum()), | |
| 74 | + "assessment_by_source": df.groupby("source")["assess_in_text"].mean().round(4).to_dict(), | |
| 75 | + "realtor_dollar_share": float(df.loc[df.source == "realtor", "price_in_text"].mean()), | |
| 76 | +} | |
| 77 | +print("leakage:", OUT["text_leakage"]) | |
| 78 | + | |
| 79 | +lang_tab = (df.assign(lnp=np.log(df["price"])) | |
| 80 | + .groupby(["source", "lang"]).agg(n=("price", "size"), median_price=("price", "median"), | |
| 81 | + mean_lnp=("lnp", "mean"), desc_len=("desc_len", "mean")) | |
| 82 | + .reset_index()) | |
| 83 | +OUT["language"] = {"by_source": lang_tab.to_dict(orient="records"), | |
| 84 | + "share_en_overall": float(df["lang_en"].mean()), | |
| 85 | + "share_en_realtor": float(df.loc[df.source == "realtor", "lang_en"].mean()), | |
| 86 | + "share_by_lang": df["lang"].value_counts(normalize=True).round(4).to_dict()} | |
| 87 | +print(lang_tab) | |
| 88 | + | |
| 89 | +# ------------------------------------------------------------------ coverage of AI layers | |
| 90 | +df["has_specs"] = df["uid"].map(lambda u: int(u in specs)); df["has_facade"] = df["uid"].map(lambda u: int(u in facade)) | |
| 91 | +OUT["coverage"] = {"specs": int(df.has_specs.sum()), "facade": int(df.has_facade.sum()), | |
| 92 | + "is_exterior": int(df.v_is_ext.sum()), "n": int(len(df))} | |
| 93 | +print("coverage:", OUT["coverage"]) | |
| 94 | + | |
| 95 | +# ------------------------------------------------------------------ OLS helpers | |
| 96 | +df_cv = df.copy() # pristine copy (NaN kept) for the tree models; the OLS block below imputes df in place | |
| 97 | +df["ln_price"] = np.log(df["price"]) | |
| 98 | +df["ln_sqft"] = np.log(df["sqft_final"].fillna(df.groupby("ptype")["sqft_final"].transform("median")).fillna(df["sqft_final"].median())) | |
| 99 | +df["ln_lot"] = np.log(df["lot_sqft"].fillna(df["lot_sqft"].median())); df["has_lot"] = df["lot_sqft"].notna().astype(int) | |
| 100 | +df["has_age"] = df["age"].notna().astype(int) | |
| 101 | +for c in ["beds", "baths", "storeys", "age", "age2"]: | |
| 102 | + df[c] = df[c].fillna(df.groupby("ptype")[c].transform("median")).fillna(df[c].median()) | |
| 103 | +df["parking"] = df["parking"].fillna(0) | |
| 104 | +vc = df["fsa"].value_counts(); keepf = set(vc[(vc >= 20)].index) - {""} | |
| 105 | +df["fsa_fe"] = df["fsa"].where(df["fsa"].isin(keepf), "__other__") | |
| 106 | +OUT["fsa"] = {"n_fsa_raw": int(df.loc[df.fsa != "", "fsa"].nunique()), "n_fsa_fe": int(df["fsa_fe"].nunique()), | |
| 107 | + "n_city_fe": int(df["city_fe"].nunique())} | |
| 108 | +print("FSA:", OUT["fsa"]) | |
| 109 | + | |
| 110 | +CORE = ("ln_lot+has_lot+beds+baths+parking+storeys+age+age2+has_age+C(source)+C(ptype_fe)+" | |
| 111 | + + "+".join(amen_) + "+n_images_c+virtual_tour+" + "+".join(rv)) | |
| 112 | +TEXT = "+".join(gv); VIS = "+".join(vv) | |
| 113 | +def form(fe="C(city_fe)", area=True, text=True, vis=True, extra=""): | |
| 114 | + f = "ln_price ~ " + ("ln_sqft+" if area else "") + CORE | |
| 115 | + if text: f += "+" + TEXT | |
| 116 | + if vis: f += "+" + VIS | |
| 117 | + if extra: f += "+" + extra | |
| 118 | + return f + "+" + fe | |
| 119 | +KEYS = ["v_curb", "v_reno", "v_luxury", "v_garage_vis", "v_mat_brique", "v_mat_pierre", "v_mat_vinyle", "v_set_rural", | |
| 120 | + "v_land", "g_cond", "g_renovated_kitchen", "g_hardwood", "g_income_property", "lang_en", "lang_mixed"] | |
| 121 | +def grab(m): | |
| 122 | + return {k: {"b": float(m.params[k]), "se": float(m.bse[k]), "p": float(m.pvalues[k])} for k in KEYS if k in m.params.index} | |
| 123 | +def fit(f, d, groups): | |
| 124 | + return smf.ols(f, data=d).fit(cov_type="cluster", cov_kwds={"groups": d[groups]}) | |
| 125 | +def ablation(d, fe="C(city_fe)", area=True): | |
| 126 | + r = {} | |
| 127 | + for nm, (t, v) in {"base": (False, False), "plus_text": (True, False), "plus_text_vision": (True, True)}.items(): | |
| 128 | + r[nm] = float(smf.ols(form(fe, area, t, v), data=d).fit().rsquared) | |
| 129 | + r["n"] = int(len(d)); r["d_text"] = r["plus_text"] - r["base"]; r["d_vision"] = r["plus_text_vision"] - r["plus_text"] | |
| 130 | + return r | |
| 131 | + | |
| 132 | +dfA = df[df["has_sqft"] == 1].copy() | |
| 133 | + | |
| 134 | +# ------------------------------------------------------------------ (a) language indicator | |
| 135 | +mA = fit(form(), dfA, "city_fe") | |
| 136 | +mA_lang = fit(form(extra="lang_en+lang_mixed+desc_len"), dfA, "city_fe") | |
| 137 | +mB = fit(form(area=False), df, "city_fe") | |
| 138 | +mB_lang = fit(form(area=False, extra="lang_en+lang_mixed+desc_len"), df, "city_fe") | |
| 139 | +OUT["ols"] = {"A": {"r2": mA.rsquared, "n": int(mA.nobs), "coef": grab(mA)}, | |
| 140 | + "A_lang": {"r2": mA_lang.rsquared, "n": int(mA_lang.nobs), "coef": grab(mA_lang)}, | |
| 141 | + "B": {"r2": mB.rsquared, "n": int(mB.nobs), "coef": grab(mB)}, | |
| 142 | + "B_lang": {"r2": mB_lang.rsquared, "n": int(mB_lang.nobs), "coef": grab(mB_lang)}} | |
| 143 | +print("lang_en A:", OUT["ols"]["A_lang"]["coef"]["lang_en"], "| B:", OUT["ols"]["B_lang"]["coef"]["lang_en"]) | |
| 144 | +# raw language gap (no controls, city FE only) | |
| 145 | +m_gap = smf.ols("ln_price ~ lang_en + lang_mixed + C(source) + C(city_fe)", data=df).fit() | |
| 146 | +OUT["language"]["raw_gap_en_cityFE"] = float(m_gap.params["lang_en"]) | |
| 147 | +OUT["language"]["raw_gap_en_nocontrols"] = float(smf.ols("ln_price ~ lang_en + lang_mixed", data=df).fit().params["lang_en"]) | |
| 148 | + | |
| 149 | +# in-sample ablation by language / source / price-in-text (model A, city FE) | |
| 150 | +OUT["ablation_A"] = {"all": ablation(dfA), | |
| 151 | + "fr": ablation(dfA[dfA.lang == "fr"]), "en": ablation(dfA[dfA.lang == "en"]), | |
| 152 | + "mixed": ablation(dfA[dfA.lang == "mixed"]), | |
| 153 | + "realtor": ablation(dfA[dfA.source == "realtor"]), "duproprio": ablation(dfA[dfA.source == "duproprio"]), | |
| 154 | + "realtor_no_dollar": ablation(dfA[(dfA.source == "realtor") & (dfA.price_in_text == 0)]), | |
| 155 | + "realtor_dollar": ablation(dfA[(dfA.source == "realtor") & (dfA.price_in_text == 1)]), | |
| 156 | + "with_lang": {k: float(v) for k, v in zip(["base", "plus_text", "plus_text_vision"], | |
| 157 | + [smf.ols(form(text=t, vis=v, extra="lang_en+lang_mixed+desc_len"), data=dfA).fit().rsquared | |
| 158 | + for t, v in [(False, False), (True, False), (True, True)]])}} | |
| 159 | +for k, v in OUT["ablation_A"].items(): print("ablation", k, {a: round(b, 4) for a, b in v.items()}) | |
| 160 | + | |
| 161 | +# ------------------------------------------------------------------ (c) FSA fixed effects | |
| 162 | +mA_fsa = fit(form(fe="C(fsa_fe)"), dfA, "fsa_fe"); mB_fsa = fit(form(fe="C(fsa_fe)", area=False), df, "fsa_fe") | |
| 163 | +mA_fsa_lang = fit(form(fe="C(fsa_fe)", extra="lang_en+lang_mixed+desc_len"), dfA, "fsa_fe") | |
| 164 | +OUT["ols"]["A_fsa"] = {"r2": mA_fsa.rsquared, "n": int(mA_fsa.nobs), "coef": grab(mA_fsa)} | |
| 165 | +OUT["ols"]["A_fsa_lang"] = {"r2": mA_fsa_lang.rsquared, "n": int(mA_fsa_lang.nobs), "coef": grab(mA_fsa_lang)} | |
| 166 | +OUT["ols"]["B_fsa"] = {"r2": mB_fsa.rsquared, "n": int(mB_fsa.nobs), "coef": grab(mB_fsa)} | |
| 167 | +OUT["ablation_A"]["fsa_fe"] = ablation(dfA, fe="C(fsa_fe)") | |
| 168 | +# Realtor-only with FSA FE + language (the cleanest specification: no price in text) | |
| 169 | +dR = dfA[dfA.source == "realtor"] | |
| 170 | +mA_realtor = fit(form(fe="C(fsa_fe)", extra="lang_en+lang_mixed+desc_len"), dR, "fsa_fe") | |
| 171 | +OUT["ols"]["A_realtor_fsa_lang"] = {"r2": mA_realtor.rsquared, "n": int(mA_realtor.nobs), "coef": grab(mA_realtor)} | |
| 172 | +print("FSA A R2=%.4f B R2=%.4f realtor-FSA-lang R2=%.4f" % (mA_fsa.rsquared, mB_fsa.rsquared, mA_realtor.rsquared)) | |
| 173 | + | |
| 174 | +# ------------------------------------------------------------------ (d) cluster (pairs) bootstrap, model A | |
| 175 | +import patsy | |
| 176 | +yA, XA = patsy.dmatrices(form(), data=dfA, return_type="dataframe") | |
| 177 | +XA = XA.values; yA = yA.values.ravel(); cols = list(patsy.dmatrices(form(), data=dfA, return_type="dataframe")[1].columns) | |
| 178 | +groups = dfA["city_fe"].values; ug = np.unique(groups); gidx = {g: np.where(groups == g)[0] for g in ug} | |
| 179 | +rng = np.random.RandomState(20261017); B = 299; keep_ix = [cols.index(k) for k in KEYS if k in cols] | |
| 180 | +boot = np.full((B, len(keep_ix)), np.nan) | |
| 181 | +for b in range(B): | |
| 182 | + samp = rng.choice(ug, size=len(ug), replace=True) | |
| 183 | + rows = np.concatenate([gidx[g] for g in samp]) | |
| 184 | + Xb = XA[rows]; yb = yA[rows] | |
| 185 | + nz = Xb.std(0) > 0; nz[0] = True | |
| 186 | + beta = np.full(XA.shape[1], np.nan) | |
| 187 | + beta[nz] = np.linalg.lstsq(Xb[:, nz], yb, rcond=None)[0] | |
| 188 | + boot[b] = beta[keep_ix] | |
| 189 | +OUT["cluster_bootstrap_A"] = {"B": B, "n_clusters": int(len(ug)), | |
| 190 | + "ci95": {k: [float(np.nanpercentile(boot[:, j], 2.5)), float(np.nanpercentile(boot[:, j], 97.5))] | |
| 191 | + for j, k in enumerate([k for k in KEYS if k in cols])}, | |
| 192 | + "se": {k: float(np.nanstd(boot[:, j], ddof=1)) for j, k in enumerate([k for k in KEYS if k in cols])}} | |
| 193 | +print("bootstrap CI:", {k: [round(a, 4) for a in v] for k, v in OUT["cluster_bootstrap_A"]["ci95"].items()}) | |
| 194 | + | |
| 195 | +# ------------------------------------------------------------------ (e) agreement between extraction sources | |
| 196 | +def agree(a, b): | |
| 197 | + a = np.asarray(a).astype(int); b = np.asarray(b).astype(int) | |
| 198 | + po = float(np.mean(a == b)); pe = float(np.mean(a) * np.mean(b) + (1 - np.mean(a)) * (1 - np.mean(b))) | |
| 199 | + kappa = (po - pe) / (1 - pe) if pe < 1 else np.nan | |
| 200 | + tp = int(((a == 1) & (b == 1)).sum()); fp = int(((a == 1) & (b == 0)).sum()); fn = int(((a == 0) & (b == 1)).sum()) | |
| 201 | + prec = tp / (tp + fp) if tp + fp else np.nan; rec = tp / (tp + fn) if tp + fn else np.nan | |
| 202 | + return {"agreement": po, "kappa": kappa, "precision_vs_ref": prec, "recall_vs_ref": rec, | |
| 203 | + "share_a": float(np.mean(a)), "share_ref": float(np.mean(b)), "n": int(len(a))} | |
| 204 | +ds = df[df.has_specs == 1] | |
| 205 | +OUT["agreement"] = {"llm_vs_keyword": { | |
| 206 | + "garage": agree(ds.g_garage, ds.garage), "pool": agree(ds.g_pool, ds.pool), "waterfront": agree(ds.g_waterfront, ds.waterfront), | |
| 207 | + "fireplace": agree(ds.g_fireplace, ds.fireplace), "central_ac": agree(ds.g_central_ac, ds.central_air), | |
| 208 | + "finished_basement": agree(ds.g_finished_basement, ds.finished_bsmt)}} | |
| 209 | +dv = df[(df.has_facade == 1) & (df.v_is_ext == 1) & (df.has_specs == 1)] | |
| 210 | +OUT["agreement"]["vision_vs_text"] = {"garage_visible_vs_llm_garage": agree(dv.v_garage_vis, dv.g_garage), | |
| 211 | + "garage_visible_vs_keyword_garage": agree(dv.v_garage_vis, dv.garage), | |
| 212 | + "waterfront_setting_vs_keyword": agree(dv.v_set_bord_eau, dv.waterfront)} | |
| 213 | +# vision storeys vs structured storeys ; vision building type vs listing type | |
| 214 | +sv = dv["uid"].map(lambda u: facade[u].get("storeys_visual")); st = dv["storeys"] | |
| 215 | +m = sv.isin(["1", "1.5", "2", "3+"]) & st.notna() | |
| 216 | +def st_cat(x): return "1" if x < 1.25 else "1.5" if x < 1.75 else "2" if x < 2.75 else "3+" | |
| 217 | +OUT["agreement"]["vision_storeys_vs_structured"] = {"n": int(m.sum()), | |
| 218 | + "exact": float(np.mean(sv[m].values == st[m].map(st_cat).values)), | |
| 219 | + "within_half_storey": float(np.mean(np.abs(sv[m].map({"1": 1, "1.5": 1.5, "2": 2, "3+": 3}).values - st[m].clip(upper=3).values) <= 0.5))} | |
| 220 | +bt = dv["uid"].map(lambda u: facade[u].get("building_type_visual")) | |
| 221 | +row_types = {"Row / Townhouse", "Townhouse"} | |
| 222 | +is_row = dv["ptype"].isin(row_types).astype(int); vis_row = (bt == "rangee").astype(int) | |
| 223 | +OUT["agreement"]["vision_rowhouse_vs_listing_type"] = agree(vis_row, is_row) | |
| 224 | +OUT["agreement"]["vision_building_type_dist"] = bt.value_counts(normalize=True).round(3).to_dict() | |
| 225 | +print("agreement:", json.dumps(OUT["agreement"], indent=0, default=float)[:1500]) | |
| 226 | + | |
| 227 | +# ------------------------------------------------------------------ CV: random vs spatial (RTA) holdout, by subgroup | |
| 228 | +kf = KFold(n_splits=5, shuffle=True, random_state=42) | |
| 229 | +grp = df["fsa"].where(df["fsa"] != "", df["city_fe"]).values | |
| 230 | +gkf = GroupKFold(n_splits=5) | |
| 231 | +Xcat = pd.get_dummies(df[cats], dtype=float).reset_index(drop=True) | |
| 232 | +dfi = df.copy() | |
| 233 | +for c in ["sqft_final", "lot_sqft", "beds", "baths", "storeys", "age", "age2"]: | |
| 234 | + dfi[c] = dfi.groupby("ptype")[c].transform(lambda s: s.fillna(s.median())); dfi[c] = dfi[c].fillna(dfi[c].median()) | |
| 235 | +dfi["parking"] = dfi["parking"].fillna(0) | |
| 236 | +def stats(pred, mask=None): | |
| 237 | + mask = np.ones(len(y), bool) if mask is None else mask | |
| 238 | + e = np.abs(np.exp(pred[mask] - y[mask]) - 1) | |
| 239 | + return {"r2": float(r2_score(y[mask], pred[mask])), "mdape": float(np.median(e) * 100), "n": int(mask.sum())} | |
| 240 | +def cv_ols(numcols, cv, groups=None): | |
| 241 | + X = pd.concat([dfi[numcols].reset_index(drop=True), Xcat], axis=1); X = X.fillna(X.median()) | |
| 242 | + return cross_val_predict(LinearRegression(), X, y, cv=cv, groups=groups, n_jobs=-1) | |
| 243 | +def cv_gbm(numcols, cv, groups=None): | |
| 244 | + X = pd.concat([df_cv[numcols].reset_index(drop=True), Xcat], axis=1) | |
| 245 | + m = HistGradientBoostingRegressor(max_iter=600, learning_rate=0.05, max_leaf_nodes=63, l2_regularization=1.0, random_state=42) | |
| 246 | + return cross_val_predict(m, X, y32, cv=cv, groups=groups, n_jobs=-1).astype(np.float64) | |
| 247 | +L1 = ["sqft_final", "has_sqft", "lot_sqft", "beds", "baths", "parking", "storeys", "age", "age2"] + amen_ | |
| 248 | +L2 = L1 + ["n_images_c", "virtual_tour"] + rv; L3 = L2 + gv; L4 = L3 + vv | |
| 249 | +L4L = L4 + ["lang_en", "lang_mixed", "desc_len"] | |
| 250 | +masks = {"all": np.ones(len(y), bool), "fr": (df.lang == "fr").values, "en": (df.lang == "en").values, | |
| 251 | + "mixed": (df.lang == "mixed").values, "realtor": (df.source == "realtor").values, | |
| 252 | + "duproprio": (df.source == "duproprio").values, | |
| 253 | + "realtor_no_dollar": ((df.source == "realtor") & (df.price_in_text == 0)).values, | |
| 254 | + "realtor_dollar": ((df.source == "realtor") & (df.price_in_text == 1)).values} | |
| 255 | +OUT["cv"] = {"random": {}, "spatial_fsa": {}} | |
| 256 | +for lname, cols in [("L2", L2), ("L3", L3), ("L4", L4), ("L4+lang", L4L)]: | |
| 257 | + po = cv_ols(cols, kf); pg = cv_gbm(cols, kf) | |
| 258 | + OUT["cv"]["random"][lname] = {"ols": {k: stats(po, m) for k, m in masks.items()}, "gbm": {k: stats(pg, m) for k, m in masks.items()}} | |
| 259 | + print(f"random {lname}: OLS {OUT['cv']['random'][lname]['ols']['all']} GBM {OUT['cv']['random'][lname]['gbm']['all']} [{time.time()-T0:.0f}s]") | |
| 260 | +for lname, cols in [("L2", L2), ("L3", L3), ("L4", L4)]: | |
| 261 | + po = cv_ols(cols, gkf, grp); pg = cv_gbm(cols, gkf, grp) | |
| 262 | + OUT["cv"]["spatial_fsa"][lname] = {"ols": {k: stats(po, m) for k, m in masks.items()}, "gbm": {k: stats(pg, m) for k, m in masks.items()}} | |
| 263 | + print(f"spatial {lname}: OLS {OUT['cv']['spatial_fsa'][lname]['ols']['all']} GBM {OUT['cv']['spatial_fsa'][lname]['gbm']['all']} [{time.time()-T0:.0f}s]") | |
| 264 | +OUT["cv"]["spatial_groups"] = int(len(np.unique(grp))) | |
| 265 | + | |
| 266 | +# ------------------------------------------------------------------ (f) blend weights | |
| 267 | +g5 = cv_gbm(NUM_v5, kf); b5 = np.load("data/processed/v5_blend_oos.npy").astype(np.float64); n5 = 2 * b5 - g5 | |
| 268 | +g4 = cv_gbm(NUM_v4, kf); n4 = np.load("data/processed/nn_robust_oos.npy").astype(np.float64) | |
| 269 | +OUT["blend"] = {"gbm_v5_r2": float(r2_score(y, g5)), "nn_v5_r2_recovered": float(r2_score(y, n5)), | |
| 270 | + "blend_v5_r2_file": float(r2_score(y, b5)), "gbm_v4_r2": float(r2_score(y, g4)), "nn_v4_r2": float(r2_score(y, n4)), | |
| 271 | + "grid_v5": {str(w): float(r2_score(y, w * g5 + (1 - w) * n5)) for w in [0.0, 0.3, 0.4, 0.5, 0.6, 0.7, 1.0]}, | |
| 272 | + "grid_v4": {str(w): float(r2_score(y, w * g4 + (1 - w) * n4)) for w in [0.0, 0.3, 0.4, 0.5, 0.6, 0.7, 1.0]}, | |
| 273 | + "blend_v5_by_group": {k: stats(b5, m) for k, m in masks.items()}} | |
| 274 | +# optimal stacking weight by nested CV (weight chosen on 4 folds, applied to the 5th) | |
| 275 | +wgrid = np.linspace(0, 1, 21); pred_nested = np.zeros_like(y) | |
| 276 | +for tr, te in kf.split(y): | |
| 277 | + wbest = wgrid[np.argmax([r2_score(y[tr], w * g5[tr] + (1 - w) * n5[tr]) for w in wgrid])] | |
| 278 | + pred_nested[te] = wbest * g5[te] + (1 - wbest) * n5[te] | |
| 279 | +OUT["blend"]["nested_weight_r2"] = float(r2_score(y, pred_nested)) | |
| 280 | +print("blend:", {k: v for k, v in OUT["blend"].items() if k != "blend_v5_by_group"}) | |
| 281 | + | |
| 282 | +json.dump(OUT, open("results/revision_2026-10-17.json", "w"), indent=1, default=float) | |
| 283 | +print(f"-> results/revision_2026-10-17.json ({time.time()-T0:.0f}s)") | |
| 284 | +print("Next: python3 scripts/19_make_revision_tables.py") | |
added
scripts/19_make_revision_tables.py
+208 −0
@@ -0,0 +1,208 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +# -*- coding: utf-8 -*- | |
| 3 | +"""Génère les tables LaTeX de la révision 2026-10-17 à partir de results/revision_2026-10-17.json | |
| 4 | +(produit par scripts/18_revision_language_leakage_spatial.py). Aucun calcul : mise en forme seulement. | |
| 5 | +Sorties : paper/tables/rob_language_source.tex, rob_spatial.tex, rob_ai_coefs.tex, agreement.tex.""" | |
| 6 | +import json | |
| 7 | +OUT = json.load(open("results/revision_2026-10-17.json")) | |
| 8 | +y = [0] * OUT["text_leakage"]["n"] | |
| 9 | + | |
| 10 | +def f3(x): return f"${x:.3f}$" if x < 0 else f"{x:.3f}" | |
| 11 | +def pct(x): return f"{x*100:.1f}\\%" | |
| 12 | +def num(n): return f"{n:,}".replace(",", "{,}") | |
| 13 | + | |
| 14 | +# ---- Table: language and text leakage (robustness of the AI layers) ---- | |
| 15 | +A = OUT["ablation_A"]; R = OUT["cv"]["random"] | |
| 16 | +def row_abl(label, key): | |
| 17 | + a = A[key]; return f" {label} & {num(a['n'])} & {f3(a['base'])} & {a['d_text']*100:+.1f} & {a['d_vision']*100:+.1f} \\\\" | |
| 18 | +def row_cv(label, key, est): | |
| 19 | + r2 = [R[L][est][key]["r2"] for L in ("L2", "L3", "L4")]; n = R["L2"][est][key]["n"] | |
| 20 | + return f" {label} & {num(n)} & {f3(r2[0])} & {(r2[1]-r2[0])*100:+.1f} & {(r2[2]-r2[1])*100:+.1f} \\\\" | |
| 21 | +tab = r"""% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 22 | +\begin{table}[htbp] | |
| 23 | + \centering | |
| 24 | + \begin{threeparttable} | |
| 25 | + \caption{Gains from the AI Feature Layers by Language, Platform, and Presence of a Price in the Text} | |
| 26 | + \label{tab:rob_language_source} | |
| 27 | + \small | |
| 28 | + \begin{tabular}{@{}lcccc@{}} | |
| 29 | + \toprule | |
| 30 | + Subsample & $N$ & $R^2$ base & $\Delta R^2$ text (pp) & $\Delta R^2$ vision (pp) \\ | |
| 31 | + \midrule | |
| 32 | + \multicolumn{5}{@{}l}{\textit{Panel A: In-sample $R^2$, Model~A (measured area), municipality FE}} \\[2pt] | |
| 33 | +""" + "\n".join([row_abl("All listings", "all"), row_abl("\\quad French descriptions", "fr"), | |
| 34 | + row_abl("\\quad English descriptions", "en"), row_abl("\\quad Mixed / bilingual", "mixed"), | |
| 35 | + row_abl("\\quad Realtor.ca (no asking price in text)", "realtor"), | |
| 36 | + row_abl("\\quad DuProprio (asking price in text)", "duproprio"), | |
| 37 | + row_abl("\\quad Realtor.ca, no dollar amount in text", "realtor_no_dollar"), | |
| 38 | + row_abl("All listings, RTA fixed effects", "fsa_fe")]) + r""" | |
| 39 | + \addlinespace | |
| 40 | + \multicolumn{5}{@{}l}{\textit{Panel B: Out-of-sample $R^2$ (5-fold, random), OLS, full sample}} \\[2pt] | |
| 41 | +""" + "\n".join([row_cv("All listings", "all", "ols"), row_cv("\\quad French", "fr", "ols"), row_cv("\\quad English", "en", "ols"), | |
| 42 | + row_cv("\\quad Realtor.ca", "realtor", "ols"), row_cv("\\quad DuProprio", "duproprio", "ols")]) + r""" | |
| 43 | + \addlinespace | |
| 44 | + \multicolumn{5}{@{}l}{\textit{Panel C: Out-of-sample $R^2$ (5-fold, random), gradient boosting, full sample}} \\[2pt] | |
| 45 | +""" + "\n".join([row_cv("All listings", "all", "gbm"), row_cv("\\quad French", "fr", "gbm"), row_cv("\\quad English", "en", "gbm"), | |
| 46 | + row_cv("\\quad Realtor.ca", "realtor", "gbm"), row_cv("\\quad DuProprio", "duproprio", "gbm")]) + r""" | |
| 47 | + \bottomrule | |
| 48 | + \end{tabular} | |
| 49 | + \begin{tablenotes}[flushleft] | |
| 50 | + \footnotesize | |
| 51 | + \item \textit{Notes:} Panel~A re-estimates the nested in-sample ablation of Model~A (structural, amenity, room, and | |
| 52 | + listing controls with municipality and type fixed effects; then $+$ LLM text layer; then $+$ façade vision layer) on | |
| 53 | + each subsample; ``$\Delta R^2$'' is the gain, in percentage points, from adding the layer. Language is classified | |
| 54 | + from French and English stop-word counts (ratio rule of 1.5; ``mixed'' listings are mostly DuProprio descriptions that | |
| 55 | + concatenate an English translation and the French original). Every DuProprio description contains the asking price | |
| 56 | + (``Asking Price \$\dots''); """ + f"{OUT['text_leakage']['realtor_dollar_share']*100:.1f}" + r"""\% of Realtor.ca | |
| 57 | + descriptions contain some dollar amount (usually a municipal assessment, a renovation budget, or a tax; the 141 | |
| 58 | + Model~A listings concerned are too few for a separate regression). Panels~B and | |
| 59 | + C evaluate the full-sample cross-validated predictions (Table~\ref{tab:ablation}, identical folds) within each | |
| 60 | + subsample; the base is the structural $+$ amenity $+$ rooms $+$ listing specification. Within-subsample $R^2$ | |
| 61 | + values can be negative (DuProprio, OLS) when the pooled model is miscalibrated for the subsample. | |
| 62 | + \end{tablenotes} | |
| 63 | + \end{threeparttable} | |
| 64 | +\end{table} | |
| 65 | +""" | |
| 66 | +open("paper/tables/rob_language_source.tex", "w").write(tab) | |
| 67 | + | |
| 68 | +# ---- Table: random vs spatial holdout ---- | |
| 69 | +S = OUT["cv"]["spatial_fsa"] | |
| 70 | +def row_sp(label, est): | |
| 71 | + r = [R[L][est]["all"]["r2"] for L in ("L2", "L3", "L4")]; s = [S[L][est]["all"]["r2"] for L in ("L2", "L3", "L4")] | |
| 72 | + mr = [R[L][est]["all"]["mdape"] for L in ("L2", "L3", "L4")]; ms = [S[L][est]["all"]["mdape"] for L in ("L2", "L3", "L4")] | |
| 73 | + return (f" {label} & {f3(r[0])} & {f3(r[1])} & {f3(r[2])} & {mr[2]:.1f}\\% & {f3(s[0])} & {f3(s[1])} & {f3(s[2])} & {ms[2]:.1f}\\% \\\\") | |
| 74 | +tab = r"""% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 75 | +\begin{table}[htbp] | |
| 76 | + \centering | |
| 77 | + \begin{threeparttable} | |
| 78 | + \caption{Random versus Spatial (RTA-Grouped) Cross-Validation} | |
| 79 | + \label{tab:rob_spatial} | |
| 80 | + \small | |
| 81 | + \begin{tabular}{@{}lcccc@{\hskip 0.8cm}cccc@{}} | |
| 82 | + \toprule | |
| 83 | + & \multicolumn{4}{c}{Random 5-fold} & \multicolumn{4}{c}{Spatial 5-fold (RTA groups)} \\ | |
| 84 | + \cmidrule(lr){2-5}\cmidrule(lr){6-9} | |
| 85 | + Estimator & Base & $+$Text & $+$Vision & MdAPE & Base & $+$Text & $+$Vision & MdAPE \\ | |
| 86 | + \midrule | |
| 87 | +""" + "\n".join([row_sp("OLS (linear hedonic)", "ols"), row_sp("Gradient boosting", "gbm")]) + r""" | |
| 88 | + \bottomrule | |
| 89 | + \end{tabular} | |
| 90 | + \begin{tablenotes}[flushleft] | |
| 91 | + \footnotesize | |
| 92 | + \item \textit{Notes:} Out-of-sample $R^2$ on $\ln(\text{Price})$ and median absolute percentage error (MdAPE, for the | |
| 93 | + full text\,$+$\,vision specification). ``Base'' is the structural $+$ amenity $+$ rooms $+$ listing specification; the | |
| 94 | + next two columns add the LLM text layer and the façade vision layer. In the spatial design the """ + num(OUT["cv"]["spatial_groups"]) + r""" forward | |
| 95 | + sortation areas (RTA, first three characters of the postal code) are assigned to five folds by \texttt{GroupKFold}, so | |
| 96 | + no listing is predicted from a model that has seen a listing of the same RTA; municipality indicators of RTAs held | |
| 97 | + out in their entirety are unobserved in training and the model falls back on the reference category. Random-fold | |
| 98 | + entries may differ by $\pm0.001$ from Table~\ref{tab:ablation}, which comes from a separate run. $N=$""" + num(len(y)) + r""". | |
| 99 | + \end{tablenotes} | |
| 100 | + \end{threeparttable} | |
| 101 | +\end{table} | |
| 102 | +""" | |
| 103 | +open("paper/tables/rob_spatial.tex", "w").write(tab) | |
| 104 | + | |
| 105 | +# ---- Table: robustness of AI coefficients ---- | |
| 106 | +O = OUT["ols"]; CB = OUT["cluster_bootstrap_A"] | |
| 107 | +def star(p): return "$^{***}$" if p < .01 else "$^{**}$" if p < .05 else "$^{*}$" if p < .1 else "" | |
| 108 | +def cellc(spec, k): | |
| 109 | + c = O[spec]["coef"].get(k) | |
| 110 | + if not c: return "", "" | |
| 111 | + s = "$-$" if c["b"] < 0 else "" | |
| 112 | + return f"{s}{abs(c['b']):.3f}{star(c['p'])}", f"({c['se']:.3f})" | |
| 113 | +labels = [("v_curb", "Curb appeal (1--10)"), ("v_reno", "Renovation level (ord.)"), ("v_luxury", "Luxury (visual)"), | |
| 114 | + ("v_garage_vis", "Garage visible"), ("v_mat_brique", "Brick façade"), ("v_mat_pierre", "Stone façade"), | |
| 115 | + ("v_mat_vinyle", "Vinyl façade"), ("v_set_rural", "Rural setting"), ("v_land", "Landscaping (ord.)"), | |
| 116 | + ("g_cond", "Condition (LLM, ord.)"), ("g_renovated_kitchen", "Reno.\\ kitchen (LLM)"), ("g_hardwood", "Hardwood floor (LLM)"), | |
| 117 | + ("lang_en", "English description"), ("lang_mixed", "Mixed-language description")] | |
| 118 | +specs_ = ["A", "A_lang", "A_fsa_lang", "A_realtor_fsa_lang"] | |
| 119 | +L = [] | |
| 120 | +for k, lab in labels: | |
| 121 | + cells = [cellc(s, k) for s in specs_] | |
| 122 | + ci = CB["ci95"].get(k) | |
| 123 | + cic = f"[${ci[0]:.3f}$, ${ci[1]:.3f}$]" if ci else "" | |
| 124 | + L.append(f" {lab} & " + " & ".join(c[0] for c in cells) + f" & {cic} \\\\") | |
| 125 | + L.append(" & " + " & ".join(c[1] for c in cells) + " & \\\\[2pt]") | |
| 126 | +tab = r"""% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 127 | +\begin{table}[htbp] | |
| 128 | + \centering | |
| 129 | + \begin{threeparttable} | |
| 130 | + \caption{Robustness of the AI-Derived Implicit Prices (Model~A)} | |
| 131 | + \label{tab:rob_ai_coefs} | |
| 132 | + \footnotesize | |
| 133 | + \setlength{\tabcolsep}{4pt} | |
| 134 | + \begin{tabular}{@{}lccccc@{}} | |
| 135 | + \toprule | |
| 136 | + & (1) & (2) & (3) & (4) & (5) \\ | |
| 137 | + & Baseline & $+$Language & RTA FE & Realtor.ca only & Cluster bootstrap \\ | |
| 138 | + & & & $+$Language & RTA FE $+$Lang. & 95\% CI \\ | |
| 139 | + \midrule | |
| 140 | +""" + "\n".join(L) + r""" | |
| 141 | + \midrule | |
| 142 | + Fixed effects & Municipality & Municipality & RTA & RTA & Municipality \\ | |
| 143 | + Observations & """ + " & ".join(num(O[s]["n"]) for s in specs_) + r""" & """ + num(O["A"]["n"]) + r""" \\ | |
| 144 | + $R^2$ & """ + " & ".join(f3(O[s]["r2"]) for s in specs_) + r""" & \\ | |
| 145 | + \bottomrule | |
| 146 | + \end{tabular} | |
| 147 | + \begin{tablenotes}[flushleft] | |
| 148 | + \footnotesize | |
| 149 | + \item \textit{Notes:} OLS estimates of Equation~\eqref{eq:hedonic} on the measured-area subsample with the full | |
| 150 | + control set (coefficients of the controls not shown). Column~(1) is the baseline of Table~\ref{tab:regression}. | |
| 151 | + Column~(2) adds indicators for English and mixed-language descriptions and the description length (thousands of | |
| 152 | + characters). Column~(3) replaces the """ + str(OUT["fsa"]["n_city_fe"]) + r""" municipality fixed effects by """ + str(OUT["fsa"]["n_fsa_fe"]) + r""" forward-sortation-area (RTA) fixed | |
| 153 | + effects (RTAs with at least 20 listings; the remainder pooled). Column~(4) restricts the sample to Realtor.ca | |
| 154 | + listings, whose descriptions never contain the asking price. Standard errors in parentheses are clustered at the | |
| 155 | + level of the fixed effects. Column~(5) reports the 2.5th and 97.5th percentiles of a pairs cluster bootstrap | |
| 156 | + (""" + str(CB["B"]) + r""" replications, resampling the """ + str(CB["n_clusters"]) + r""" municipalities with replacement) for the baseline | |
| 157 | + specification. $^{***}$, $^{**}$, $^{*}$: significance at 1\%, 5\%, 10\%. | |
| 158 | + \end{tablenotes} | |
| 159 | + \end{threeparttable} | |
| 160 | +\end{table} | |
| 161 | +""" | |
| 162 | +open("paper/tables/rob_ai_coefs.tex", "w").write(tab) | |
| 163 | + | |
| 164 | +# ---- Table: agreement ---- | |
| 165 | +AG = OUT["agreement"] | |
| 166 | +def row_ag(label, r): | |
| 167 | + return (f" {label} & {num(r['n'])} & {pct(r['share_a'])} & {pct(r['share_ref'])} & {pct(r['agreement'])} & {r['kappa']:.2f} & " | |
| 168 | + f"{pct(r['precision_vs_ref'])} & {pct(r['recall_vs_ref'])} \\\\") | |
| 169 | +rows = [row_ag(l, AG["llm_vs_keyword"][k]) for k, l in [("garage", "Garage"), ("pool", "Swimming pool"), ("waterfront", "Waterfront"), | |
| 170 | + ("fireplace", "Fireplace"), ("central_ac", "Central A/C or heat pump"), | |
| 171 | + ("finished_basement", "Finished basement")]] | |
| 172 | +rows2 = [row_ag("Garage visible vs.\\ garage (LLM)", AG["vision_vs_text"]["garage_visible_vs_llm_garage"]), | |
| 173 | + row_ag("Garage visible vs.\\ garage (keyword)", AG["vision_vs_text"]["garage_visible_vs_keyword_garage"]), | |
| 174 | + row_ag("Waterfront setting vs.\\ waterfront (keyword)", AG["vision_vs_text"]["waterfront_setting_vs_keyword"]), | |
| 175 | + row_ag("Row house vs.\\ townhouse (listing type)", AG["vision_rowhouse_vs_listing_type"])] | |
| 176 | +sto = AG["vision_storeys_vs_structured"] | |
| 177 | +tab = r"""% Auto-generated by scripts/18_revision_language_leakage_spatial.py (2026-10-17) | |
| 178 | +\begin{table}[htbp] | |
| 179 | + \centering | |
| 180 | + \begin{threeparttable} | |
| 181 | + \caption{Agreement Between Machine-Generated Attributes and Independent Sources} | |
| 182 | + \label{tab:agreement} | |
| 183 | + \footnotesize | |
| 184 | + \setlength{\tabcolsep}{3.5pt} | |
| 185 | + \begin{tabular}{@{}lccccccc@{}} | |
| 186 | + \toprule | |
| 187 | + Attribute & $N$ & Share (AI) & Share (ref.) & Agreement & $\kappa$ & Precision & Recall \\ | |
| 188 | + \midrule | |
| 189 | + \multicolumn{8}{@{}l}{\textit{Panel A: LLM text layer vs.\ bilingual keyword rule on the same text}} \\[2pt] | |
| 190 | +""" + "\n".join(rows) + r""" | |
| 191 | + \addlinespace | |
| 192 | + \multicolumn{8}{@{}l}{\textit{Panel B: Façade vision layer vs.\ text or structured fields (exterior shots only)}} \\[2pt] | |
| 193 | +""" + "\n".join(rows2) + r""" | |
| 194 | + \bottomrule | |
| 195 | + \end{tabular} | |
| 196 | + \begin{tablenotes}[flushleft] | |
| 197 | + \footnotesize | |
| 198 | + \item \textit{Notes:} ``Share (AI)'' is the prevalence of the attribute according to the AI layer, ``Share (ref.)'' | |
| 199 | + according to the reference source; ``Agreement'' is the share of listings on which the two coincide, $\kappa$ is | |
| 200 | + Cohen's kappa, and precision and recall treat the reference as ground truth (it is not: keyword rules miss | |
| 201 | + negations and synonyms, and a garage need not be visible on the façade photograph). Visual storey count agrees | |
| 202 | + exactly with the structured storey field for """ + f"{sto['exact']*100:.1f}" + r"""\% of """ + num(sto["n"]) + r""" listings and within half a storey for """ + f"{sto['within_half_storey']*100:.1f}" + r"""\%. | |
| 203 | + \end{tablenotes} | |
| 204 | + \end{threeparttable} | |
| 205 | +\end{table} | |
| 206 | +""" | |
| 207 | +open("paper/tables/agreement.tex", "w").write(tab) | |
| 208 | +print("-> paper/tables/rob_language_source.tex, rob_spatial.tex, rob_ai_coefs.tex, agreement.tex") | |
| 209 | ||