SPB Git

spb/wp5_uqo

Public

UQO Working Paper No. 5 — Airbnb, residential rents and housing market pressure.

révision scientifique complète (editorial board, 2026-10-17)

v1.0 → v1.1 (October 2026). FSA (neighbourhood) fixed effects and Conley /
cluster spatial inference added (scripts/12): the 0.4 %/listing city-FE
association falls to 0.08 % within FSAs and is not distinguishable from zero
under spatial SEs; spatial SEs ≈ 3× HC1. Spatial models re-estimated on
projected coordinates with LeSage–Pace impacts; Model 2 collinearity fixed and
re-estimated on the plausibly priced subsample (bimodal price field documented);
random vs FSA-blocked ML cross-validation; benchmark magnitudes (Duso, Koster,
Garcia-López, Combs) corrected; bibliography 56 → 67 entries, all Crossref-
verified. Full report: docs/REVIEW-REPORT.md; audit trail:
docs/CHANGELOG-REVISION.md.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Oct 18, 2026) parent a4cf1c4 Browse files

67 changed files +2,621 −939

67 changed files
Unified Split
modified README.md +88 −72
@@ -3,20 +3,24 @@
3 3
4 4 **UQO Working Paper No. 5** — *A Hedonic and Spatial Econometric Analysis*
5 5
6 −[![Paper](https://img.shields.io/badge/paper-PDF%20(51%20p.)-b31b1b?logo=latex&logoColor=white)](paper/main.pdf)
6 +[![Paper](https://img.shields.io/badge/paper-PDF%20(59%20p.)-b31b1b?logo=latex&logoColor=white)](paper/main.pdf)
7 7 [![Python](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)](requirements.txt)
8 8 [![Data](https://img.shields.io/badge/data-8%2C303%20rentals%20·%203%2C456%20Airbnb%20·%20parquet-4051b5)](data/raw/README.md)
9 −[![Estimation](https://img.shields.io/badge/estimation-OLS%20HC1%20·%20SAR%2FSEM%20GMM%20·%20QuantReg%20·%20ML-4051b5)](src/)
9 +[![Estimation](https://img.shields.io/badge/estimation-OLS%20·%20FSA%20FE%20·%20Conley%20SE%20·%20SAR%2FSEM%20GMM%20·%20QuantReg%20·%20ML-4051b5)](src/)
10 10 [![Reproducible](https://img.shields.io/badge/reproducible-end--to--end%20pipeline-2e7d32)](scripts/)
11 11 [![Institution](https://img.shields.io/badge/UQO-D%C3%A9pt.%20des%20sciences%20administratives-16365c)](https://uqo.ca)
12 12 [![Author](https://img.shields.io/badge/author-Simon--Pierre%20Boucher-16365c)](mailto:simon-pierre.boucher@uqo.ca)
13 13
14 −> **TL;DR** — Using cross-sectional microdata on **3,456 Airbnb listings** and **8,303 residential rental listings** in
15 −> Quebec, the paper measures the conditional association between nearby short-term-rental activity and monthly rents in
16 −> a hedonic framework augmented with spatial econometrics. Each additional Airbnb listing within **500 m** is associated
17 −> with **≈ +0.4 %** monthly rent (0.3–0.5 % across specifications, ≈ $6–10/month at the median), decaying with distance,
18 −> stronger at the top of the rent distribution (β(τ = 0.90) = 0.0047), and surviving SAR/SEM spatial models
19 −> (ρ̂ = 0.137***), city-clustered SEs and leave-one-city-out checks. Cross-sectional associations, not causal effects.
14 +> **TL;DR** — Using a 2026 cross-section of **3,456 Airbnb listings** and **8,303 residential rental listings** in
15 +> Quebec, the paper measures the conditional association between nearby short-term-rental activity and monthly
16 +> asking rents. With **city fixed effects**, each additional Airbnb listing within **500 m** is associated with
17 +> **≈ +0.4 %** rent (0.3–0.5 % across specifications), decaying per listing with distance, larger at the top of the
18 +> rent distribution, and unchanged in SAR/SEM models (total impact 0.40 %). Two results qualify this: **Conley and
19 +> FSA-clustered standard errors are ≈ 3× the HC1 errors** (t from 17 to ≈ 5.5), and **with postal-code-neighbourhood
20 +> (FSA) fixed effects the coefficient falls to 0.08 %** and is not distinguishable from zero under spatial inference.
21 +> The association is predominantly *between* neighbourhoods — consistent with STR supply sorting into high-rent
22 +> neighbourhoods, not with a within-neighbourhood causal effect. Spatially blocked cross-validation erases the
23 +> apparent advantage of tree-based ML models. Cross-sectional associations, not causal effects.
20 24
21 25 ---
22 26
@@ -24,37 +28,41 @@
24 28
25 29 | Item | Value |
26 30 |---|---|
27 −| Version | 1.0 (May 2026) — cover page harmonised to the UQO WP standard, October 2026 |
28 −| SSRN | Abstract ID **7626658** (submitted 2026-10-17, preliminary upload) |
31 +| Version | **1.1 (October 2026)** — revised 2026-10-17 by the editorial-board review (`docs/REVIEW-REPORT.md`, `docs/CHANGELOG-REVISION.md`); v1.0 May 2026, cover page harmonised October 2026 |
32 +| SSRN | Abstract ID **7626658** (preliminary upload 2026-10-17; v1.1 to be uploaded) |
29 33 | Journal | not yet submitted |
30 −| Code & data | steps 04–11 and the paper fully reproducible from the committed parquets; raw scraped files not redistributed |
34 +| Code & data | steps 04–12 and the paper fully reproducible from the committed parquets (< 1 min total); raw scraped files not redistributed |
31 35
32 36 ## 🎯 What this paper does
33 37
34 38 Peer-to-peer platforms can divert dwellings from the long-term rental stock and raise rents nearby. Quasi-experimental
35 −evidence exists for Berlin, Los Angeles or Boston, but Canadian evidence is thin. For every rental listing the paper
36 −builds Airbnb exposure measures within 250 m, 500 m, 1 km and 2 km buffers (Haversine distances) — count, density, mean
37 −nightly price, entire-home share, mean rating, superhost share — and estimates:
39 +evidence exists for Berlin, Los Angeles, Barcelona or Boston, but Canadian evidence is descriptive. For every rental
40 +listing the paper builds Airbnb exposure measures within 250 m, 500 m, 1 km and 2 km buffers (Haversine distances) —
41 +count, density, mean nightly price, entire-home share — and estimates
38 42
39 43 ```
40 −log(rent_i) = α + β · airbnb_count_500m_i + X_i'γ + building-type + city FE + ε_i (Models 1a–1e)
44 +log(rent_i) = α + β · airbnb_count_500m_i + X_i'γ + building-type + city FE + ε_i (Model 1c)
45 +log(rent_i) = α + β^F · airbnb_count_500m_i + X_i'γ + building-type + FSA FE + ε_i (Model F2)
41 46 ```
42 47
43 −complemented by a hedonic model of Airbnb nightly prices (Models 2a–2c), city-level forward and reverse regressions
44 −(153 cities), SAR/SEM spatial models estimated by Kelejian–Prucha GMM, quantile regressions and a machine-learning
45 −benchmark. The discussion benchmarks magnitudes against the quasi-experimental literature and draws policy implications
46 −for CITQ registration and Montreal zoning, while cautioning against causal readings.
48 +with HC1, city-clustered, FSA-clustered and Conley spatial HAC standard errors (1–10 km cutoffs); SAR/SEM models
49 +by Kelejian–Prucha GMM with LeSage–Pace direct/indirect/total impacts; quantile regressions; a hedonic model of Airbnb
50 +nightly prices (full sample and plausibly priced subsample); city-level regressions; and an ML benchmark evaluated under
51 +random and spatially blocked (FSA) cross-validation. The discussion benchmarks magnitudes against the quasi-experimental
52 +literature in standardised terms and draws implications for Quebec's registration regime and Montreal's zoning rules.
47 53
48 54 ## 🏆 Headline results
49 55
50 56 | # | Finding | Evidence |
51 57 |:-:|---|---|
52 −| 1 | Each additional Airbnb listing within 500 m ⇒ ≈ +0.4 % monthly rent (β = 0.0039***) | Table 3 (1c) · §7.1 |
53 −| 2 | The per-listing association decays monotonically with distance (0.93 % at 250 m → 0.06 % at 2 km) | Table 10 · Fig. 4 |
54 −| 3 | Significant at every quantile, rising to 0.0047 at τ = 0.90 (~25 % above OLS) | Table 7 · Fig. 5 |
55 −| 4 | Substantial spatial dependence (ρ̂ = 0.137***, λ̂ = 0.539); coefficient survives GMM spatial models (0.0034) | Table 6 |
56 −| 5 | Airbnb nightly prices driven by listing characteristics; superhost enters with a *discount* | Table 4 · §7.1 |
57 −| 6 | Robust to city-clustered SEs, size control, log(1 + count), ring decomposition, trimming, leave-one-city-out (0.0038–0.0040) | Table 12 · Fig. 9 |
58 +| 1 | City FE: each additional Airbnb listing within 500 m ⇒ ≈ +0.4 % rent (β = 0.0039; 1 SD of exposure ≈ +5.5 %) | Table 4 (1c) · §5.1 |
59 +| 2 | **FSA (neighbourhood) FE: β falls to 0.0008**; 0.0003 with size control; log(1+count) and 250 m count insignificant; *any* Airbnb nearby ⇒ −2.8 % within FSA | Table 5 · §5.2 |
60 +| 3 | **Spatial inference**: Conley / FSA-cluster SE = 0.0007 vs HC1 0.0002 (t 17 → 5–6 with city FE; 2.3 → 1.1–2.0 with FSA FE); city-clustering (Montreal = 59 % of sample) unreliable | Table 6 · §5.3 |
61 +| 4 | Spatial dependence: ρ̂ = 0.134***, λ̂ = 0.544; SAR total impact 0.0040 (direct 0.0034, indirect 0.0005) = OLS | Tables 7–8 · §5.4 |
62 +| 5 | Per-listing coefficient decays with radius (0.93 % at 250 m → 0.06 % at 2 km) while the mean-exposure association accumulates (2.2 % → 5.0 %); quantiles 0.0034–0.0047, rising at τ = 0.90 | Tables 9, 14 · Figs 5, 8 |
63 +| 6 | **Spatially blocked CV**: RF/GBM R² 0.65 (random folds) → 0.43/0.41 (FSA folds), below OLS (0.47) — the ML advantage is neighbourhood interpolation | Table 13 · §5.8 |
64 +| 7 | Airbnb price field is bimodal (26.5 % of listings > $1,000 "per night"); on the plausibly priced subsample the superhost "discount" disappears and the usual entire-home/size premia reappear; no city-rent premium (θ ≈ 0) | Table 10 · Fig. 4 · §3.1, §5.6 |
65 +| 8 | City-FE estimate robust to clustering, size control, log form, ring decomposition, trimming, leave-one-city-out (0.0038–0.0040) | Tables 15–17 · Figs 9–10 |
58 66
59 67 ## 🗂 Repository layout
60 68
@@ -62,19 +70,20 @@ for CITQ registration and Montreal zoning, while cautioning against causal readi
62 70 wp5_uqo/
63 71 ├── README.md
64 72 ├── requirements.txt # pinned dependencies
65 −├── docs/ # AUDIT.md · CHANGES.md · PAPER_REVIEW.md · UPGRADE_REPORT.md
73 +├── docs/ # REVIEW-REPORT.md · CHANGELOG-REVISION.md (2026-10-17) · AUDIT.md · CHANGES.md ·
74 +│ # PAPER_REVIEW.md · UPGRADE_REPORT.md (2026-08-05) · main_pre-revision-20261017.pdf
66 75 ├── data/
67 76 │ ├── raw/ # airbnb.csv + rent.json — NOT distributed (see data/raw/README.md)
68 77 │ └── processed/ # 5 verified parquet datasets (committed)
69 78 ├── src/
70 79 │ ├── config.py # all paths & constants
71 80 │ ├── geo.py # vectorised Haversine matrix
72 −│ ├── latex_tables.py # stargazer-style table builder
81 +│ ├── latex_tables.py # table builder + readable variable labels
73 82 │ └── plotting.py # publication matplotlib styles
74 −├── scripts/ # 01 → 11 numbered pipeline
75 −├── figures/ # 16 publication PDF figures
76 −├── results/tables/ # 13 LaTeX fragments + 4 CSVs
77 −├── results/logs/ # data-inspection log
83 +├── scripts/ # 01 → 12 numbered pipeline
84 +├── figures/ # 17 publication PDF figures
85 +├── results/tables/ # 18 LaTeX fragments + CSV/JSON records
86 +├── results/logs/ # data-inspection log · pipeline run log
78 87 └── paper/ # main.tex + sections/ + appendix/ + references.bib → main.pdf
79 88 ```
80 89
@@ -83,10 +92,10 @@ wp5_uqo/
83 92 ```bash
84 93 python3 -m pip install -r requirements.txt
85 94
86 −# steps 01–03 need data/raw/ (not distributed); steps 04–11 run from the committed parquets
87 −for s in scripts/0{4..9}_*.py scripts/1{0,1}_*.py; do python3 "$s"; done
95 +# steps 01–03 need data/raw/ (not distributed); steps 04–12 run from the committed parquets
96 +for s in scripts/0{4..9}_*.py scripts/1{0,1,2}_*.py; do python3 "$s"; done
88 97
89 −cd paper && make # latexmk → main.pdf (51 pages)
98 +cd paper && make # latexmk → main.pdf (59 pages)
90 99 ```
91 100
92 101 | Step | Script | Produces | ⏱ |
@@ -95,66 +104,68 @@ cd paper && make # latexmk → main.pdf (51 pages)
95 104 | 02 | `02_clean_airbnb.py` | `airbnb_clean.parquet` | ⚡ |
96 105 | 03 | `03_clean_rent.py` | `rent_clean.parquet` | ⚡ |
97 106 | 04 | `04_merge_data.py` | 3 merged parquets (buffer merge) | ~1 min |
98 −| 05 | `05_descriptive_analysis.py` | 3 tables + 7 figures | ⚡ |
99 −| 06 | `06_hedonic_models.py` | Models 1–3 → 3 tables | ⚡ |
100 −| 07 | `07_spatial_models.py` | SAR/SEM + buffer robustness | ~1 min |
101 −| 08 | `08_quantile_models.py` | quantile table + coefficient path | ~1 min |
102 −| 09 | `09_ml_robustness.py` | ML comparison + SHAP figures | ~2 min |
107 +| 05 | `05_descriptive_analysis.py` | 4 tables (incl. exposure summary, correlation) + 8 figures | ⚡ |
108 +| 06 | `06_hedonic_models.py` | Models 1–3 → 3 tables (Model 2 with restricted-sample columns) | ⚡ |
109 +| 07 | `07_spatial_models.py` | SAR/SEM (projected-coordinate KNN) + LeSage–Pace impacts + buffer robustness | ⚡ |
110 +| 08 | `08_quantile_models.py` | quantile table + coefficient path | ⚡ |
111 +| 09 | `09_ml_robustness.py` | ML comparison + SHAP figures + random vs FSA-blocked CV | ~30 s |
103 112 | 10 | `10_robustness_tables_figures.py` | outlier/subsample tables + 3 figures | ⚡ |
104 −| 11 | `11_extended_robustness.py` | clustered SEs · ring · leave-one-out | ~1 min |
113 +| 11 | `11_extended_robustness.py` | clustered SEs · size · log form · ring · leave-one-out | ⚡ |
114 +| 12 | `12_neighbourhood_fe_inference.py` | **FSA fixed effects · Conley / cluster SE comparison** | ~20 s |
105 115
106 −⚡ = under 15 s on Apple Silicon. Fully deterministic (seed 42).
116 +⚡ = under 5 s on Apple Silicon. Fully deterministic (seed 42).
107 117
108 118 ## 🗃 Data
109 119
110 120 | Dataset | Source | Raw → Clean | Key fields |
111 121 |---|---|---|---|
112 −| Airbnb listings | Airbnb (scraped) | ~5,000 → 3,456 | nightly price, lat/lon, property type, rating, reviews, superhost |
113 −| Rental listings | Realtor.ca (scraped) | 8,356 → 8,303 | monthly rent, lat/lon, bedrooms, bathrooms, building type, size |
122 +| Airbnb listings | Airbnb (scraped, early 2026) | 5,000 → 3,456 (price missing for 30.9 %) | displayed price (bimodal, see §3.1), lat/lon, property type, rating, reviews, superhost, capacity, amenities |
123 +| Rental listings | Realtor.ca (scraped 2026-01-08) | 8,356 → 8,303 | monthly asking rent, lat/lon, bedrooms, bathrooms, building type, size, **postal code → FSA** |
114 124
115 125 Spatial merge: for every rental listing × radius r ∈ {250 m, 500 m, 1 km, 2 km}, six metrics computed against all
116 −Airbnb listings via chunked vectorised Haversine distances, plus city-level aggregates (24 exposure variables). Raw
117 −files are not distributed (`data/raw/README.md`); the committed parquets make steps 04–11 and the paper reproducible.
126 +Airbnb listings via chunked vectorised Haversine distances, plus city-level aggregates. 333 FSAs (289 non-singleton),
127 +253 municipalities (Montreal 59 %). Raw files are not distributed (`data/raw/README.md`); the committed parquets make
128 +steps 04–12 and the paper reproducible.
118 129
119 130 ## 🔬 Methodology
120 131
121 −1. **Hedonic rent models 1a–1e** — OLS, HC1 SE, building-type and city fixed effects; variants with density and
122 − entire-home share (`scripts/06`).
123 −2. **Airbnb pricing models 2a–2c** — log nightly price on city mean rent and listing controls.
124 −3. **City-level regressions** — forward and reverse, 153 cities.
125 −4. **Spatial models** — SAR and SEM, KNN (k = 5) row-standardised weights, Kelejian–Prucha GMM (`spreg.GM_Lag`,
126 − `GM_Error`) (`scripts/07`).
132 +1. **Hedonic rent models 1a–1e** — OLS, HC1 SE, building-type and city fixed effects; density and entire-home share variants (`scripts/06`).
133 +2. **Neighbourhood (FSA) fixed effects F1–F6** — within transformation, 250 m / 500 m counts, extensive + intensive margin, log(1+count), size (`scripts/12`).
134 +3. **Inference** — HC1, cluster-city, cluster-FSA, Conley spatial HAC (Bartlett kernel, 1/2/5/10 km) (`scripts/12`).
135 +4. **Spatial models** — SAR (GM_Lag, White SE) and SEM (GM_Error), KNN k = 5 on projected km coordinates; LeSage–Pace direct/indirect/total impacts with simulated SEs (`scripts/07`).
127 136 5. **Quantile regressions** — τ ∈ {0.10, 0.25, 0.50, 0.75, 0.90} plus a fine grid (`scripts/08`).
128 −6. **Machine-learning benchmark** — OLS / LASSO / Elastic Net / RF / GBM, 80/20 split, SHAP attribution (`scripts/09`).
129 −7. **Robustness** — buffer radii, alternative exposures, subsamples, trimming, city-clustered SEs, size control,
130 − log(1 + count), ring decomposition, leave-one-city-out (`scripts/10`, `scripts/11`).
137 +6. **Airbnb pricing models 2a–2e** — log nightly price on city mean log rent and listing controls; city FE absorb the city rent; restricted sample ≤ $1,000 (`scripts/06`).
138 +7. **Machine-learning benchmark** — OLS / LASSO / Elastic Net / RF / GBM, 80/20 split, SHAP, random vs FSA-blocked 5-fold CV (`scripts/09`).
139 +8. **Robustness** — buffer radii, alternative exposures, subsamples, trimming, city-clustered SEs, size, log(1+count), ring decomposition, leave-one-city-out (`scripts/07`, `10`, `11`).
131 140
132 141 ## 🖼 Figures & tables inventory
133 142
134 143 | Figure | Content |
135 144 |---|---|
136 145 | `map_airbnb`, `map_rent` | Spatial distribution of the two samples |
137 −| `dist_airbnb_price`, `dist_rent` | Price and rent distributions |
138 −| `airbnb_by_city`, `rent_by_city` | City-level profiles |
139 −| `scatter_airbnb_rent`, `rent_by_airbnb_bins`, `rent_airbnb_heatmap` | Exposure–rent relationships |
146 +| `dist_airbnb_price`, `dist_airbnb_logprice`, `dist_rent` | Price and rent distributions (log-scale figure documents the bimodal price field) |
147 +| `airbnb_by_city`, `rent_by_city` | City-level profiles (generated, not in the paper) |
148 +| `scatter_airbnb_rent`, `rent_by_airbnb_bins`, `rent_airbnb_heatmap` | Exposure–rent relationships (generated, not in the paper) |
140 149 | `coefficient_buffer_comparison` | β across buffer radii (spatial decay) |
141 150 | `quantile_coefficients` | β(τ) path |
142 151 | `ml_predicted_vs_actual`, `feature_importance`, `shap_summary` | ML benchmark and attribution |
143 152 | `coefficient_robustness`, `leave_one_city_out` | Robustness programme |
144 153
145 −Tables (`results/tables/*.tex`, 13 fragments): summary statistics, city aggregates, hedonic rent models, Airbnb
146 −pricing, city-level regressions, spatial models, quantile regressions, ML comparison, buffer robustness, subsample and
147 −trimming checks, extended robustness, appendix variable dictionary.
154 +Tables (`results/tables/*.tex`, 18 fragments): exposure summary, summary statistics (2), hedonic rent models,
155 +**neighbourhood FE**, **inference comparison**, spatial models, **spatial impacts**, quantile regressions, Airbnb pricing,
156 +city-level regressions, ML comparison, **random vs spatial CV**, buffer robustness, subsample and trimming checks,
157 +extended robustness, correlation matrix. JSON records: `spatial_models.json`, `neighbourhood_fe.json`.
148 158
149 159 ## ⚠️ Limitations
150 160
151 −- Cross-sectional listing data (asking rents and nightly prices), no panel or quasi-experimental variation: estimates
152 − are conditional associations.
153 −- Airbnb exposure may be endogenous to unobserved neighbourhood amenities; the spatial models and city FE mitigate but do
154 − not eliminate this.
155 −- Scraped samples are not census-complete; coverage is concentrated in the largest Quebec cities.
156 −- Superhost discount and the absence of a city-rent premium in nightly prices diverge from prior work and are discussed,
157 − not resolved.
161 +- Cross-sectional listing data (asking rents and displayed nightly prices), no panel or quasi-experimental variation:
162 + estimates are conditional associations; the city-FE estimate is an upper bound on any causal within-neighbourhood effect.
163 +- The Airbnb price field partly records total-stay prices (second mode above $1,000): the full-sample pricing model is
164 + unreliable; the count-based rent results are unaffected.
165 +- No room type or host identifiers (entire-home status is a property-type proxy; commercial operation unmeasured).
166 +- Scraped winter samples are not census-complete; Realtor.ca over-represents agent-listed, higher-priced units;
167 + coverage concentrated in Montreal.
168 +- Quantile regressions use coarse city groups and non-spatial SEs; quantile and spatial models with FSA FE not estimated.
158 169
159 170 ## 📝 Citation
160 171
@@ -167,7 +178,8 @@ trimming checks, extended robustness, appendix variable dictionary.
167 178 type = {Working Paper},
168 179 number = {5},
169 180 year = {2026},
170 − month = {May}
181 + month = {October},
182 + note = {Version 1.1}
171 183 }
172 184 ```
173 185
@@ -179,9 +191,13 @@ Université du Québec en Outaouais (UQO), Gatineau, QC.
179 191
180 192 ## 🗒 Notes
181 193
182 −- Format follows `Recherche-UQO/HARMONISATION.md` (2026-10-17): template title page, `natbib` + `aer` bibliography style,
183 − `docs/` for the restructuring reports.
194 +- **Revision 2026-10-17 (v1.1)**: full scientific review by the editorial-board protocol (`Recherche-UQO/REVISION-MASTER-PROMPT.md`).
195 + Report: `docs/REVIEW-REPORT.md`; audit trail of every change (old → new numbers, reasons, evidence): `docs/CHANGELOG-REVISION.md`.
196 + Pre-revision PDF: `docs/main_pre-revision-20261017.pdf` (git tag `pre-revision-20261017`). Headline interpretation changed:
197 + the Airbnb–rent association is predominantly between neighbourhoods (FSA FE, Conley SE); Model 2 superhost "discount" and the
198 + Berlin/LA magnitude comparisons of v1.0 were corrected.
199 +- Format follows `Recherche-UQO/HARMONISATION.md` (2026-10-17): template title page, `natbib` + `aer` bibliography style, `docs/` for reports.
184 200 - The original flat May 2026 project (`immo-wp5-spb-20260519`) is archived in
185 201 `Recherche-UQO/_archives/versions-mai-2026/airbnb-rents-housing-pressure--immo-wp5-20260519/`; `docs/AUDIT.md` §8 and
186 − `docs/CHANGES.md` document the 2026-08-05 rebuild (14/16 tables byte-identical, prose-only corrections).
187 −- Build verified 2026-10-17: 0 errors, 0 undefined references, 56 references rendered.
202 + `docs/CHANGES.md` document the 2026-08-05 rebuild.
203 +- Build verified 2026-10-17: 0 errors, 0 undefined references, 67 references rendered (all DOI/Crossref-verified).
added docs/CHANGELOG-REVISION.md +68 −0
@@ -0,0 +1,68 @@
1 +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca -->
2 +# CHANGELOG-REVISION — UQO WP 5, editorial-board revision (2026-10-17), v1.0 → v1.1
3 +
4 +Pre-revision state: git tag `pre-revision-20261017`; `docs/main_pre-revision-20261017.pdf` (51 pages). All original files preserved in git history; every number below was regenerated by the scripts in `scripts/` (run log: `results/logs/pipeline_run_20261017.txt`).
5 +
6 +## 1. Major corrections (where · before → after · why · evidence)
7 +
8 +| # | Where | Before (v1.0) | After (v1.1) | Why / evidence |
9 +|---|---|---|---|---|
10 +| 1 | Abstract, §1, §3, §8 | "approximately 5,000 Airbnb listings" | 3,456 listings analysed (5,000 scraped, 1,544 without price) | `airbnb_clean.parquet` has 3,456 rows; inspection log: 30.9 % null prices |
11 +| 2 | **New §5.2, Table 5** | city FE only (β = 0.0039) | FSA FE: β = 0.0008 (HC1 0.0004), N = 7,883, 289 FSAs; 250 m: 0.0008 (0.0009); any-Airbnb −0.0279*** + count 0.0010; log(1+count) 0.0022 (0.0053); + size 0.0003 (0.0006) | `scripts/12`, `results/tables/neighbourhood_fe.{tex,json}`; within-FSA variance share of the count = 26 % |
12 +| 3 | **New §5.3, Table 6** | HC1 (0.0002) + one city-cluster column (0.0001) | City FE: HC1 0.0002 / cluster-city 0.0001 (187 cl.) / cluster-FSA 0.0007 (318) / Conley 1–10 km 0.0007; FSA FE: 0.0004 / 0.0004 / 0.0007 / 0.0007–0.0004 | `scripts/12`, `inference_comparison.tex`; city clustering unreliable (Montreal 59 %) |
13 +| 4 | §4.4, §5.4, Table 7, App. B | KNN on raw degrees; ρ̂ = 0.1367 (0.0199), λ̂ = 0.5393, SAR β 0.0034 (0.0002), SEM β 0.0038 (0.0004), pseudo-R² 0.5503/0.4972; SAR SE classical | KNN on projected km; SAR White-robust SE; ρ̂ = 0.1340 (0.0222), λ̂ = 0.5437, SAR β 0.0034 (0.0002), SEM β 0.0039 (0.0004), pseudo-R² 0.5508/0.4973 | anisotropy of degree coordinates at 45–47° N (cos φ ≈ 0.69); `scripts/07` `project_km()` |
14 +| 5 | **New Table 8** | SAR coefficient read as "mildly attenuated" marginal effect | LeSage–Pace impacts: direct 0.0034 (0.0002), indirect 0.0005 (0.0001), total 0.0040 (0.0002); n⁻¹tr[(I−ρW)⁻¹] = 1.0026 | `scripts/07` `lesage_pace_impacts()`; `spatial_impacts.tex` |
15 +| 6 | §4.3, §5.6, Table 10 | (2c) reported mean_rent_city = 0.0307 (0.1039) with city FE | regressor dropped in FE columns (perfectly collinear; v1.0 value was a pseudo-inverse artefact); other (2c) coefficients unchanged | `scripts/06`; statsmodels pinv behaviour |
16 +| 7 | §3.1, §5.6, Table 10, Fig. 4 | superhost "discount" (−0.35***/−0.28***) interpreted as Quebec composition effect; R² 0.03/0.14 | price field bimodal (26.5 % > $1,000); restricted sample ≤ $1,000 (N = 1,699): superhost 0.014/0.042 n.s., entire home 0.137*** (FE), amenities 0.003***, R² 0.21/0.30; θ = 0.003 (0.052) | `scripts/05` log-price histogram; `scripts/06` columns (2d)–(2e) |
17 +| 8 | §6.3, Table 15 | "(4) Houses" = 0.006699*** (0.001995), N = 789 (substring match caught "Row / Townhouse") | exact `building_type == "House"`: 0.005857** (0.002348), N = 741 | `scripts/10` |
18 +| 9 | §6.5, Table 17 | "clustering by city (153 clusters)" | 252 clusters (row added to table) | `scripts/11` prints `city clusters = 252` |
19 +| 10 | §5.8, **new Table 13** | random 80/20 split only (RF test R² 0.71) | 5-fold CV: random RF 0.647 / GBM 0.654 / OLS 0.477; FSA-blocked RF 0.431 / GBM 0.414 / OLS 0.467 (181 FSA groups); ML sample N = 4,370 stated | `scripts/09` `cross_validate_blocks()`; `ml_spatial_cv.tex` |
20 +| 11 | §1, §7.1, §8 | Duso et al. "7–13 euros per month per listing"; "strikingly close … mutual corroboration" | Duso et al. (2024) published abstract: each additional *commercial* listing displaces 0.23–0.37 units and raises rent/m² by 1.3–2.4 %; comparison rewritten in standardised terms (city-FE estimates exceed quasi-experimental magnitudes; FSA-FE estimates of the same order or smaller) | abstract verified (fis.leuphana.de record of RSUE 106, 104007) |
21 +| 12 | §2.1, §7.1 | Koster et al.: prices and rents "around 2 %" | about 3 % (published JUE abstract; 2 % was the 2018 WP) | Semantic Scholar record of DOI 10.1016/j.jue.2021.103356 |
22 +| 13 | §2.1 | Garcia-López et al.: "rents 1.9 %, transaction prices 4.6–7 % in high-activity areas" | rents +1.9 %, transaction +4.6 %, posted +3.7 % on average; rents +7 % in top-decile neighbourhoods | UAB WP / UCL record |
23 +| 14 | §2.2 | Combs et al.: "roughly 31,000 housing units removed" | "between 17,000 and 43,000 entire homes … unlikely to house a permanent resident" | CJUR abstract |
24 +| 15 | §5.1 | bedrooms "11–13 %", bathrooms "23–30 %" | 12–14 %, 26–30 % (100(e^β−1), columns 1b–1d) | Table 4 |
25 +| 16 | §4.4 / Table 7 note | spatial-table OLS presented as Model 1c | note: 15-city FE; "differs slightly from column (1c)" | `scripts/07` top-15 cities |
26 +| 17 | §1 | "over 11 million visitors", "vacancy rates historically low" (uncited) | softened to qualitative statements | no verifiable source in repo |
27 +| 18 | §7.3 | Montreal "limits on nights per year … prohibitions on non-owner-occupied STRs in certain boroughs" | provincial Tourist Accommodation Act (2022), 2023 platform-liability amendment, Montreal summer window (10 June–10 Sept, since 2025) and borough bans; footnoted official source; January 2026 scrape outside the window | quebec.ca / City of Montréal pages (2026-10-17) |
28 +| 19 | §5 / §6 | Figure `coefficient_buffer_comparison.pdf` included twice | once (§6.1) | — |
29 +| 20 | Appendix C | "available upon request" (×4) | correlation table included (Table A3); other outputs referenced to scripts | `correlation_matrix.tex` regenerated with labels |
30 +| 21 | All tables | raw variable names (`airbnb\_count\_500m`) | readable labels (`src/latex_tables.LABELS`); dep-var row as multicolumn | presentation |
31 +| 22 | Table 2 | no size row; no superhost/entire-home rows | interior size (N 3,699, mean 956, median 880; implausible extremes noted); superhost 0.53; entire-home 0.47 | `scripts/05` (column name `size_sqft` → `size_interior_sqft`) |
32 +| 23 | **New Table 1** | exposure statistics in prose ("mean ≈ 8") | mean 7.92, SD 14.20, median 1, P90 30, max 84, 44.1 % zeros at 500 m (and 250 m/1 km/2 km) | `exposure_summary.tex` |
33 +| 24 | main.tex | version 1.0, May 2026; JEL R21, R31, L83, C21 | version 1.1, October 2026; JEL + R52; keywords harmonised ("hedonic price function", "neighbourhood fixed effects"); `\theHequation` etc. (hyperref duplicate-destination warnings removed) | HARMONISATION.md |
34 +
35 +Unchanged numbers (verified identical after re-run): Table 4 (1a–1e), Table 9 (quantiles), Table 11 (city-level), Table 12 (ML hold-out), Table 14 (buffers), Table 16 (outliers), Table 17 columns R1–R5, leave-one-city-out range 0.0038–0.0040.
36 +
37 +## 2. References added (12, all verified — see REVIEW-REPORT §4 for DOIs)
38 +
39 +lee2016airbnb · calderwang2021distributional · conley1999gmm · kelejian2007hac · cameron2015practitioner · bishop2020best · kuminoff2014capitalization · oster2019unobservable · almagro2025location · hidalgo2024effect · fotheringham1991modifiable · cocola2021airbnb.
40 +Corrected: garcia2020airbnb, ke2017sharing, parmeter2010applied → parmeter2007nonparametric (+ DOIs on 16 existing entries). Removed: agyeman2020airbnb (unverifiable). Total 56 → 67.
41 +
42 +## 3. Reanalyses executed (script · runtime on Apple Silicon · output)
43 +
44 +| Script | Change | Runtime | Output |
45 +|---|---|---|---|
46 +| `05_descriptive_analysis.py` | size row; superhost/entire-home shares; labelled correlation table; exposure summary table; log-price histogram | 2 s | `summary_stats_*.tex`, `correlation_matrix.tex`, `exposure_summary.{tex,csv}`, `figures/dist_airbnb_logprice.pdf` |
47 +| `06_hedonic_models.py` | Model 2: (2c) without collinear regressor; (2d)–(2e) restricted sample; readable labels | 1 s | `hedonic_airbnb_pricing.tex`, `hedonic_rent_baseline.tex`, `city_level_interaction.tex` |
48 +| `07_spatial_models.py` | projected-km KNN; SAR `robust="white"`; LeSage–Pace impacts (exact trace + 2,000-draw simulation); JSON record | 3 s | `spatial_models.tex`, `spatial_impacts.tex`, `spatial_models.json`, `buffer_robustness.tex` |
49 +| `08_quantile_models.py` | labels; figure title without causal wording | 2 s | `quantile_regression.tex`, `figures/quantile_coefficients.pdf` |
50 +| `09_ml_robustness.py` | random vs FSA-blocked 5-fold CV | 28 s | `ml_spatial_cv.{tex,csv}` (+ unchanged hold-out outputs) |
51 +| `10_robustness_tables_figures.py` | exact building-type matches | 2 s | `robustness_subsamples.tex` (+ unchanged outlier table, figures) |
52 +| `11_extended_robustness.py` | cluster count row | 2 s | `extended_robustness.tex` |
53 +| **`12_neighbourhood_fe_inference.py` (new)** | FSA FE (F1–F6); HC1 / cluster / Conley SE comparison | ~20 s | `neighbourhood_fe.{tex,json}`, `inference_comparison.tex` |
54 +
55 +Steps 01–04 not re-run (raw data absent; merged parquets verified identical on 2026-08-05, `docs/AUDIT.md` §8).
56 +
57 +## 4. Text and structure
58 +
59 +- Abstract rewritten (two-layer result). §1 rewritten (identification made measurable; contributions reframed). §2: new identification/spatial-inference paragraphs; corrected magnitudes; new §2.5 title. §3: new §3.1 price caveat, exposure table, FSA description, buffer-overlap paragraph, limitations rewritten. §4: new §4.2 (FSA FE, hurdle, log), formal W, reduced form and impacts (Eq. 9), identification §4.8, standard errors §4.9. §5: new §5.2–5.4, §5.8 spatial CV; Model 2 rewritten. §6: interpretation of accumulation with radius; ring reading. §7: §7.1 rewritten; new §7.2 between/within; §7.3–7.4 toned down and updated; limitations by type; future work. §8 rewritten. Appendices: variable table (+fsa, any, ring), attrition; projection, impacts, Conley formulas; correlation table.
60 +- Removed: duplicate figure; "available upon request"; promotional wording ("strikingly close", "remarkably stable", "compelling setting").
61 +
62 +## 5. Not modified for lack of data
63 +
64 +Room type and host identity (not scraped); nightly vs total-stay price disambiguation (no stay-length field); census-tract FE (no boundary files downloaded per protocol); panel variation; contract rents.
65 +
66 +## 6. Build
67 +
68 +`cd paper && make`: 0 errors, 0 undefined references/citations, 0 BibTeX warnings, 59 pages, 1 overfull hbox of 0.98 pt (text line), no table overfull > 10 pt. Page 1: "Working Paper No. 5", title, author, "October 2026", "Version 1.1"; page 2: Abstract, Keywords, JEL.
added docs/REVIEW-REPORT.md +75 −0
@@ -0,0 +1,75 @@
1 +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca -->
2 +# REVIEW-REPORT — Editorial-board scientific review of UQO WP 5 (2026-10-17)
3 +
4 +**Paper:** *Airbnb, Residential Rents, and Housing Market Pressure: A Hedonic and Spatial Econometric Analysis* (v1.0, May 2026, 51 pages → v1.1, October 2026, 59 pages).
5 +**Protocol:** `Recherche-UQO/REVISION-MASTER-PROMPT.md` (8 phases) and `REVISION-PROTOCOLE.md`. Pre-revision state: git tag `pre-revision-20261017`, `docs/main_pre-revision-20261017.pdf`.
6 +**Audit trail of every change:** `docs/CHANGELOG-REVISION.md`.
7 +
8 +## 1. Summary verdict
9 +
10 +The v1.0 manuscript was a competently executed cross-sectional hedonic study whose headline claim — a stable 0.4 % rent premium per nearby Airbnb listing, "strikingly close" to quasi-experimental magnitudes — did not survive the two checks that a referee in urban economics would ask for first: (i) location fixed effects finer than the city and (ii) standard errors that respect the spatial dependence of a buffer-based exposure variable. Both were feasible with the committed data (postal codes → forward sortation areas; coordinates → Conley HAC) and were run during this review. **With FSA fixed effects the coefficient falls from 0.0039 to 0.0008 and is not distinguishable from zero under Conley or FSA-clustered inference; with city fixed effects the HC1 standard error understates the spatial standard error by a factor of ≈ 3.** The paper has been rewritten around this result: the city-FE estimate is now presented as an upper bound, the association as predominantly between-neighbourhood, and the policy discussion toned down accordingly. Three further defects were corrected: a bimodal, partly total-stay Airbnb price field (which produced the v1.0 "superhost discount"), a collinear regressor reported with a pseudo-inverse coefficient in the Airbnb pricing model, and three misquoted benchmark magnitudes (Duso et al., Koster et al., Garcia-López et al.). The revised paper is honest, better identified in its claims, and better referenced; its publishable contribution is now *methodological-empirical* (what a cross-sectional STR–rent correlation is worth once neighbourhood FE and spatial inference are applied, documented for a new market) rather than a new positive estimate.
11 +
12 +## 2. Section-by-section diagnosis
13 +
14 +| Section | Strengths (v1.0) | Weaknesses / errors found | Action |
15 +|---|---|---|---|
16 +| Abstract | Clear, cautious wording | "approximately 5,000 Airbnb listings" (3,456 analysed; 30.9 % had no price); results stated as if robust; no mention of FE resolution or spatial SEs | Rewritten with correct N and the two-layer result |
17 +| 1 Introduction | Good motivation, P2P framing, explicit endogeneity paragraph | Uncited facts ("over 11 million visitors", "historically low vacancy"); magnitude preview relied on a misread of Duso et al.; contributions overstated ("mutual corroboration") | Facts softened; preview rewritten; contributions reframed |
18 +| 2 Literature | Thematic, 56 refs, mostly verified | 3 defective entries (Garcia-López title; Ke venue/author; Parmeter 2010 non-existent), 1 unverifiable (Agyeman 2020); misquoted magnitudes; no spatial-inference, identification-bounds or endogenous-amenity literature; Calder-Wang, Lee, Conley, Kelejian–Prucha 2007, Cameron–Miller, Bishop et al., Kuminoff–Pope, Oster, Almagro–Domínguez-Iino, Hidalgo et al., Fotheringham–Wong, Cocola-Gant–Gago absent | 12 added, 3 corrected, 1 removed; all 67 Crossref/DOI-verified; identification subsection added |
19 +| 3 Data | Transparent cleaning, Haversine merge formalised | Airbnb price bimodality (26.5 % > $1,000 "per night") not noticed although the summary table showed mean $1,233 vs median $220; exposure distribution (44 % zeros at 500 m) described in one sentence; postal codes available but unused; nested/overlapping buffers not discussed; ML/1e samples (N = 4,370) not explained; scrape date, winter composition, Realtor.ca selection unmentioned | Price caveat + log-scale figure; exposure table; FSA description; buffer-overlap paragraph; limitations rewritten |
20 +| 4 Methodology | Equations for all models | No formal W; SAR coefficient read as marginal effect; Model 2 "θ identified from variation absorbed by FE" is false (collinear); "153 cities" in clusters (252); no FSA FE; no spatial SE; "row-standardisation guarantees non-empty neighbourhoods" wrong (it is the KNN) | Added Eq. for FSA FE, hurdle/log forms, W, reduced form, LeSage–Pace impacts, Conley/cluster formulas; identification rewritten as "measurable" |
21 +| 5 Results | Accurate reading of tables | SAR "attenuation" (0.0034 vs 0.0038) misread (total impact 0.0040); spatial table uses 15-city FE, not stated; superhost discount interpreted as composition; bedroom/bathroom % slightly off; quantile differences not tested; ML split leakage unaddressed | New §5.2 FSA, §5.3 inference, §5.4 impacts, §5.8 spatial CV; Model 2 restricted sample |
22 +| 6 Robustness | Broad battery | Buffer figure duplicated (same PDF in §5 and §6); "Houses" subsample included townhouses; "153 clusters" | Fixed; accumulation-with-radius interpretation added |
23 +| 7 Discussion | Candid about two disagreements | Magnitude comparison factually wrong (Berlin "7–13 €/month" is 1.3–2.4 % per m² per commercial listing; LA 2 % is 3 %; Barcelona 4.6–7 % conflated prices/rents); regulation description partly outdated; limitations list-like | Rewritten in standardised terms; new between/within subsection; regulation updated with footnoted official source; limitations by type |
24 +| 8 Conclusion | Cautious | Repeated the "5,000", "mutual corroboration" claims | Rewritten |
25 +| Appendices | Haversine, W, QR, ML | Several "available upon request"; correlation matrix generated but not included (raw underscores) | Correlation table included; Conley/impacts/projection documented |
26 +
27 +## 3. Methodology verdicts (master prompt §3)
28 +
29 +- **Specification justified:** yes for the hedonic form; the v1.0 reliance on city FE alone was not justified given available postal codes — now remedied (FSA FE).
30 +- **Estimation assumptions explicit:** now yes (exogeneity failure channels, FE scope, SAR reduced form, Conley kernel).
31 +- **Variables correctly defined:** yes after corrections (entire-home = property-type proxy, stated; composition variables undefined at zero exposure, stated; density = rescaled count).
32 +- **Fixed effects appropriate:** city FE insufficient — the core finding of the review; FSA FE implemented; quantile/spatial models still use coarse city groups (stated as a limitation).
33 +- **Spatial dependence defensible:** W now on projected coordinates (v1.0 used degrees → anisotropic neighbourhoods; effect on estimates marginal: ρ 0.137 → 0.134); impacts reported; SEM λ ≈ 0.54 motivates HAC SEs.
34 +- **Standard errors:** v1.0 HC1 only (plus one city-cluster column that *tightened* SEs — a symptom of a dominant cluster, not a reassurance). Now HC1 / cluster-city / cluster-FSA / Conley 1–10 km; FSA-cluster and Conley agree (0.0007 vs HC1 0.0002).
35 +- **Sample construction transparent:** now yes (attrition, matched-city N = 2,437, restricted N = 1,699, FSA singletons, ML N = 4,370).
36 +- **Robustness addresses genuine threats:** v1.0 battery addressed stability, not identification; the FSA/Conley/spatial-CV analyses address the genuine threats.
37 +- **Coefficient interpretation:** semi-elasticities now given exactly (100(e^β−1)); SAR impacts; log(1+count) elasticity; density rescaling.
38 +- **Statistical vs economic significance:** distinguished ($8 vs $1.6 per listing at the median; 1 SD = 5.5 % vs 1.2 %).
39 +- **Causal claims:** none; "effect/impact" reserved for the spatial-econometric sense.
40 +
41 +## 4. Literature (all entries verified via Crossref `api.crossref.org/works`, DOI resolution, or publisher/working-paper page)
42 +
43 +- **Corrected:** `garcia2020airbnb` (title → "Do short-term rental platforms affect housing markets? Evidence from Airbnb in Barcelona", DOI 10.1016/j.jue.2020.103278); `ke2017sharing` (→ Qing Ke, WebSci '17, pp. 131–139, DOI 10.1145/3091478.3091504; v1.0 gave a non-existent IJHM article); `parmeter2010applied` (non-existent) → `parmeter2007nonparametric` (JAE 22(3), 10.1002/jae.929); DOIs added to barron2021effect (10.1287/mksc.2020.1227), horn2017airbnb, wachsmuth2018airbnb, nieuwland2020regulating, palmquist2005property, rosen1974hedonic, koenker1978regression, zietz2008determinants, gyourko2005superstar, glaeser2005urban, saiz2010geographic, athey2019machine, mullainathan2017machine, tibshirani1996regression, breiman2001random, friedman2001greedy; sheppard2016airbnb given its WP number (2016-03).
44 +- **Removed:** `agyeman2020airbnb` (no such Urban Studies article found in Crossref; only McLaren & Agyeman book chapters).
45 +- **Added (12):** lee2016airbnb (HLPR 10(1) 229–253); calderwang2021distributional (SSRN 3908062, working paper — publication status unresolved, cited as such); conley1999gmm (10.1016/S0304-4076(98)00084-0); kelejian2007hac (10.1016/j.jeconom.2006.09.005); cameron2015practitioner (10.3368/jhr.50.2.317); bishop2020best (10.1093/reep/reaa001); kuminoff2014capitalization (10.1111/iere.12088); oster2019unobservable (10.1080/07350015.2016.1227711); almagro2025location (Econometrica 93(3), 10.3982/ECTA21394); hidalgo2024effect (JRS 64(3), 10.1111/jors.12685); fotheringham1991modifiable (10.1068/a231025); cocola2021airbnb (10.1177/0308518X19869012).
46 +- **Facts re-verified against abstracts:** Horn & Merante (1 SD → 0.4 %, confirmed); Koster et al. published abstract (listings −50 %, prices −3 %, rents −3 %; WP version said 2 %); Duso et al. published abstract (0.23–0.37 units displaced, rent/m² +1.3–2.4 % per commercial listing); Garcia-López et al. (rents +1.9 %, transaction +4.6 %, posted +3.7 %; top decile rents +7 %); Combs et al. (17,000–43,000 entire homes; v1.0 "31,000" replaced by the published range).
47 +- Count: 56 → **67** references, all cited, 0 BibTeX warnings.
48 +
49 +## 5. Results — inconsistencies found and resolved
50 +
51 +1. Abstract/intro/conclusion "≈ 5,000 Airbnb listings" vs 3,456 analysed. 2. Model 2 column (2c) reported a coefficient (0.0307) on a regressor perfectly collinear with city FE. 3. Spatial table OLS column (15-city FE, β 0.0038) compared to Model 1c (252-city FE, 0.0039) as if the same specification. 4. "153 clusters" (actual 252). 5. "Houses" subsample included 48 townhouses (0.0067 → 0.0059 after exact match). 6. SAR coefficient read as attenuated marginal effect (total impact 0.0040). 7. Bedroom/bathroom percentages (11–13/23–30 → 12–14/26–30 exact). 8. Garcia-López "4.6–7 % prices in high-activity areas" conflated two outcomes. 9. Duso "7–13 € per month per listing" — not in the published paper. 10. Koster "2 %" → 3 %. 11. ML sample N = 4,370 (not 7,925) unstated. 12. Figure duplicated.
52 +
53 +## 6. Reanalyses executed (all from versioned scripts; see CHANGELOG §3 for timings)
54 +
55 +FSA fixed effects (6 specifications); HC1 / cluster-city / cluster-FSA / Conley (1, 2, 5, 10 km) SEs for the city-FE and FSA-FE estimates; SAR/SEM on projected-coordinate KNN weights with White-robust SAR SEs; LeSage–Pace impacts with simulated SEs; Model 2 without the collinear regressor and on the ≤ $1,000 subsample; random vs FSA-blocked 5-fold CV for the five ML models; exact-match building-type subsamples; exposure summary table; log-scale price histogram; correlation table.
56 +
57 +## 7. Analyses recommended, not executed
58 +
59 +- **Quantile regressions with FSA fixed effects** — 289 groups require penalised fixed-effects QR (Koenker 2004); not implemented, incidental-parameter concerns.
60 +- **SAR/SEM with FSA fixed effects** — spreg GM estimators with ~290 dummies and instrument proliferation; feasible but outside the 30-minute budget for careful implementation.
61 +- **Formal test of equality of quantile coefficients** (bootstrap); **wild cluster bootstrap** by city (Montreal dominance makes it the appropriate complement to Conley).
62 +- **Oster (2019) bounds** — coefficient movements reported qualitatively (0.0020 → 0.0048 → 0.0039 → 0.0008); the formal δ is ill-suited because observables move the coefficient away from zero while FE move it toward zero.
63 +- **Alternative neighbourhood units** (census tracts / dissemination areas) — would require a geocoding step with external boundary files (not downloaded per protocol).
64 +- **Panel / event-study designs** around Quebec's registration regime and Montreal's 2025 seasonal rule — require repeated scrapes.
65 +- **Host-resolved data**, room type, contract rents — data not available.
66 +
67 +## 8. Remaining limitations
68 +
69 +Single cross-section; asking rents from the agent-listed segment; winter scrape; bimodal price field; no room type / host ID; FSAs are delivery zones, not submarkets; spatial and quantile models use coarse city groups; Montreal = 59 % of the sample.
70 +
71 +## 9. Maturity for publication
72 +
73 +- **Target journals:** *Journal of Housing Economics*, *Regional Science and Urban Economics*, *Journal of Real Estate Research*, *Canadian Journal of Economics* (Canadian evidence), *Urban Studies*. Not JUE/REE at this stage (no causal identification).
74 +- **Risks of rejection:** (i) "a null result after FE" without a causal design — mitigate by framing as the first Canadian listing-level evidence plus a methodological demonstration that cross-sectional STR–rent correlations are mostly between-neighbourhood (the paper now does this); (ii) data quality of the scraped Airbnb file (price field, no room type) — now disclosed, but a referee may ask for a re-scrape with room type and nightly price; (iii) representativeness of Realtor.ca asking rents; (iv) absence of FE in quantile/spatial models.
75 +- **Verdict:** publishable as a careful descriptive-cum-methodological working paper after one more data pass (re-scrape with room type/host ID); the v1.1 text is internally consistent, all numbers are regenerated by the pipeline, and the claims are commensurate with the design.
modified figures/airbnb_by_city.pdf +0 −0

Binary file not shown.

modified figures/coefficient_buffer_comparison.pdf +0 −0

Binary file not shown.

modified figures/coefficient_robustness.pdf +0 −0

Binary file not shown.

added figures/dist_airbnb_logprice.pdf +0 −0

Binary file not shown.

modified figures/dist_airbnb_price.pdf +0 −0

Binary file not shown.

modified figures/dist_rent.pdf +0 −0

Binary file not shown.

modified figures/feature_importance.pdf +0 −0

Binary file not shown.

modified figures/leave_one_city_out.pdf +0 −0

Binary file not shown.

modified figures/map_airbnb.pdf +0 −0

Binary file not shown.

modified figures/map_rent.pdf +0 −0

Binary file not shown.

modified figures/ml_predicted_vs_actual.pdf +0 −0

Binary file not shown.

modified figures/quantile_coefficients.pdf +0 −0

Binary file not shown.

modified figures/rent_airbnb_heatmap.pdf +0 −0

Binary file not shown.

modified figures/rent_by_airbnb_bins.pdf +0 −0

Binary file not shown.

modified figures/rent_by_city.pdf +0 −0

Binary file not shown.

modified figures/scatter_airbnb_rent.pdf +0 −0

Binary file not shown.

modified figures/shap_summary.pdf +0 −0

Binary file not shown.

modified paper/appendix/appendix_data.tex +34 −36
@@ -6,79 +6,84 @@
6 6
7 7 \subsection{Variable Definitions}
8 8
9 −Table~\ref{tab:var_definitions} provides a comprehensive list of variables used in the analysis, including their definitions, sources, and units.
9 +Table~\ref{tab:var_definitions} lists the variables used in the analysis, with their sources, definitions and units.
10 10
11 11 \begin{table}[htbp]
12 12 \centering
13 13 \caption{Variable Definitions}
14 14 \label{tab:var_definitions}
15 − \small
15 + \footnotesize\setlength{\tabcolsep}{4pt}
16 16 \begin{tabularx}{\textwidth}{l l X l}
17 17 \toprule
18 18 \textbf{Variable} & \textbf{Source} & \textbf{Definition} & \textbf{Unit} \\
19 19 \midrule
20 20 \multicolumn{4}{l}{\textit{Rental listing variables}} \\
21 21 \addlinespace
22 − \texttt{rent} & Realtor.ca & Monthly asking rent & CAD \\
22 + \texttt{rent} & Realtor.ca & Monthly asking rent (winsorised at p1/p99) & CAD \\
23 23 \texttt{log\_rent} & Constructed & Natural log of monthly rent & --- \\
24 24 \texttt{bedrooms} & Realtor.ca & Number of bedrooms & Count \\
25 25 \texttt{bathrooms} & Realtor.ca & Number of bathrooms (total) & Count \\
26 26 \texttt{building\_type} & Realtor.ca & Building type (Apartment, House, Row/Townhouse) & Category \\
27 − \texttt{size\_interior} & Realtor.ca & Interior floor area & sq ft \\
27 + \texttt{size\_interior} & Realtor.ca & Interior floor area (reported for 3{,}699 listings) & sq ft \\
28 28 \texttt{lat}, \texttt{lon} & Realtor.ca & Latitude and longitude of the listing & Degrees \\
29 − \texttt{city} & Realtor.ca & City / municipality name & Category \\
29 + \texttt{city} & Realtor.ca & Municipality (standardised; boroughs collapsed) & Category \\
30 + \texttt{postal\_code} & Realtor.ca & Six-character postal code & Category \\
31 + \texttt{fsa} & Constructed & Forward sortation area (first three characters of the postal code) & Category \\
30 32 \addlinespace
31 33 \midrule
32 34 \multicolumn{4}{l}{\textit{Airbnb listing variables}} \\
33 35 \addlinespace
34 − \texttt{price\_numeric} & Airbnb & Nightly asking price & CAD \\
35 − \texttt{log\_price} & Constructed & Natural log of nightly price & --- \\
36 − \texttt{property\_type} & Airbnb & Property type (Rental unit, House, Cabin/Chalet, Condo, Apartment) & Category \\
37 − \texttt{rating} & Airbnb & Star rating (0--5 scale) & Numeric \\
38 − \texttt{num\_reviews} & Airbnb & Number of guest reviews & Count \\
36 + \texttt{price\_numeric} & Airbnb & Displayed price (winsorised at p1/p99; see Section~\ref{sec:data_airbnb}) & CAD \\
37 + \texttt{log\_price} & Constructed & Natural log of displayed price & --- \\
38 + \texttt{property\_type} & Airbnb & Property type (Rental unit, House, Cabin/Chalet, Condo, Apartment, Other) & Category \\
39 + \texttt{rating} & Airbnb & Star rating (median-imputed when missing) & 0--5 \\
40 + \texttt{num\_reviews} & Airbnb & Number of guest reviews (zero when missing) & Count \\
41 + \texttt{bedrooms}, \texttt{bathrooms} & Airbnb & Number of bedrooms and bathrooms & Count \\
42 + \texttt{guests\_count} & Airbnb & Maximum number of guests & Count \\
43 + \texttt{amenities\_count} & Airbnb & Number of listed amenities & Count \\
39 44 \texttt{is\_superhost} & Airbnb & Superhost status indicator & Binary \\
40 − \texttt{is\_guest\_favorite} & Airbnb & Guest favourite designation & Binary \\
41 − \texttt{pets\_allowed} & Airbnb & Whether pets are allowed & Binary \\
42 − \texttt{is\_entire\_home} & Constructed & Indicator for entire-home property types & Binary \\
45 + \texttt{is\_entire\_home} & Constructed & Property type in \{House, Cabin/Chalet, Condo\} & Binary \\
43 46 \texttt{lat}, \texttt{lon} & Airbnb & Latitude and longitude of the listing & Degrees \\
44 47 \texttt{city} & Airbnb & City name (standardised) & Category \\
45 48 \addlinespace
46 49 \midrule
47 − \multicolumn{4}{l}{\textit{Airbnb exposure variables (constructed via spatial buffer merge)}} \\
50 + \multicolumn{4}{l}{\textit{Airbnb exposure variables (spatial buffer merge, $r \in \{250\text{\,m}, 500\text{\,m}, 1\text{\,km}, 2\text{\,km}\}$)}} \\
48 51 \addlinespace
49 − \texttt{airbnb\_count\_$r$} & Constructed & Number of Airbnb listings within radius $r$ & Count \\
50 − \texttt{airbnb\_density\_$r$} & Constructed & Airbnb count / buffer area ($\pi r^2$) & Per km$^2$ \\
51 − \texttt{mean\_airbnb\_price\_$r$} & Constructed & Mean Airbnb nightly price within radius $r$ & CAD \\
52 − \texttt{share\_entire\_home\_$r$} & Constructed & Share of entire-home Airbnb listings within $r$ & Proportion \\
53 − \texttt{mean\_rating\_$r$} & Constructed & Mean rating of Airbnb listings within $r$ & Numeric \\
52 + \texttt{airbnb\_count\_$r$} ($A_{i,r}$) & Constructed & Number of Airbnb listings within radius $r$ & Count \\
53 + \texttt{airbnb\_density\_$r$} & Constructed & $A_{i,r}/(\pi r^2)$ & Per km$^2$ \\
54 + \texttt{mean\_airbnb\_price\_$r$} & Constructed & Mean displayed price of Airbnb listings within $r$ (undefined if $A_{i,r}=0$) & CAD \\
55 + \texttt{share\_entire\_home\_$r$} & Constructed & Share of entire-home listings within $r$ (undefined if $A_{i,r}=0$) & Proportion \\
56 + \texttt{mean\_rating\_$r$} & Constructed & Mean rating within $r$ & 0--5 \\
54 57 \texttt{superhost\_share\_$r$} & Constructed & Share of superhost listings within $r$ & Proportion \\
58 + \texttt{any\_airbnb\_500m} & Constructed & $\mathbf{1}[A_{i,500\text{m}}>0]$ & Binary \\
59 + \texttt{airbnb\_ring\_500m\_1km} & Constructed & $A_{i,1\text{km}} - A_{i,500\text{m}}$ & Count \\
55 60 \addlinespace
56 61 \midrule
57 62 \multicolumn{4}{l}{\textit{City-level variables}} \\
58 63 \addlinespace
59 − \texttt{airbnb\_count\_city} & Constructed & Total Airbnb listings in the city & Count \\
60 − \texttt{mean\_airbnb\_price\_city} & Constructed & City-level mean Airbnb nightly price & CAD \\
61 − \texttt{share\_entire\_home\_city} & Constructed & City-level share of entire-home listings & Proportion \\
62 − \texttt{mean\_rent\_city} & Constructed & City-level mean monthly rent & CAD \\
64 + \texttt{airbnb\_count\_city} ($A_c$) & Constructed & Total Airbnb listings in the city & Count \\
65 + \texttt{mean\_rent\_city} & Constructed & City mean of \texttt{log\_rent} & --- \\
66 + \texttt{mean\_airbnb\_price\_city} & Constructed & City mean displayed Airbnb price & CAD \\
67 + \texttt{share\_entire\_home\_city} & Constructed & City share of entire-home listings & Proportion \\
63 68 \bottomrule
64 69 \end{tabularx}
65 70 \begin{flushleft}
66 − \footnotesize\textit{Notes:} Buffer radii $r \in \{250\text{m}, 500\text{m}, 1\text{km}, 2\text{km}\}$. All monetary values are in Canadian dollars (CAD). ``Constructed'' indicates variables derived from the raw data during the cleaning and merge stages.
71 + \footnotesize\textit{Notes:} All monetary values are in Canadian dollars. ``Constructed'' indicates variables derived during cleaning and merging.
67 72 \end{flushleft}
68 73 \end{table}
69 74
70 75 \subsection{City Name Standardisation}
71 76
72 −The Airbnb dataset contains city names with inconsistent formatting, including accented and unaccented variants and abbreviations. Table~\ref{tab:city_mapping} lists the standardisation mapping applied during data cleaning.
77 +The Airbnb data contain city names with inconsistent formatting, and the Realtor.ca addresses identify Montreal boroughs, Quebec City and Longueuil arrondissements and similar subdivisions, which are collapsed to the municipality. Table~\ref{tab:city_mapping} lists the explicit mappings applied to the Airbnb data; the rental data are standardised by prefix rules in \texttt{scripts/03\_clean\_rent.py}.
73 78
74 79 \begin{table}[htbp]
75 80 \centering
76 − \caption{City Name Standardisation Mapping}
81 + \caption{City Name Standardisation Mapping (Airbnb Data)}
77 82 \label{tab:city_mapping}
78 83 \small
79 84 \begin{tabular}{ll}
80 85 \toprule
81 − \textbf{Original Name(s)} & \textbf{Standardised Name} \\
86 + \textbf{Original name(s)} & \textbf{Standardised name} \\
82 87 \midrule
83 88 Montr\'{e}al & Montreal \\
84 89 Qu\'{e}bec City, Quebec City, Quebec & Qu\'{e}bec \\
@@ -91,13 +96,6 @@ The Airbnb dataset contains city names with inconsistent formatting, including a
91 96 \end{tabular}
92 97 \end{table}
93 98
94 −\subsection{Sample Attrition}
95 −
96 −The following summarises the sample attrition at each stage of data cleaning:
99 +\subsection{Sample Construction}
97 100
98 −\begin{itemize}
99 − \item \textbf{Airbnb:} Raw dataset $\approx 5{,}000$ listings. After dropping listings with missing or non-positive prices, the cleaned sample retains 3{,}456 listings.
100 − \item \textbf{Rentals:} Raw dataset of 8{,}356 records. After restricting to single-family properties with monthly rental periods and positive parsed rents, the cleaned sample retains 8{,}303 listings, all with valid coordinates.
101 − \item \textbf{Spatial merge:} All rental listings with valid coordinates are retained; the Airbnb count is zero for listings with no Airbnb neighbours within the buffer radius (composition variables such as the mean nearby price are undefined in that case).
102 − \item \textbf{Regressions:} The baseline hedonic sample comprises the 7{,}925 rental listings with non-missing bedrooms and bathrooms.
103 −\end{itemize}
101 +The Airbnb file contains 5{,}000 listings, of which 1{,}544 (30.9\%) have no price and are dropped, leaving 3{,}456 listings, all with coordinates; 2{,}437 of them are located in a municipality with rental listings and enter the Airbnb pricing model, and 1{,}699 of those are priced at or below \$1{,}000 per night. The Realtor.ca file contains 8{,}356 records; restricting to single-family residential listings with a monthly rental period and a positive parsed rent leaves 8{,}303 listings, all with valid coordinates and postal codes. All 8{,}303 enter the spatial merge; the Airbnb count is zero for listings with no Airbnb within the radius, and the composition variables are undefined in that case (4{,}370 listings have positive 500\,m exposure). The baseline regression sample comprises the 7{,}925 listings with non-missing bedrooms; the FSA-fixed-effects sample drops singleton FSAs (7{,}883 listings in 289 FSAs); the interior-size specifications use 3{,}531 (city fixed effects) and 3{,}485 (FSA fixed effects) listings.
modified paper/appendix/appendix_methods.tex +27 −39
@@ -4,62 +4,50 @@
4 4 % =============================================================================
5 5 \section{Methodological Appendix}\label{app:methods}
6 6
7 −\subsection{Haversine Distance Formula}\label{app:haversine}
8 −
9 −The Haversine formula computes the great-circle distance between two points on the surface of a sphere, given their latitudes and longitudes. For two points $(lat_1, lon_1)$ and $(lat_2, lon_2)$ expressed in radians, the Haversine distance is:
7 +\subsection{Haversine Distance}\label{app:haversine}
10 8
9 +The Haversine formula gives the great-circle distance between two points on a sphere from their latitudes and longitudes. For points $(\phi_1, \lambda_1)$ and $(\phi_2, \lambda_2)$ in radians,
11 10 \begin{equation}\label{eq:haversine}
12 − d = 2R \cdot \arcsin\!\left(\sqrt{\sin^2\!\left(\frac{\Delta lat}{2}\right) + \cos(lat_1) \cdot \cos(lat_2) \cdot \sin^2\!\left(\frac{\Delta lon}{2}\right)}\right),
11 + d = 2R \arcsin\!\left(\sqrt{\sin^2\!\left(\tfrac{\Delta\phi}{2}\right) + \cos\phi_1 \cos\phi_2 \sin^2\!\left(\tfrac{\Delta\lambda}{2}\right)}\right),
13 12 \end{equation}
13 +where $R = 6{,}371$\,km is the mean Earth radius, $\Delta\phi = \phi_2-\phi_1$ and $\Delta\lambda = \lambda_2-\lambda_1$. For distances below a few kilometres the difference from the geodesic distance on the reference ellipsoid is negligible. In the spatial merge (Section~\ref{sec:spatial_merge}) the distance matrix between each chunk of 500 rental listings and all 3{,}456 Airbnb listings is computed in vectorised form, and buffer membership is determined by comparing each element against the radius. The same routine computes the pairwise distances between rental listings used by the Conley estimator.
14 14
15 −\noindent where:
16 −\begin{itemize}
17 − \item $R = 6{,}371$ km is the mean radius of the Earth;
18 − \item $\Delta lat = lat_2 - lat_1$ is the difference in latitudes;
19 − \item $\Delta lon = lon_2 - lon_1$ is the difference in longitudes.
20 −\end{itemize}
21 −
22 −The Haversine formula provides an accurate approximation for short to medium distances on the Earth's surface. For the distances relevant in our application (typically less than 5 km), the approximation error relative to the exact geodesic distance (Vincenty's formula) is negligible.
23 −
24 −\paragraph{Implementation.} In our spatial merge (Section~\ref{sec:spatial_merge}), the Haversine distance is computed in vectorised form using NumPy. For each chunk of rental listings, we compute the full pairwise distance matrix between the chunk and all Airbnb listings, yielding an $(n_{\text{chunk}} \times n_{\text{Airbnb}})$ matrix of distances. Buffer membership is determined by comparing each element of this matrix against the threshold radius $r$.
15 +\subsection{Spatial Weights, Estimation and Impacts}\label{app:spatial_weights}
25 16
26 −\subsection{Spatial Weights Construction}\label{app:spatial_weights}
27 −
28 −The spatial weights matrix $\mathbf{W}$ used in Model~4 (Equation~\ref{eq:spatial_lag}) is a $k$-nearest-neighbour matrix with $k = 5$. For each rental listing $i$, the neighbourhood $\mathcal{N}_i$ is the set of the five rental listings closest to $i$ in Euclidean coordinate space (excluding $i$ itself):
17 +\paragraph{Projection.} Nearest neighbours are determined on coordinates projected to kilometres by an equirectangular projection centred on the sample centroid, $x = 111.32\cos(\bar\phi)\,(\lambda-\bar\lambda)$ and $y = 111.32\,(\phi-\bar\phi)$ with angles in degrees. An earlier version of the analysis searched for neighbours in raw degree coordinates; at the latitude of Quebec one degree of longitude spans about 0.69 of a degree of latitude, so those neighbourhoods were stretched east--west. The correction changes the spatial estimates only marginally ($\hat\rho$ from 0.137 to 0.134, $\hat\lambda$ from 0.539 to 0.544).
29 18
19 +\paragraph{Weights.} The weights matrix $\mathbf{W}$ is a $k$-nearest-neighbour matrix with $k=5$: for each rental listing $i$, $\mathcal{N}_i$ is the set of the five other rental listings closest to $i$ in projected coordinates, and
30 20 \begin{equation}
31 − w_{ik} = \begin{cases}
32 − \frac{1}{5} & \text{if } k \in \mathcal{N}_i, \\[4pt]
33 − 0 & \text{otherwise},
34 − \end{cases}
21 + w_{ik} = \begin{cases} 1/5 & \text{if } k \in \mathcal{N}_i, \\ 0 & \text{otherwise,} \end{cases}
35 22 \end{equation}
23 +so that $\sum_k w_{ik}\ln(\text{rent}_k)$ is the mean log rent of the five nearest listings. A nearest-neighbour definition guarantees that every listing has a neighbourhood, which a fixed-radius definition would not in sparse areas; the resulting graph is not fully connected (140 components), which does not affect the generalised-moments estimators. Listings in the same building share coordinates and are each other's nearest neighbours. The choice $k=5$ balances responsiveness against noise; in dense urban areas the five nearest listings lie within a few hundred metres.
36 24
37 −\noindent so that the spatial lag $\sum_k w_{ik} \ln(\text{rent}_k)$ is the mean log rent of listing $i$'s five nearest neighbours. Row-standardisation guarantees that every observation has a well-defined, equally weighted neighbourhood, avoiding the empty-neighbourhood problem that a fixed-radius definition would create in sparse rural areas.
25 +\paragraph{Estimation.} The spatial lag $\sum_k w_{ik}\ln(\text{rent}_k)$ is correlated with the disturbance, so OLS estimation of Equation~\eqref{eq:spatial_lag} is inconsistent. The SAR model is estimated by the spatial two-stage least squares estimator of \citet{kelejian1998generalized}, which instruments the lag with the spatially lagged exogenous regressors $\mathbf{W}\mathbf{X}$ (\texttt{GM\_Lag} in \texttt{spreg}, White-robust standard errors); the SEM by the generalised-moments estimator of \citet{kelejian1999generalized} for $\lambda$ followed by feasible generalised least squares (\texttt{GM\_Error}), whose standard errors are the classical GM ones. Both include building-type dummies and fixed effects for the fifteen largest cities with the remaining cities grouped.
38 26
39 −\paragraph{Choice of $k$.} The choice of $k = 5$ balances two considerations. A smaller $k$ would capture only the most proximate listings, yielding a responsive but noisy spatial lag; a larger $k$ would average over a broader area, reducing noise but blurring relevant spatial variation---and, in dense urban cores, five nearest neighbours typically lie within a few hundred metres.
27 +\paragraph{Impacts.} With $\mathbf{S} = (\mathbf{I}-\rho\mathbf{W})^{-1}$, the average direct impact of regressor $x$ is $\beta_x\, n^{-1}\mathrm{tr}(\mathbf{S})$, the average total impact is $\beta_x\, n^{-1}\boldsymbol{\iota}'\mathbf{S}\boldsymbol{\iota} = \beta_x/(1-\rho)$ for a row-standardised $\mathbf{W}$, and the average indirect impact is their difference \citep{lesage2009introduction}. At the point estimates the trace is computed exactly from a sparse LU factorisation of $\mathbf{I}-\hat\rho\mathbf{W}$. Standard errors are obtained from 2{,}000 draws of $(\beta_x,\rho)$ from the estimated asymptotic normal distribution of the spatial two-stage least squares estimator; for each draw the trace is evaluated through the series $\mathrm{tr}(\mathbf{S}) = \sum_{k\ge0}\rho^k\,\mathrm{tr}(\mathbf{W}^k)$, truncated at $k=60$, with $\mathrm{tr}(\mathbf{W}^0)=n$, $\mathrm{tr}(\mathbf{W})=0$ and the higher-order traces estimated by Hutchinson's stochastic estimator with 50 Rademacher vectors. The series and the exact trace agree to five decimals at the point estimate.
40 28
41 −\paragraph{Estimation.} The inclusion of a spatial lag of the dependent variable as a regressor introduces a well-known simultaneity problem: $\sum_k w_{ik} \ln(\text{rent}_k)$ is correlated with $\eta_i$ whenever the errors are spatially correlated, so OLS estimation of Equation~\ref{eq:spatial_lag} would be inconsistent. We therefore estimate the SAR model by the generalised-moments instrumental-variable estimator of Kelejian and Prucha (\texttt{GM\_Lag} in \texttt{spreg}), which instruments the spatial lag with spatially lagged exogenous regressors, and the SEM by the corresponding \texttt{GM\_Error} estimator \citep{anselin1988spatial, lesage2009introduction}.
29 +\subsection{Fixed-Effects Estimation and Spatial HAC Standard Errors}\label{app:conley}
42 30
43 −\subsection{Quantile Regression Estimation}
31 +The city- and FSA-fixed-effects specifications in Tables~\ref{tab:neighbourhood_fe} and~\ref{tab:inference} are estimated by the within transformation: $\tilde{y}_i = y_i - \bar y_{g(i)}$ and $\tilde{\mathbf{x}}_i = \mathbf{x}_i - \bar{\mathbf{x}}_{g(i)}$, where $g(i)$ is the city or FSA of listing $i$, and $\hat{\boldsymbol\beta} = (\tilde{\mathbf{X}}'\tilde{\mathbf{X}})^{-1}\tilde{\mathbf{X}}'\tilde{\mathbf{y}}$. Groups with a single listing are dropped. With $\hat e_i$ the residuals and $\mathbf{s}_i = \tilde{\mathbf{x}}_i \hat e_i$ the scores, the covariance estimators share the sandwich form $\hat{\mathbf{V}} = (\tilde{\mathbf{X}}'\tilde{\mathbf{X}})^{-1}\,\hat{\mathbf{M}}\,(\tilde{\mathbf{X}}'\tilde{\mathbf{X}})^{-1}$ and differ in the meat $\hat{\mathbf{M}}$:
32 +\begin{align}
33 + \hat{\mathbf{M}}_{\text{HC1}} &= \frac{n}{n-k-G}\sum_i \mathbf{s}_i\mathbf{s}_i', \\
34 + \hat{\mathbf{M}}_{\text{cluster}} &= \frac{C}{C-1}\,\frac{n-1}{n-k}\sum_{c=1}^{C}\Big(\sum_{i\in c}\mathbf{s}_i\Big)\Big(\sum_{i\in c}\mathbf{s}_i\Big)', \\
35 + \hat{\mathbf{M}}_{\text{Conley}} &= \sum_i\sum_j K(d_{ij})\,\mathbf{s}_i\mathbf{s}_j', \qquad K(d) = \max\{0,\,1-d/\bar d\},
36 +\end{align}
37 +where $G$ is the number of absorbed groups, $C$ the number of clusters, $d_{ij}$ the great-circle distance between listings $i$ and $j$, and $\bar d$ the cutoff (1, 2, 5 or 10\,km). The Bartlett kernel guarantees a positive semi-definite estimate \citep{conley1999gmm, kelejian2007hac}. Pairs at zero distance (units in the same building) receive weight one, so the Conley estimator also absorbs within-building correlation. The double sum is evaluated exactly in chunks of 500 listings against all others, without a sparsity approximation.
44 38
45 −The quantile regression model at quantile $\tau$ (Equation~\ref{eq:quantile}) is estimated by minimising the asymmetrically weighted sum of absolute residuals:
39 +\subsection{Quantile Regression Estimation}
46 40
41 +The quantile regression at quantile $\tau$ (Equation~\ref{eq:quantile}) minimises the asymmetrically weighted sum of absolute residuals,
47 42 \begin{equation}
48 − \hat{\boldsymbol{\beta}}_\tau = \arg\min_{\boldsymbol{\beta}} \sum_{i=1}^{n} \rho_\tau\!\left(\ln(\text{rent}_i) - \mathbf{X}_i' \boldsymbol{\beta}\right),
43 + \hat{\boldsymbol{\beta}}_\tau = \arg\min_{\boldsymbol{\beta}} \sum_{i=1}^{n} \rho_\tau\!\left(\ln(\text{rent}_i) - \mathbf{X}_i' \boldsymbol{\beta}\right), \qquad \rho_\tau(u) = u\,(\tau - \mathbf{1}[u < 0]),
49 44 \end{equation}
45 +\citep{koenker1978regression}, solved by iteratively reweighted least squares in \texttt{statsmodels}. Standard errors are the asymptotic estimates based on a kernel estimate of the conditional density of the response at the fitted quantile (the \texttt{statsmodels} default), which are consistent under independent but not necessarily identically distributed errors and do not account for spatial dependence.
50 46
51 −\noindent where $\rho_\tau(u) = u(\tau - \mathbf{1}[u < 0])$ is the check function \citep{koenker1978regression}. We estimate the model with the iteratively reweighted least squares algorithm implemented in \texttt{statsmodels}.
52 −
53 −Standard errors are the asymptotic estimates based on the kernel estimate of the conditional density of the response at the fitted quantile (the default in \texttt{statsmodels}), which are consistent under independent but not necessarily identically distributed errors.
54 −
55 −\subsection{Machine-Learning Model Details}
47 +\subsection{Machine-Learning Models}
56 48
57 −\paragraph{LASSO and Elastic Net.} The LASSO model \citep{tibshirani1996regression} estimates:
58 −\begin{equation}
59 − \hat{\boldsymbol{\beta}}_{\text{LASSO}} = \arg\min_{\boldsymbol{\beta}} \left\{ \frac{1}{2n}\|\mathbf{y} - \mathbf{X}\boldsymbol{\beta}\|_2^2 + \lambda \|\boldsymbol{\beta}\|_1 \right\},
60 −\end{equation}
61 −where $\lambda > 0$ is the regularisation parameter selected by 5-fold cross-validation. The elastic net extends this with an $L_2$ penalty, controlled by a mixing parameter $\alpha \in (0,1)$.
49 +\paragraph{Regularised linear models.} The LASSO \citep{tibshirani1996regression} solves $\min_{\boldsymbol\beta}\{\tfrac{1}{2n}\|\mathbf{y}-\mathbf{X}\boldsymbol\beta\|_2^2 + \lambda\|\boldsymbol\beta\|_1\}$, and the elastic net \citep{zou2005regularization} adds an $\ell_2$ penalty with a mixing parameter; both regularisation parameters are chosen by five-fold cross-validation within the training data, and features are standardised.
62 50
63 −\paragraph{Random Forest.} The random forest model \citep{breiman2001random} constructs an ensemble of $B = 500$ regression trees with a maximum depth of 15, each trained on a bootstrap sample with random feature subsampling.
51 +\paragraph{Tree ensembles.} The random forest \citep{breiman2001random} averages 500 regression trees of maximum depth 15, each grown on a bootstrap sample with random feature subsampling. Gradient boosting \citep{friedman2001greedy} fits 500 trees of maximum depth 5 sequentially to the residuals of the current ensemble with a learning rate of 0.05. SHAP values \citep{lundberg2017unified} are computed on the hold-out set with the tree explainer.
64 52
65 −\paragraph{Gradient Boosting.} The gradient boosting model \citep{friedman2001greedy} sequentially fits shallow regression trees to the residuals of the current ensemble. We use 500 boosting iterations, a maximum tree depth of 5, and a learning rate of 0.05. SHAP (SHapley Additive exPlanations) values \citep{lundberg2017unified} are computed on the held-out test set from the fitted gradient boosting model to quantify the contribution of each feature to individual predictions.
53 +\paragraph{Evaluation.} The hold-out evaluation uses a random 80/20 split with a fixed seed. The cross-validation uses five folds under two designs: random folds (shuffled with the same seed) and spatially blocked folds, in which \texttt{GroupKFold} assigns whole FSAs (181 groups in the 4{,}370-listing sample) to folds, so that no test listing shares a neighbourhood with a training listing. Within each training fold the scaler and the regularisation parameters are re-estimated.
modified paper/appendix/appendix_robustness.tex +11 −21
@@ -1,27 +1,17 @@
1 1 % Author: Simon-Pierre Boucher — contact@spboucher.ai
2 2 % =============================================================================
3 −% appendix_robustness.tex — Additional robustness tables
3 +% appendix_robustness.tex — Additional tables
4 4 % =============================================================================
5 −\section{Additional Robustness Results}\label{app:robustness}
5 +\section{Additional Tables}\label{app:robustness}
6 6
7 −This appendix presents additional robustness checks that supplement the results reported in Section~\ref{sec:robustness}.
7 +This appendix reports the correlation matrix of the 500\,m exposure measures and dwelling controls referred to in Section~\ref{sec:data}. Full regression output for every specification, including the fixed-effect coefficients, the quantile-regression control coefficients and the machine-learning cross-validation folds, is produced by the replication scripts in the paper's repository (\texttt{scripts/05} to \texttt{scripts/12}) and is not reproduced here.
8 8
9 −\subsection{Full Regression Output --- Baseline Hedonic Model}
9 +\begin{table}[htbp]
10 + \centering
11 + \caption{Correlation Matrix --- Log Rent, Airbnb Exposure (500\,m) and Dwelling Controls}
12 + \label{tab:correlation}
13 + \small
14 + \input{../results/tables/correlation_matrix.tex}
15 +\end{table}
10 16
11 −The preferred hedonic rent specification (Model~1c in Table~\ref{tab:hedonic_rent}) includes property controls (bedrooms, bathrooms, building type) and city fixed effects. Full regression output including all control variable coefficients and city fixed effects is available upon request.
12 −
13 −\subsection{Correlation Matrix of Airbnb Exposure Measures}
14 −
15 −The pairwise correlation matrix of the Airbnb exposure variables at the 500\,m buffer radius documents the degree of collinearity among alternative exposure measures. The various exposure measures---count, density, share of entire-home listings, mean price---are positively correlated, reflecting the spatial concentration of Airbnb activity.
16 −
17 −\subsection{Quantile Regression --- Full Coefficient Tables}
18 −
19 −The quantile regression results reported in Table~\ref{tab:quantile} focus on the Airbnb exposure coefficient across the rent distribution. Full coefficient tables including control variables at each quantile are available upon request.
20 −
21 −\subsection{Machine-Learning Cross-Validation Results}
22 −
23 −Table~\ref{tab:ml_performance} in the main text reports hold-out sample performance for all machine-learning models. The gradient boosting and random forest models achieve substantially higher $R^2$ on the test set relative to linear models, suggesting meaningful nonlinearities in the rent--amenity relationship.
24 −
25 −\subsection{Additional Subsample Results}
26 −
27 −The subsample analysis in Section~\ref{sec:robustness} examines Montreal versus non-Montreal and apartment versus house subsamples. Additional subsample results (e.g., by Airbnb exposure quartile or by borough-level regulation status) are available upon request.
17 +The exposure count is positively but weakly correlated with log rent (0.14) and negatively correlated with bedrooms ($-0.19$), which accounts for the increase in the Airbnb coefficient when dwelling controls are added (Section~\ref{sec:results_baseline}). The entire-home share is negatively correlated with the count ($-0.19$): neighbourhoods with many Airbnb listings have a lower share of houses, chalets and condos among them, consistent with urban rental units dominating dense STR clusters.
modified paper/main.pdf +0 −0

Binary file not shown.

modified paper/main.tex +34 −24
@@ -102,6 +102,9 @@
102 102 \setcounter{figure}{0}%
103 103 \renewcommand{\theequation}{A.\arabic{equation}}%
104 104 \setcounter{equation}{0}%
105 + \renewcommand{\theHequation}{A.\arabic{equation}}%
106 + \renewcommand{\theHtable}{A\arabic{table}}%
107 + \renewcommand{\theHfigure}{A\arabic{figure}}%
105 108 }
106 109
107 110 % --- Graphics Path ---
@@ -113,32 +116,39 @@
113 116 \newcommand{\WPnumber}{5}
114 117 \newcommand{\WPtitle}{Airbnb, Residential Rents, and Housing Market Pressure: A Hedonic and Spatial Econometric Analysis}
115 118 \newcommand{\WPsubtitle}{}
116 −\newcommand{\WPdate}{May 2026}
117 −\newcommand{\WPversion}{1.0}
119 +\newcommand{\WPdate}{October 2026}
120 +\newcommand{\WPversion}{1.1}
118 121 \newcommand{\WPabstract}{%
119 −This paper investigates the relationship between Airbnb short-term rental
120 −activity and residential rents in Quebec, Canada. Using cross-sectional
121 −microdata comprising approximately 5,000 Airbnb listings and 8,300
122 −residential rental listings, we employ a hedonic pricing framework augmented
123 −with spatial econometric techniques to quantify the conditional association
124 −between nearby Airbnb presence and monthly rents. For each rental listing we
125 −construct Airbnb exposure measures within 250\,m, 500\,m, 1\,km, and 2\,km
126 −buffers using Haversine distances. Our baseline estimates indicate that an
127 −additional Airbnb listing within 500\,m is associated with a statistically
128 −significant increase in monthly rent of approximately 0.3--0.5\%, controlling
129 −for dwelling characteristics, building type, and city fixed effects. Quantile
130 −regressions reveal that this association is stronger at the upper tail of the
131 −rent distribution. A complementary hedonic model of Airbnb nightly prices
132 −indicates that short-term rental pricing is driven primarily by listing
133 −characteristics, with no significant premium attached to city-level rents.
134 −Robustness checks---including alternative buffer radii, subsample
135 −analyses, and machine-learning benchmarks---confirm the stability of the
136 −rent--exposure association. We discuss the policy implications of these results for housing
137 −affordability and short-term rental regulation, while cautioning that
138 −cross-sectional associations should not be interpreted as causal effects.%
122 +This paper examines the relationship between short-term rental (STR) activity
123 +and residential rents in Quebec, Canada, using a 2026 cross-section of 3{,}456
124 +Airbnb listings and 8{,}303 residential rental listings with precise
125 +coordinates. For each rental listing we count the Airbnb listings within
126 +250\,m, 500\,m, 1\,km and 2\,km (Haversine distances) and estimate hedonic rent
127 +equations with building-type and location fixed effects. With city fixed
128 +effects, one additional Airbnb listing within 500\,m is associated with
129 +monthly rents about 0.4\% higher (0.3--0.5\% across specifications), the
130 +per-listing coefficient decays with distance, the association is larger at the
131 +upper quantiles of the conditional rent distribution, and it survives spatial
132 +lag and spatial error models (total impact 0.40\%). Two further results
133 +qualify this picture. First, heteroskedasticity-robust standard errors
134 +overstate precision: Conley spatial HAC and neighbourhood-clustered standard
135 +errors are about three times larger, although the city-fixed-effects estimate
136 +remains significant. Second, with fixed effects for forward sortation areas
137 +(postal-code neighbourhoods), the coefficient falls to 0.08\% per listing and
138 +is not distinguishable from zero under spatial inference, with the same
139 +pattern for logarithmic and extensive-margin exposure measures. The
140 +Airbnb--rent association in these data is therefore predominantly a
141 +between-neighbourhood phenomenon, consistent with STR supply concentrating in
142 +high-amenity, high-rent neighbourhoods rather than with a within-neighbourhood
143 +causal effect. Spatially blocked cross-validation shows that the apparent
144 +advantage of tree-based machine-learning models over the linear hedonic model
145 +disappears when test neighbourhoods are unseen, and a hedonic model of Airbnb
146 +nightly prices finds no premium attached to city-level rents. We discuss the
147 +implications for the interpretation of cross-sectional STR--rent correlations
148 +and for Quebec's registration-based regulation.%
139 149 }
140 −\newcommand{\WPkeywords}{Airbnb, short-term rentals, housing rents, hedonic pricing, spatial econometrics, housing affordability, Quebec}
141 −\newcommand{\WPjel}{R21, R31, L83, C21}
150 +\newcommand{\WPkeywords}{Airbnb, short-term rentals, housing rents, hedonic price function, neighbourhood fixed effects, spatial econometrics, Quebec}
151 +\newcommand{\WPjel}{R21, R31, R52, L83, C21}
142 152
143 153 % --- Author ---
144 154 \newcommand{\WPauthor}{Simon-Pierre Boucher}
modified paper/references.bib +508 −381
@@ -1,301 +1,83 @@
1 1 % Author: Simon-Pierre Boucher — contact (at) spboucher.ai
2 2 % =============================================================================
3 −% references.bib
4 −% IMPORTANT: All entries below are reconstructed from memory and NEED
5 −% VERIFICATION against the actual publications before submission.
6 −% Check titles, journal names, volume/issue numbers, page ranges, and DOIs.
3 +% references.bib — UQO Working Paper No. 5
4 +% 2026-08-05: 24 original entries + 32 added (Crossref-verified).
5 +% 2026-10-17 (editorial-board revision): every entry re-verified against
6 +% Crossref (DOI resolved) or the publisher/working-paper page; DOIs added to
7 +% all journal articles; three defective entries corrected or replaced
8 +% (garcia2020airbnb title; ke2017sharing venue/author; parmeter2010applied ->
9 +% parmeter2007nonparametric); one unverifiable entry removed
10 +% (agyeman2020airbnb); 12 entries added. See docs/CHANGELOG-REVISION.md.
7 11 % =============================================================================
8 12
9 13 % ── Short-term rentals and housing markets ──────────────────────────────────
10 14
11 15 @article{barron2021effect,
12 − title = {The Effect of Home-Sharing on House Prices and Rents: Evidence from {Airbnb}},
13 − author = {Barron, Kyle and Kung, Edward and Proserpio, Davide},
14 − journal = {Marketing Science},
15 − volume = {40},
16 − number = {1},
17 − pages = {23--47},
18 − year = {2021},
19 − publisher = {INFORMS},
16 + author = {Barron, Kyle and Kung, Edward and Proserpio, Davide},
17 + title = {The Effect of Home-Sharing on House Prices and Rents: Evidence from {Airbnb}},
18 + journal = {Marketing Science},
19 + year = {2021},
20 + volume = {40},
21 + number = {1},
22 + pages = {23--47},
23 + doi = {10.1287/mksc.2020.1227}
20 24 }
21 25
22 26 @techreport{sheppard2016airbnb,
23 − title = {Do {Airbnb} Properties Affect House Prices?},
24 27 author = {Sheppard, Stephen and Udell, Andrew},
25 − institution = {Williams College Department of Economics},
26 − year = {2016},
28 + title = {Do {Airbnb} Properties Affect House Prices?},
29 + institution = {Department of Economics, Williams College},
27 30 type = {Working Paper},
31 + number = {2016-03},
32 + year = {2016},
33 + address = {Williamstown, MA}
28 34 }
29 35
30 36 @article{garcia2020airbnb,
31 − title = {{Airbnb}, Short-Term Rentals and Housing Prices: Evidence from {Barcelona}},
32 − author = {Garcia-L\'{o}pez, Miquel-\`{A}ngel and Jofre-Monseny, Jordi and Mart\'{i}nez-Mazza, Rodrigo and Segú, Mariona},
33 − journal = {Journal of Urban Economics},
34 − volume = {119},
35 − pages = {103278},
36 − year = {2020},
37 − publisher = {Elsevier},
37 + author = {Garcia-L\'{o}pez, Miquel-\`{A}ngel and Jofre-Monseny, Jordi and Mart\'{i}nez-Mazza, Rodrigo and Seg\'{u}, Mariona},
38 + title = {Do Short-Term Rental Platforms Affect Housing Markets? {Evidence} from {Airbnb} in {Barcelona}},
39 + journal = {Journal of Urban Economics},
40 + year = {2020},
41 + volume = {119},
42 + pages = {103278},
43 + doi = {10.1016/j.jue.2020.103278}
38 44 }
39 45
40 46 @article{horn2017airbnb,
41 − title = {Is Home Sharing Driving Up Rents? Evidence from {Airbnb} in {Boston}},
42 − author = {Horn, Keren and Merante, Mark},
43 − journal = {Journal of Housing Economics},
44 − volume = {38},
45 − pages = {14--24},
46 − year = {2017},
47 − publisher = {Elsevier},
47 + author = {Horn, Keren and Merante, Mark},
48 + title = {Is Home Sharing Driving Up Rents? {Evidence} from {Airbnb} in {Boston}},
49 + journal = {Journal of Housing Economics},
50 + year = {2017},
51 + volume = {38},
52 + pages = {14--24},
53 + doi = {10.1016/j.jhe.2017.08.002}
48 54 }
49 55
50 56 @article{wachsmuth2018airbnb,
51 − title = {{Airbnb} and the Rent Gap: Gentrification Through the Sharing Economy},
52 − author = {Wachsmuth, David and Weisler, Alexander},
53 − journal = {Environment and Planning A: Economy and Space},
54 − volume = {50},
55 − number = {6},
56 − pages = {1147--1170},
57 − year = {2018},
58 − publisher = {SAGE Publications},
59 −}
60 −
61 −@article{ke2017sharing,
62 − title = {Short-Term Rentals and the Sharing Economy: The Case of {Airbnb}},
63 − author = {Ke, Qiulin},
64 − journal = {International Journal of Hospitality Management},
65 − volume = {67},
66 − pages = {120--129},
67 − year = {2017},
68 − publisher = {Elsevier},
69 −}
70 −
71 −% ── Hedonic pricing theory ──────────────────────────────────────────────────
72 −
73 −@article{rosen1974hedonic,
74 − title = {Hedonic Prices and Implicit Markets: Product Differentiation in Pure Competition},
75 − author = {Rosen, Sherwin},
76 − journal = {Journal of Political Economy},
77 − volume = {82},
78 − number = {1},
79 − pages = {34--55},
80 − year = {1974},
81 − publisher = {University of Chicago Press},
82 −}
83 −
84 −@incollection{palmquist2005property,
85 − title = {Property Value Models},
86 − author = {Palmquist, Raymond B.},
87 − booktitle = {Handbook of Environmental Economics},
88 − editor = {M\"{a}ler, Karl-G\"{o}ran and Vincent, Jeffrey R.},
89 − volume = {2},
90 − pages = {763--819},
91 − year = {2005},
92 − publisher = {Elsevier},
93 −}
94 −
95 −@article{parmeter2010applied,
96 − title = {Applied Nonparametric Instrumental Variables Estimation},
97 − author = {Parmeter, Christopher F. and Henderson, Daniel J. and Kumbhakar, Subal C.},
98 − journal = {Econometric Reviews},
99 − volume = {29},
100 − number = {4},
101 − pages = {398--418},
102 − year = {2010},
103 − publisher = {Taylor \& Francis},
104 −}
105 −
106 −% ── Spatial econometrics ────────────────────────────────────────────────────
107 −
108 −@book{anselin1988spatial,
109 − title = {Spatial Econometrics: Methods and Models},
110 − author = {Anselin, Luc},
111 − year = {1988},
112 − publisher = {Kluwer Academic Publishers},
113 − address = {Dordrecht},
114 −}
115 −
116 −@book{lesage2009introduction,
117 − title = {Introduction to Spatial Econometrics},
118 − author = {LeSage, James P. and Pace, R. Kelley},
119 − year = {2009},
120 − publisher = {CRC Press},
121 − address = {Boca Raton, FL},
122 −}
123 −
124 −% ── Quantile regression ────────────────────────────────────────────────────
125 −
126 −@article{koenker1978regression,
127 − title = {Regression Quantiles},
128 − author = {Koenker, Roger and Bassett, Gilbert},
129 − journal = {Econometrica},
130 − volume = {46},
131 − number = {1},
132 − pages = {33--50},
133 − year = {1978},
134 − publisher = {Econometric Society},
135 −}
136 −
137 −@article{zietz2008determinants,
138 − title = {Determinants of House Prices: A Quantile Regression Approach},
139 − author = {Zietz, Joachim and Zietz, Emily Norman and Sirmans, G. Stacy},
140 − journal = {Journal of Real Estate Finance and Economics},
141 − volume = {37},
142 − number = {4},
143 − pages = {317--333},
144 − year = {2008},
145 − publisher = {Springer},
146 −}
147 −
148 −% ── Machine learning and econometrics ───────────────────────────────────────
149 −
150 −@article{mullainathan2017machine,
151 − title = {Machine Learning: An Applied Econometric Approach},
152 − author = {Mullainathan, Sendhil and Spiess, Jann},
153 − journal = {Journal of Economic Perspectives},
154 − volume = {31},
155 − number = {2},
156 − pages = {87--106},
157 − year = {2017},
158 − publisher = {American Economic Association},
159 −}
160 −
161 −@article{athey2019machine,
162 − title = {Machine Learning Methods That Economists Should Know About},
163 − author = {Athey, Susan and Imbens, Guido W.},
164 − journal = {Annual Review of Economics},
165 − volume = {11},
166 − pages = {685--725},
167 − year = {2019},
168 − publisher = {Annual Reviews},
169 −}
170 −
171 −@article{tibshirani1996regression,
172 − title = {Regression Shrinkage and Selection via the {Lasso}},
173 − author = {Tibshirani, Robert},
174 − journal = {Journal of the Royal Statistical Society: Series B (Methodological)},
175 − volume = {58},
176 − number = {1},
177 − pages = {267--288},
178 − year = {1996},
179 − publisher = {Wiley},
180 −}
181 −
182 −@article{breiman2001random,
183 − title = {Random Forests},
184 − author = {Breiman, Leo},
185 − journal = {Machine Learning},
186 − volume = {45},
187 − number = {1},
188 − pages = {5--32},
189 − year = {2001},
190 − publisher = {Springer},
191 −}
192 −
193 −@article{friedman2001greedy,
194 − title = {Greedy Function Approximation: A Gradient Boosting Machine},
195 − author = {Friedman, Jerome H.},
196 − journal = {Annals of Statistics},
197 − volume = {29},
198 − number = {5},
199 − pages = {1189--1232},
200 − year = {2001},
201 − publisher = {Institute of Mathematical Statistics},
57 + author = {Wachsmuth, David and Weisler, Alexander},
58 + title = {{Airbnb} and the Rent Gap: Gentrification Through the Sharing Economy},
59 + journal = {Environment and Planning A: Economy and Space},
60 + year = {2018},
61 + volume = {50},
62 + number = {6},
63 + pages = {1147--1170},
64 + doi = {10.1177/0308518X18778038}
202 65 }
203 66
204 −@inproceedings{lundberg2017unified,
205 − title = {A Unified Approach to Interpreting Model Predictions},
206 − author = {Lundberg, Scott M. and Lee, Su-In},
207 − booktitle = {Advances in Neural Information Processing Systems},
208 − volume = {30},
209 − pages = {4765--4774},
67 +@inproceedings{ke2017sharing,
68 + author = {Ke, Qing},
69 + title = {Sharing Means Renting? {An} Entire-Marketplace Analysis of {Airbnb}},
70 + booktitle = {Proceedings of the 2017 ACM on Web Science Conference (WebSci~'17)},
210 71 year = {2017},
211 −}
212 −
213 −% ── Regulation and policy ──────────────────────────────────────────────────
214 −
215 −@article{nieuwland2020regulating,
216 − title = {Regulating {Airbnb}: How Cities Deal with Perceived Negative Externalities of Short-Term Rentals},
217 − author = {Nieuwland, Shirley and van Melik, Rianne},
218 − journal = {Current Issues in Tourism},
219 − volume = {23},
220 − number = {7},
221 − pages = {811--825},
222 − year = {2020},
223 − publisher = {Taylor \& Francis},
224 −}
225 −
226 −@article{agyeman2020airbnb,
227 − title = {{Airbnb} and the Undoing of Mid-Twentieth Century Housing Policy},
228 − author = {Agyeman, Julian and McLaren, Duncan and Schaefer-Borrego, Adrianne},
229 − journal = {Urban Studies},
230 − volume = {57},
231 − number = {14},
232 − pages = {2998--3015},
233 − year = {2020},
234 − publisher = {SAGE Publications},
235 −}
236 −
237 −% ── Housing economics ──────────────────────────────────────────────────────
238 −
239 −@article{glaeser2005urban,
240 − title = {Urban Growth and Housing Supply},
241 − author = {Glaeser, Edward L. and Gyourko, Joseph and Saks, Raven E.},
242 − journal = {Journal of Economic Geography},
243 − volume = {6},
244 − number = {1},
245 − pages = {71--89},
246 − year = {2006},
247 − publisher = {Oxford University Press},
248 −}
249 −
250 −@article{saiz2010geographic,
251 − title = {The Geographic Determinants of Housing Supply},
252 − author = {Saiz, Albert},
253 − journal = {Quarterly Journal of Economics},
254 − volume = {125},
255 − number = {3},
256 − pages = {1253--1296},
257 − year = {2010},
258 − publisher = {Oxford University Press},
259 −}
260 −
261 −@article{gyourko2005superstar,
262 − title = {Superstar Cities},
263 − author = {Gyourko, Joseph and Mayer, Christopher and Sinai, Todd},
264 − journal = {American Economic Journal: Economic Policy},
265 − volume = {5},
266 − number = {4},
267 − pages = {167--199},
268 − year = {2013},
269 − publisher = {American Economic Association},
270 −}
271 −
272 −% ── Added 2026-08-05 (scholarly upgrade) — every entry verified via Crossref/JMLR ──
273 −
274 −@article{zervas2017rise,
275 − author = {Zervas, Georgios and Proserpio, Davide and Byers, John W.},
276 − title = {The Rise of the Sharing Economy: Estimating the Impact of {Airbnb} on the Hotel Industry},
277 − journal = {Journal of Marketing Research},
278 − year = {2017},
279 − volume = {54},
280 − number = {5},
281 − pages = {687--705},
282 − doi = {10.1509/jmr.15.0204}
283 −}
284 −
285 −@article{farronato2022welfare,
286 − author = {Farronato, Chiara and Fradkin, Andrey},
287 − title = {The Welfare Effects of Peer Entry: The Case of {Airbnb} and the Accommodation Industry},
288 − journal = {American Economic Review},
289 − year = {2022},
290 − volume = {112},
291 − number = {6},
292 − pages = {1782--1817},
293 − doi = {10.1257/aer.20180260}
72 + pages = {131--139},
73 + publisher = {ACM},
74 + address = {Troy, NY},
75 + doi = {10.1145/3091478.3091504}
294 76 }
295 77
296 78 @article{koster2021short,
297 79 author = {Koster, Hans R. A. and van Ommeren, Jos and Volkhausen, Nicolas},
298 − title = {Short-term rentals and the housing market: Quasi-experimental evidence from {Airbnb} in {Los Angeles}},
80 + title = {Short-Term Rentals and the Housing Market: Quasi-Experimental Evidence from {Airbnb} in {Los Angeles}},
299 81 journal = {Journal of Urban Economics},
300 82 year = {2021},
301 83 volume = {124},
@@ -305,7 +87,7 @@
305 87
306 88 @article{valentin2021regulating,
307 89 author = {Valentin, Maxence},
308 − title = {Regulating short-term rental housing: Evidence from {New Orleans}},
90 + title = {Regulating Short-Term Rental Housing: Evidence from {New Orleans}},
309 91 journal = {Real Estate Economics},
310 92 year = {2021},
311 93 volume = {49},
@@ -316,7 +98,7 @@
316 98
317 99 @article{duso2024airbnb,
318 100 author = {Duso, Tomaso and Michelsen, Claus and Sch{\"a}fer, Maximilian and Tran, Kevin Ducbao},
319 − title = {Airbnb and rental markets: Evidence from {Berlin}},
101 + title = {{Airbnb} and Rental Markets: Evidence from {Berlin}},
320 102 journal = {Regional Science and Urban Economics},
321 103 year = {2024},
322 104 volume = {106},
@@ -326,7 +108,7 @@
326 108
327 109 @article{franco2021impact,
328 110 author = {Franco, Sofia F. and Santos, Carlos Daniel},
329 − title = {The impact of {Airbnb} on residential property values and rents: Evidence from {Portugal}},
111 + title = {The Impact of {Airbnb} on Residential Property Values and Rents: Evidence from {Portugal}},
330 112 journal = {Regional Science and Urban Economics},
331 113 year = {2021},
332 114 volume = {88},
@@ -356,9 +138,62 @@
356 138 doi = {10.1287/mnsc.2021.4288}
357 139 }
358 140
141 +@article{shabrina2022airbnb,
142 + author = {Shabrina, Zahratu and Arcaute, Elsa and Batty, Michael},
143 + title = {{Airbnb} and Its Potential Impact on the {London} Housing Market},
144 + journal = {Urban Studies},
145 + year = {2022},
146 + volume = {59},
147 + number = {1},
148 + pages = {197--221},
149 + doi = {10.1177/0042098020970865}
150 +}
151 +
152 +@article{lee2016airbnb,
153 + author = {Lee, Dayne},
154 + title = {How {Airbnb} Short-Term Rentals Exacerbate {Los Angeles}'s Affordable Housing Crisis: Analysis and Policy Recommendations},
155 + journal = {Harvard Law \& Policy Review},
156 + year = {2016},
157 + volume = {10},
158 + number = {1},
159 + pages = {229--253}
160 +}
161 +
162 +@unpublished{calderwang2021distributional,
163 + author = {Calder-Wang, Sophie},
164 + title = {The Distributional Impact of the Sharing Economy on the Housing Market},
165 + note = {Working paper, The Wharton School, University of Pennsylvania; SSRN 3908062},
166 + year = {2021},
167 + doi = {10.2139/ssrn.3908062}
168 +}
169 +
170 +@article{almagro2025location,
171 + author = {Almagro, Milena and Dom\'{i}nguez-Iino, Tom\'{a}s},
172 + title = {Location Sorting and Endogenous Amenities: Evidence from {Amsterdam}},
173 + journal = {Econometrica},
174 + year = {2025},
175 + volume = {93},
176 + number = {3},
177 + pages = {1031--1071},
178 + doi = {10.3982/ECTA21394}
179 +}
180 +
181 +@article{hidalgo2024effect,
182 + author = {Hidalgo, Alberto and Riccaboni, Massimo and Vel\'{a}zquez, Francisco J.},
183 + title = {The Effect of Short-Term Rentals on Local Consumption Amenities: Evidence from {Madrid}},
184 + journal = {Journal of Regional Science},
185 + year = {2024},
186 + volume = {64},
187 + number = {3},
188 + pages = {621--648},
189 + doi = {10.1111/jors.12685}
190 +}
191 +
192 +% ── Canadian evidence ───────────────────────────────────────────────────────
193 +
359 194 @article{combs2020short,
360 195 author = {Combs, Jennifer and Kerrigan, Danielle and Wachsmuth, David},
361 − title = {Short-term rentals in {Canada}: Uneven growth, uneven impacts},
196 + title = {Short-Term Rentals in {Canada}: Uneven Growth, Uneven Impacts},
362 197 journal = {Canadian Journal of Urban Research},
363 198 year = {2020},
364 199 volume = {29},
@@ -369,7 +204,7 @@
369 204
370 205 @article{grisdale2021displacement,
371 206 author = {Grisdale, Sean},
372 − title = {Displacement by disruption: short-term rentals and the political economy of ``belonging anywhere'' in {Toronto}},
207 + title = {Displacement by Disruption: Short-Term Rentals and the Political Economy of ``Belonging Anywhere'' in {Toronto}},
373 208 journal = {Urban Geography},
374 209 year = {2021},
375 210 volume = {42},
@@ -378,53 +213,62 @@
378 213 doi = {10.1080/02723638.2019.1642714}
379 214 }
380 215
381 −@article{shabrina2022airbnb,
382 − author = {Shabrina, Zahratu and Arcaute, Elsa and Batty, Michael},
383 − title = {Airbnb and its potential impact on the {London} housing market},
384 − journal = {Urban Studies},
385 − year = {2022},
386 − volume = {59},
387 − number = {1},
388 − pages = {197--221},
389 − doi = {10.1177/0042098020970865}
216 +% ── Peer-to-peer markets and STR pricing ────────────────────────────────────
217 +
218 +@article{zervas2017rise,
219 + author = {Zervas, Georgios and Proserpio, Davide and Byers, John W.},
220 + title = {The Rise of the Sharing Economy: Estimating the Impact of {Airbnb} on the Hotel Industry},
221 + journal = {Journal of Marketing Research},
222 + year = {2017},
223 + volume = {54},
224 + number = {5},
225 + pages = {687--705},
226 + doi = {10.1509/jmr.15.0204}
390 227 }
391 228
392 −@article{gotham2005tourism,
393 − author = {Gotham, Kevin Fox},
394 − title = {Tourism Gentrification: The Case of {New Orleans}' {Vieux Carr\'e} ({French Quarter})},
395 − journal = {Urban Studies},
396 − year = {2005},
397 − volume = {42},
398 − number = {7},
399 − pages = {1099--1121},
400 − doi = {10.1080/00420980500120881}
229 +@article{farronato2022welfare,
230 + author = {Farronato, Chiara and Fradkin, Andrey},
231 + title = {The Welfare Effects of Peer Entry: The Case of {Airbnb} and the Accommodation Industry},
232 + journal = {American Economic Review},
233 + year = {2022},
234 + volume = {112},
235 + number = {6},
236 + pages = {1782--1817},
237 + doi = {10.1257/aer.20180260}
401 238 }
402 239
403 −@article{cocola2016holiday,
404 − author = {Cocola-Gant, Agustin},
405 − title = {Holiday Rentals: The New Gentrification Battlefront},
406 − journal = {Sociological Research Online},
240 +@article{einav2016peer,
241 + author = {Einav, Liran and Farronato, Chiara and Levin, Jonathan},
242 + title = {Peer-to-Peer Markets},
243 + journal = {Annual Review of Economics},
407 244 year = {2016},
408 − volume = {21},
409 − number = {3},
410 − pages = {112--120},
411 − doi = {10.5153/sro.4071}
245 + volume = {8},
246 + pages = {615--635},
247 + doi = {10.1146/annurev-economics-080315-015334}
412 248 }
413 249
414 −@article{gurran2017when,
415 − author = {Gurran, Nicole and Phibbs, Peter},
416 − title = {When Tourists Move In: How Should Urban Planners Respond to {Airbnb}?},
417 − journal = {Journal of the American Planning Association},
418 − year = {2017},
419 − volume = {83},
420 − number = {1},
421 − pages = {80--92},
422 − doi = {10.1080/01944363.2016.1249011}
250 +@book{sundararajan2016sharing,
251 + author = {Sundararajan, Arun},
252 + title = {The Sharing Economy: The End of Employment and the Rise of Crowd-Based Capitalism},
253 + publisher = {MIT Press},
254 + address = {Cambridge, MA},
255 + year = {2016}
256 +}
257 +
258 +@article{guttentag2015airbnb,
259 + author = {Guttentag, Daniel},
260 + title = {{Airbnb}: Disruptive Innovation and the Rise of an Informal Tourism Accommodation Sector},
261 + journal = {Current Issues in Tourism},
262 + year = {2015},
263 + volume = {18},
264 + number = {12},
265 + pages = {1192--1217},
266 + doi = {10.1080/13683500.2013.827159}
423 267 }
424 268
425 269 @article{wang2017price,
426 270 author = {Wang, Dan and Nicolau, Juan L.},
427 − title = {Price determinants of sharing economy based accommodation rental: A study of listings from 33 cities on {Airbnb.com}},
271 + title = {Price Determinants of Sharing Economy Based Accommodation Rental: A Study of Listings from 33 Cities on {Airbnb.com}},
428 272 journal = {International Journal of Hospitality Management},
429 273 year = {2017},
430 274 volume = {62},
@@ -434,7 +278,7 @@
434 278
435 279 @article{gibbs2018pricing,
436 280 author = {Gibbs, Chris and Guttentag, Daniel and Gretzel, Ulrike and Morton, Jym and Goodwill, Alasdair},
437 − title = {Pricing in the sharing economy: a hedonic pricing model applied to {Airbnb} listings},
281 + title = {Pricing in the Sharing Economy: A Hedonic Pricing Model Applied to {Airbnb} Listings},
438 282 journal = {Journal of Travel \& Tourism Marketing},
439 283 year = {2018},
440 284 volume = {35},
@@ -445,7 +289,7 @@
445 289
446 290 @article{ert2016trust,
447 291 author = {Ert, Eyal and Fleischer, Aliza and Magen, Nathan},
448 − title = {Trust and reputation in the sharing economy: The role of personal photos in {Airbnb}},
292 + title = {Trust and Reputation in the Sharing Economy: The Role of Personal Photos in {Airbnb}},
449 293 journal = {Tourism Management},
450 294 year = {2016},
451 295 volume = {55},
@@ -453,37 +297,7 @@
453 297 doi = {10.1016/j.tourman.2016.01.013}
454 298 }
455 299
456 −@article{einav2016peer,
457 − author = {Einav, Liran and Farronato, Chiara and Levin, Jonathan},
458 − title = {Peer-to-Peer Markets},
459 − journal = {Annual Review of Economics},
460 − year = {2016},
461 − volume = {8},
462 − pages = {615--635},
463 − doi = {10.1146/annurev-economics-080315-015334}
464 −}
465 −
466 −@article{kelejian1998generalized,
467 − author = {Kelejian, Harry H. and Prucha, Ingmar R.},
468 − title = {A Generalized Spatial Two-Stage Least Squares Procedure for Estimating a Spatial Autoregressive Model with Autoregressive Disturbances},
469 − journal = {Journal of Real Estate Finance and Economics},
470 − year = {1998},
471 − volume = {17},
472 − number = {1},
473 − pages = {99--121},
474 − doi = {10.1023/A:1007707430416}
475 −}
476 −
477 −@article{kelejian1999generalized,
478 − author = {Kelejian, Harry H. and Prucha, Ingmar R.},
479 − title = {A Generalized Moments Estimator for the Autoregressive Parameter in a Spatial Model},
480 − journal = {International Economic Review},
481 − year = {1999},
482 − volume = {40},
483 − number = {2},
484 − pages = {509--533},
485 − doi = {10.1111/1468-2354.00027}
486 −}
300 +% ── Hedonic pricing theory and practice ─────────────────────────────────────
487 301
488 302 @article{lancaster1966new,
489 303 author = {Lancaster, Kelvin J.},
@@ -496,6 +310,30 @@
496 310 doi = {10.1086/259131}
497 311 }
498 312
313 +@article{rosen1974hedonic,
314 + author = {Rosen, Sherwin},
315 + title = {Hedonic Prices and Implicit Markets: Product Differentiation in Pure Competition},
316 + journal = {Journal of Political Economy},
317 + year = {1974},
318 + volume = {82},
319 + number = {1},
320 + pages = {34--55},
321 + doi = {10.1086/260169}
322 +}
323 +
324 +@incollection{palmquist2005property,
325 + author = {Palmquist, Raymond B.},
326 + title = {Property Value Models},
327 + booktitle = {Handbook of Environmental Economics},
328 + editor = {M\"{a}ler, Karl-G\"{o}ran and Vincent, Jeffrey R.},
329 + volume = {2},
330 + pages = {763--819},
331 + year = {2005},
332 + publisher = {Elsevier},
333 + address = {Amsterdam},
334 + doi = {10.1016/S1574-0099(05)02016-4}
335 +}
336 +
499 337 @article{sirmans2005composition,
500 338 author = {Sirmans, G. Stacy and Macpherson, David A. and Zietz, Emily N.},
501 339 title = {The Composition of Hedonic Pricing Models},
@@ -509,7 +347,7 @@
509 347
510 348 @article{kuminoff2010which,
511 349 author = {Kuminoff, Nicolai V. and Parmeter, Christopher F. and Pope, Jaren C.},
512 − title = {Which hedonic models can we trust to recover the marginal willingness to pay for environmental amenities?},
350 + title = {Which Hedonic Models Can We Trust to Recover the Marginal Willingness to Pay for Environmental Amenities?},
513 351 journal = {Journal of Environmental Economics and Management},
514 352 year = {2010},
515 353 volume = {60},
@@ -518,6 +356,28 @@
518 356 doi = {10.1016/j.jeem.2010.06.001}
519 357 }
520 358
359 +@article{kuminoff2014capitalization,
360 + author = {Kuminoff, Nicolai V. and Pope, Jaren C.},
361 + title = {Do ``Capitalization Effects'' for Public Goods Reveal the Public's Willingness to Pay?},
362 + journal = {International Economic Review},
363 + year = {2014},
364 + volume = {55},
365 + number = {4},
366 + pages = {1227--1250},
367 + doi = {10.1111/iere.12088}
368 +}
369 +
370 +@article{bishop2020best,
371 + author = {Bishop, Kelly C. and Kuminoff, Nicolai V. and Banzhaf, H. Spencer and Boyle, Kevin J. and von Gravenitz, Kathrine and Pope, Jaren C. and Smith, V. Kerry and Timmins, Christopher D.},
372 + title = {Best Practices for Using Hedonic Property Value Models to Measure Willingness to Pay for Environmental Quality},
373 + journal = {Review of Environmental Economics and Policy},
374 + year = {2020},
375 + volume = {14},
376 + number = {2},
377 + pages = {260--281},
378 + doi = {10.1093/reep/reaa001}
379 +}
380 +
521 381 @incollection{malpezzi2003hedonic,
522 382 author = {Malpezzi, Stephen},
523 383 title = {Hedonic Pricing Models: A Selective and Applied Review},
@@ -530,6 +390,147 @@
530 390 doi = {10.1002/9780470690680.ch5}
531 391 }
532 392
393 +@article{parmeter2007nonparametric,
394 + author = {Parmeter, Christopher F. and Henderson, Daniel J. and Kumbhakar, Subal C.},
395 + title = {Nonparametric Estimation of a Hedonic Price Function},
396 + journal = {Journal of Applied Econometrics},
397 + year = {2007},
398 + volume = {22},
399 + number = {3},
400 + pages = {695--699},
401 + doi = {10.1002/jae.929}
402 +}
403 +
404 +@article{oster2019unobservable,
405 + author = {Oster, Emily},
406 + title = {Unobservable Selection and Coefficient Stability: Theory and Evidence},
407 + journal = {Journal of Business \& Economic Statistics},
408 + year = {2019},
409 + volume = {37},
410 + number = {2},
411 + pages = {187--204},
412 + doi = {10.1080/07350015.2016.1227711}
413 +}
414 +
415 +% ── Spatial econometrics and spatial inference ──────────────────────────────
416 +
417 +@book{anselin1988spatial,
418 + author = {Anselin, Luc},
419 + title = {Spatial Econometrics: Methods and Models},
420 + publisher = {Kluwer Academic Publishers},
421 + address = {Dordrecht},
422 + year = {1988}
423 +}
424 +
425 +@book{lesage2009introduction,
426 + author = {LeSage, James P. and Pace, R. Kelley},
427 + title = {Introduction to Spatial Econometrics},
428 + publisher = {CRC Press},
429 + address = {Boca Raton, FL},
430 + year = {2009}
431 +}
432 +
433 +@article{kelejian1998generalized,
434 + author = {Kelejian, Harry H. and Prucha, Ingmar R.},
435 + title = {A Generalized Spatial Two-Stage Least Squares Procedure for Estimating a Spatial Autoregressive Model with Autoregressive Disturbances},
436 + journal = {Journal of Real Estate Finance and Economics},
437 + year = {1998},
438 + volume = {17},
439 + number = {1},
440 + pages = {99--121},
441 + doi = {10.1023/A:1007707430416}
442 +}
443 +
444 +@article{kelejian1999generalized,
445 + author = {Kelejian, Harry H. and Prucha, Ingmar R.},
446 + title = {A Generalized Moments Estimator for the Autoregressive Parameter in a Spatial Model},
447 + journal = {International Economic Review},
448 + year = {1999},
449 + volume = {40},
450 + number = {2},
451 + pages = {509--533},
452 + doi = {10.1111/1468-2354.00027}
453 +}
454 +
455 +@article{kelejian2007hac,
456 + author = {Kelejian, Harry H. and Prucha, Ingmar R.},
457 + title = {{HAC} Estimation in a Spatial Framework},
458 + journal = {Journal of Econometrics},
459 + year = {2007},
460 + volume = {140},
461 + number = {1},
462 + pages = {131--154},
463 + doi = {10.1016/j.jeconom.2006.09.005}
464 +}
465 +
466 +@article{conley1999gmm,
467 + author = {Conley, Timothy G.},
468 + title = {{GMM} Estimation with Cross Sectional Dependence},
469 + journal = {Journal of Econometrics},
470 + year = {1999},
471 + volume = {92},
472 + number = {1},
473 + pages = {1--45},
474 + doi = {10.1016/S0304-4076(98)00084-0}
475 +}
476 +
477 +@article{cameron2015practitioner,
478 + author = {Cameron, A. Colin and Miller, Douglas L.},
479 + title = {A Practitioner's Guide to Cluster-Robust Inference},
480 + journal = {Journal of Human Resources},
481 + year = {2015},
482 + volume = {50},
483 + number = {2},
484 + pages = {317--372},
485 + doi = {10.3368/jhr.50.2.317}
486 +}
487 +
488 +@article{can1992specification,
489 + author = {Can, Ayse},
490 + title = {Specification and Estimation of Hedonic Housing Price Models},
491 + journal = {Regional Science and Urban Economics},
492 + year = {1992},
493 + volume = {22},
494 + number = {3},
495 + pages = {453--474},
496 + doi = {10.1016/0166-0462(92)90039-4}
497 +}
498 +
499 +@article{dubin1988estimation,
500 + author = {Dubin, Robin A.},
501 + title = {Estimation of Regression Coefficients in the Presence of Spatially Autocorrelated Error Terms},
502 + journal = {Review of Economics and Statistics},
503 + year = {1988},
504 + volume = {70},
505 + number = {3},
506 + pages = {466--474},
507 + doi = {10.2307/1926785}
508 +}
509 +
510 +@article{fotheringham1991modifiable,
511 + author = {Fotheringham, A. Stewart and Wong, David W. S.},
512 + title = {The Modifiable Areal Unit Problem in Multivariate Statistical Analysis},
513 + journal = {Environment and Planning A: Economy and Space},
514 + year = {1991},
515 + volume = {23},
516 + number = {7},
517 + pages = {1025--1044},
518 + doi = {10.1068/a231025}
519 +}
520 +
521 +% ── Quantile regression ─────────────────────────────────────────────────────
522 +
523 +@article{koenker1978regression,
524 + author = {Koenker, Roger and Bassett, Gilbert},
525 + title = {Regression Quantiles},
526 + journal = {Econometrica},
527 + year = {1978},
528 + volume = {46},
529 + number = {1},
530 + pages = {33--50},
531 + doi = {10.2307/1913643}
532 +}
533 +
533 534 @article{koenker2001quantile,
534 535 author = {Koenker, Roger and Hallock, Kevin F.},
535 536 title = {Quantile Regression},
@@ -541,9 +542,20 @@
541 542 doi = {10.1257/jep.15.4.143}
542 543 }
543 544
545 +@article{zietz2008determinants,
546 + author = {Zietz, Joachim and Zietz, Emily Norman and Sirmans, G. Stacy},
547 + title = {Determinants of House Prices: A Quantile Regression Approach},
548 + journal = {Journal of Real Estate Finance and Economics},
549 + year = {2008},
550 + volume = {37},
551 + number = {4},
552 + pages = {317--333},
553 + doi = {10.1007/s11146-007-9053-7}
554 +}
555 +
544 556 @article{mcmillen2008changes,
545 557 author = {McMillen, Daniel P.},
546 − title = {Changes in the distribution of house prices over time: Structural characteristics, neighborhood, or coefficients?},
558 + title = {Changes in the Distribution of House Prices over Time: Structural Characteristics, Neighborhood, or Coefficients?},
547 559 journal = {Journal of Urban Economics},
548 560 year = {2008},
549 561 volume = {64},
@@ -552,6 +564,40 @@
552 564 doi = {10.1016/j.jue.2008.06.002}
553 565 }
554 566
567 +% ── Machine learning ────────────────────────────────────────────────────────
568 +
569 +@article{mullainathan2017machine,
570 + author = {Mullainathan, Sendhil and Spiess, Jann},
571 + title = {Machine Learning: An Applied Econometric Approach},
572 + journal = {Journal of Economic Perspectives},
573 + year = {2017},
574 + volume = {31},
575 + number = {2},
576 + pages = {87--106},
577 + doi = {10.1257/jep.31.2.87}
578 +}
579 +
580 +@article{athey2019machine,
581 + author = {Athey, Susan and Imbens, Guido W.},
582 + title = {Machine Learning Methods That Economists Should Know About},
583 + journal = {Annual Review of Economics},
584 + year = {2019},
585 + volume = {11},
586 + pages = {685--725},
587 + doi = {10.1146/annurev-economics-080217-053433}
588 +}
589 +
590 +@article{tibshirani1996regression,
591 + author = {Tibshirani, Robert},
592 + title = {Regression Shrinkage and Selection via the {Lasso}},
593 + journal = {Journal of the Royal Statistical Society: Series B (Methodological)},
594 + year = {1996},
595 + volume = {58},
596 + number = {1},
597 + pages = {267--288},
598 + doi = {10.1111/j.2517-6161.1996.tb02080.x}
599 +}
600 +
555 601 @article{zou2005regularization,
556 602 author = {Zou, Hui and Hastie, Trevor},
557 603 title = {Regularization and Variable Selection via the Elastic Net},
@@ -563,45 +609,34 @@
563 609 doi = {10.1111/j.1467-9868.2005.00503.x}
564 610 }
565 611
566 −@article{guttentag2015airbnb,
567 − author = {Guttentag, Daniel},
568 − title = {Airbnb: disruptive innovation and the rise of an informal tourism accommodation sector},
569 − journal = {Current Issues in Tourism},
570 − year = {2015},
571 − volume = {18},
572 − number = {12},
573 − pages = {1192--1217},
574 − doi = {10.1080/13683500.2013.827159}
575 −}
576 −
577 −@article{can1992specification,
578 − author = {Can, Ayse},
579 − title = {Specification and estimation of hedonic housing price models},
580 − journal = {Regional Science and Urban Economics},
581 − year = {1992},
582 − volume = {22},
583 − number = {3},
584 − pages = {453--474},
585 − doi = {10.1016/0166-0462(92)90039-4}
612 +@article{breiman2001random,
613 + author = {Breiman, Leo},
614 + title = {Random Forests},
615 + journal = {Machine Learning},
616 + year = {2001},
617 + volume = {45},
618 + number = {1},
619 + pages = {5--32},
620 + doi = {10.1023/A:1010933404324}
586 621 }
587 622
588 −@article{dubin1988estimation,
589 − author = {Dubin, Robin A.},
590 − title = {Estimation of Regression Coefficients in the Presence of Spatially Autocorrelated Error Terms},
591 − journal = {Review of Economics and Statistics},
592 − year = {1988},
593 − volume = {70},
594 − number = {3},
595 − pages = {466--474},
596 − doi = {10.2307/1926785}
623 +@article{friedman2001greedy,
624 + author = {Friedman, Jerome H.},
625 + title = {Greedy Function Approximation: A Gradient Boosting Machine},
626 + journal = {Annals of Statistics},
627 + year = {2001},
628 + volume = {29},
629 + number = {5},
630 + pages = {1189--1232},
631 + doi = {10.1214/aos/1013203451}
597 632 }
598 633
599 −@book{sundararajan2016sharing,
600 − author = {Sundararajan, Arun},
601 − title = {The Sharing Economy: The End of Employment and the Rise of Crowd-Based Capitalism},
602 − publisher = {MIT Press},
603 − address = {Cambridge, MA},
604 − year = {2016}
634 +@inproceedings{lundberg2017unified,
635 + author = {Lundberg, Scott M. and Lee, Su-In},
636 + title = {A Unified Approach to Interpreting Model Predictions},
637 + booktitle = {Advances in Neural Information Processing Systems 30},
638 + year = {2017},
639 + pages = {4765--4774}
605 640 }
606 641
607 642 @article{pedregosa2011scikit,
@@ -612,3 +647,95 @@
612 647 volume = {12},
613 648 pages = {2825--2830}
614 649 }
650 +
651 +% ── Housing supply and urban economics ──────────────────────────────────────
652 +
653 +@article{glaeser2005urban,
654 + author = {Glaeser, Edward L. and Gyourko, Joseph and Saks, Raven E.},
655 + title = {Urban Growth and Housing Supply},
656 + journal = {Journal of Economic Geography},
657 + year = {2006},
658 + volume = {6},
659 + number = {1},
660 + pages = {71--89},
661 + doi = {10.1093/jeg/lbi003}
662 +}
663 +
664 +@article{saiz2010geographic,
665 + author = {Saiz, Albert},
666 + title = {The Geographic Determinants of Housing Supply},
667 + journal = {Quarterly Journal of Economics},
668 + year = {2010},
669 + volume = {125},
670 + number = {3},
671 + pages = {1253--1296},
672 + doi = {10.1162/qjec.2010.125.3.1253}
673 +}
674 +
675 +@article{gyourko2005superstar,
676 + author = {Gyourko, Joseph and Mayer, Christopher and Sinai, Todd},
677 + title = {Superstar Cities},
678 + journal = {American Economic Journal: Economic Policy},
679 + year = {2013},
680 + volume = {5},
681 + number = {4},
682 + pages = {167--199},
683 + doi = {10.1257/pol.5.4.167}
684 +}
685 +
686 +% ── Tourism gentrification and regulation ───────────────────────────────────
687 +
688 +@article{gotham2005tourism,
689 + author = {Gotham, Kevin Fox},
690 + title = {Tourism Gentrification: The Case of {New Orleans}' {Vieux Carr\'e} ({French Quarter})},
691 + journal = {Urban Studies},
692 + year = {2005},
693 + volume = {42},
694 + number = {7},
695 + pages = {1099--1121},
696 + doi = {10.1080/00420980500120881}
697 +}
698 +
699 +@article{cocola2016holiday,
700 + author = {Cocola-Gant, Agustin},
701 + title = {Holiday Rentals: The New Gentrification Battlefront},
702 + journal = {Sociological Research Online},
703 + year = {2016},
704 + volume = {21},
705 + number = {3},
706 + pages = {112--120},
707 + doi = {10.5153/sro.4071}
708 +}
709 +
710 +@article{cocola2021airbnb,
711 + author = {Cocola-Gant, Agustin and Gago, Ana},
712 + title = {{Airbnb}, Buy-to-Let Investment and Tourism-Driven Displacement: A Case Study in {Lisbon}},
713 + journal = {Environment and Planning A: Economy and Space},
714 + year = {2021},
715 + volume = {53},
716 + number = {7},
717 + pages = {1671--1688},
718 + doi = {10.1177/0308518X19869012}
719 +}
720 +
721 +@article{gurran2017when,
722 + author = {Gurran, Nicole and Phibbs, Peter},
723 + title = {When Tourists Move In: How Should Urban Planners Respond to {Airbnb}?},
724 + journal = {Journal of the American Planning Association},
725 + year = {2017},
726 + volume = {83},
727 + number = {1},
728 + pages = {80--92},
729 + doi = {10.1080/01944363.2016.1249011}
730 +}
731 +
732 +@article{nieuwland2020regulating,
733 + author = {Nieuwland, Shirley and van Melik, Rianne},
734 + title = {Regulating {Airbnb}: How Cities Deal with Perceived Negative Externalities of Short-Term Rentals},
735 + journal = {Current Issues in Tourism},
736 + year = {2020},
737 + volume = {23},
738 + number = {7},
739 + pages = {811--825},
740 + doi = {10.1080/13683500.2018.1504899}
741 +}
modified paper/sections/01_introduction.tex +8 −8
@@ -4,18 +4,18 @@
4 4 % =============================================================================
5 5 \section{Introduction}\label{sec:introduction}
6 6
7 −The rapid expansion of short-term rental platforms has fundamentally transformed urban housing markets around the world. Since its founding in 2008, Airbnb has grown from a modest home-sharing service into a global hospitality platform with millions of listings across virtually every major city, an archetypal case of disruptive innovation in tourism accommodation \citep{guttentag2015airbnb} and of the broader rise of peer-to-peer markets \citep{einav2016peer, sundararajan2016sharing}. By enabling property owners to rent their dwellings---or portions thereof---to short-term visitors at nightly rates that often exceed what a long-term tenant would pay on a monthly basis, the platform has created powerful economic incentives to divert housing units from the residential rental market. The same flexible peer supply that generates large welfare gains in the accommodation market \citep{zervas2017rise, farronato2022welfare} is, from the housing market's perspective, a competing use for the residential stock.
7 +Short-term rental (STR) platforms have changed the way urban housing can be used. Since 2008 Airbnb has grown from a small home-sharing service into a global accommodation platform, an archetypal case of disruptive innovation in tourism \citep{guttentag2015airbnb} and of the broader rise of peer-to-peer markets \citep{einav2016peer, sundararajan2016sharing}. By allowing owners to let a dwelling, or part of it, to visitors at nightly rates that can exceed what a long-term tenant pays per month, the platform creates an incentive to divert housing units from the residential rental market. The flexible peer supply that generates welfare gains in the accommodation market \citep{zervas2017rise, farronato2022welfare} is, from the housing market's perspective, a competing use for the residential stock.
8 8
9 −This diversion mechanism sits at the heart of a growing policy concern: that the proliferation of Airbnb listings may contribute to rising residential rents and reduced housing affordability, particularly in cities with significant tourist appeal. A now-substantial empirical literature supports the concern: studies exploiting cross-market variation \citep{barron2021effect, horn2017airbnb}, regulatory discontinuities \citep{koster2021short, valentin2021regulating, duso2024airbnb}, and within-city diffusion \citep{garcia2020airbnb, franco2021impact} consistently find that STR activity raises rents and house prices, with effects that are modest per listing but spatially concentrated. The economic logic is straightforward. When landlords can earn higher returns by listing a unit on Airbnb than by renting it to a long-term tenant, the effective supply of long-term rental housing contracts. On the demand side, Airbnb may attract additional visitors to a neighbourhood, increasing foot traffic, consumption amenities, and---through general equilibrium effects---the desirability of the area for both tourists and residents. The net effect on rents is theoretically ambiguous: supply withdrawal pushes rents upward, while the sign and magnitude of demand-side amenity effects depend on the local context, the composition of Airbnb listings, and the degree of market segmentation between short-term and long-term rentals.
9 +This diversion mechanism underlies a policy concern that STR activity raises residential rents and reduces affordability, particularly in cities with strong tourist appeal. The empirical literature largely supports the concern. Studies exploiting cross-market variation \citep{barron2021effect, horn2017airbnb}, regulatory discontinuities \citep{koster2021short, valentin2021regulating, duso2024airbnb} and within-city diffusion \citep{garcia2020airbnb, franco2021impact} find that STR activity raises rents and house prices, with effects that are modest per listing but spatially concentrated. The economic logic is simple: when a unit earns more on Airbnb than under a lease, the effective supply of long-term rental housing contracts. On the demand side, STR guests may raise foot traffic and consumption amenities in a neighbourhood \citep{hidalgo2024effect, almagro2025location}, so the net effect on rents depends on the local context, the composition of listings and the degree of segmentation between the short-term and long-term segments.
10 10
11 −The province of Quebec, and the city of Montreal in particular, provides a compelling setting in which to study these dynamics. Montreal is Canada's second-largest city and one of North America's foremost tourist destinations, attracting over 11 million visitors annually prior to the COVID-19 pandemic. Its dense, walkable neighbourhoods, vibrant cultural scene, and historic architecture make it especially attractive for short-term rental guests, and national analyses identify it as one of Canada's largest and most commercialised STR markets \citep{combs2020short}. At the same time, Quebec has experienced significant rental market pressures in recent years. Vacancy rates in the Montreal census metropolitan area have fallen to historically low levels, and median rents have risen substantially. Policymakers at the provincial and municipal levels have responded with a mix of regulatory interventions, including CITQ registration requirements for short-term rental operators and zoning restrictions in Montreal \citep{nieuwland2020regulating}. Yet the econometric evidence on the housing-market effects of Airbnb in the Quebec context remains remarkably thin: existing Canadian work is either national and descriptive \citep{combs2020short} or focused on Toronto's political economy of displacement \citep{grisdale2021displacement}. No study, to our knowledge, has estimated the Airbnb--rent relationship at the individual listing level for Quebec.
11 +The province of Quebec, and Montreal in particular, is a natural setting for studying these questions. Montreal is Canada's second-largest city and one of its main tourist destinations; national analyses identify it as one of the country's largest and most commercialised STR markets \citep{combs2020short}. The province has also experienced a tight rental market in recent years, and policymakers have responded with a provincial registration regime for STR operators and with municipal zoning and seasonal restrictions in Montreal \citep{nieuwland2020regulating}. Yet econometric evidence on the housing-market correlates of Airbnb in Quebec is scarce: the Canadian literature is either national and descriptive \citep{combs2020short} or focused on the political economy of displacement in Toronto \citep{grisdale2021displacement}. To our knowledge, no study has estimated the Airbnb--rent relationship at the level of individual listings for Quebec.
12 12
13 −Estimating the effect of short-term rental platforms on residential rents poses significant empirical challenges. The most fundamental is endogeneity: Airbnb listings are not randomly assigned to locations. Hosts choose to list in neighbourhoods where rents---and tourist demand---are already high, creating a positive correlation between Airbnb density and rent levels that may reflect reverse causality or omitted neighbourhood characteristics rather than a genuine causal effect. In the ideal research design, one would exploit plausible exogenous variation in Airbnb supply---for example, a regulatory shock that differentially affected neighbourhoods---combined with panel data to control for time-invariant unobservables. Our data, however, are cross-sectional: they comprise a single snapshot of Airbnb and rental listings in Quebec, scraped in 2026. We therefore adopt a transparent hedonic pricing framework that quantifies the conditional association between Airbnb presence and rents, controlling for a rich set of dwelling characteristics and location fixed effects, while being explicit about the limitations of causal interpretation.
13 +Estimating the effect of STR platforms on rents is difficult, and the central difficulty is endogeneity. Airbnb listings are not randomly located: hosts list where tourist demand, amenities and rents are already high, so a positive cross-sectional correlation between Airbnb density and rents may reflect reverse causality or omitted neighbourhood characteristics rather than a causal effect. The quasi-experimental literature addresses this with regulatory shocks and panel data \citep{koster2021short, valentin2021regulating, duso2024airbnb} or with instruments for Airbnb penetration \citep{barron2021effect, garcia2020airbnb}. Our data are a single 2026 cross-section of Airbnb and rental listings, and we do not claim to identify a causal effect. Instead, we ask what a carefully specified cross-sectional hedonic design can and cannot establish, and we let the data speak on the identification problem itself: because every rental listing carries a postal code, we can compare the Airbnb--rent association across progressively finer location fixed effects, from the city to the forward sortation area (FSA, a postal-code neighbourhood), and we can compute standard errors that respect the spatial dependence built into a buffer-based exposure measure.
14 14
15 −Our empirical strategy proceeds in several stages. First, we estimate a hedonic rent model in which the logarithm of monthly rent is regressed on the count of Airbnb listings within a spatial buffer (our preferred radius is 500 metres), controlling for the number of bedrooms, bathrooms, building type, and city fixed effects. This specification yields a semi-elasticity interpretation: the coefficient on Airbnb count measures the percentage change in rent associated with one additional nearby Airbnb listing, holding observable dwelling characteristics constant. Second, we estimate a complementary hedonic model of Airbnb nightly prices, in which city-level mean rents serve as a control, allowing us to examine the bidirectional pricing relationship between the two market segments. Third, we aggregate the data to the city level to examine cross-city variation in Airbnb penetration and mean rents. Fourth, we incorporate spatial lags and vary the buffer radius (250\,m, 500\,m, 1\,km, 2\,km) to assess the spatial decay of the association. Fifth, quantile regressions at the 10th, 25th, 50th, 75th, and 90th percentiles reveal how the Airbnb--rent association varies across the conditional rent distribution. Sixth, we benchmark our parametric estimates against machine-learning methods---LASSO, elastic net, random forest, and gradient boosting---to assess predictive importance and model robustness.
15 +Our empirical strategy proceeds in stages. We first estimate a hedonic rent equation in which the logarithm of the monthly asking rent is regressed on the number of Airbnb listings within a buffer of the listing (our reference radius is 500\,m), controlling for bedrooms, bathrooms, building type and city fixed effects; the coefficient is a semi-elasticity, the approximate percentage change in rent associated with one additional nearby listing. We then replace city fixed effects with FSA fixed effects, and compare heteroskedasticity-robust, cluster-robust and Conley spatial HAC standard errors. We estimate spatial autoregressive and spatial error models by generalised moments and report the direct, indirect and total impacts that the spatial lag implies. We vary the buffer radius, decompose exposure into rings and into extensive and intensive margins, estimate quantile regressions across the conditional rent distribution, and benchmark the linear hedonic model against regularised and tree-based learners under both random and spatially blocked cross-validation. A complementary hedonic model of Airbnb nightly prices examines whether STR pricing responds to city-level rents.
16 16
17 −To preview the central result: each additional Airbnb listing within 500 metres of a rental unit is associated with approximately 0.4\% higher monthly rent, conditional on dwelling characteristics, building type, and city fixed effects. The association decays monotonically with distance, is present throughout the conditional rent distribution but strongest at its upper tail, and survives spatial-econometric treatment, city-clustered inference, functional-form changes, sample trims, and leave-one-city-out exclusions. At the median rent of roughly \$1{,}950 per month, the point estimate corresponds to \$6--10 per additional nearby listing---strikingly close, in order of magnitude, to the 7--13 euros per listing that \citet{duso2024airbnb} recover from Berlin's regulatory shocks, and consistent with the per-listing effects implied by the Los Angeles ordinance evidence of \citet{koster2021short}. That a transparent cross-sectional design recovers magnitudes in line with the quasi-experimental literature is, we argue, informative in both directions: it lends external credibility to our estimates and out-of-sample support to the causal designs.
17 +The results have two layers. With city fixed effects, each additional Airbnb listing within 500\,m is associated with monthly rents about 0.4\% higher; the per-listing coefficient falls monotonically with the radius, the association is largest at the upper quantiles, and it is essentially unchanged in spatial lag and spatial error models, with a total impact of 0.40\% per listing. These are the results a reader of the existing cross-sectional literature would expect. The second layer qualifies them. Standard errors that account for spatial dependence are about three times larger than the heteroskedasticity-robust errors usually reported, so that the $t$-statistic of the city-fixed-effects estimate falls from 17 to about 5. More importantly, once FSA fixed effects absorb neighbourhood-level unobservables, the coefficient falls to 0.08\% per listing and is no longer distinguishable from zero under spatial inference; the logarithmic and extensive-margin exposure measures behave in the same way. About a quarter of the variance in the 500\,m count is within FSAs, so the attenuation does not reflect a lack of identifying variation. The Airbnb--rent association in these data is thus predominantly a between-neighbourhood phenomenon. Spatially blocked cross-validation delivers a parallel message for the machine-learning benchmark: the sizeable advantage of random forests and gradient boosting over the linear model under random splits disappears when whole neighbourhoods are held out, which indicates that the flexible learners were interpolating neighbourhood rent levels rather than uncovering structure in the exposure--rent relationship.
18 18
19 −This paper makes three contributions. First, it provides the first granular, listing-level econometric analysis of the Airbnb--rent nexus in Quebec---and, to our knowledge, in any Canadian market---drawing on microdata with precise geographic coordinates that allow exact distance-based matching between Airbnb and rental listings. Prior Canadian evidence is descriptive \citep{combs2020short} or qualitative \citep{grisdale2021displacement}; we complement it with formal estimation. Second, it applies a multi-method approach---hedonic regressions \citep{rosen1974hedonic}, spatial econometrics estimated by generalised moments \citep{kelejian1998generalized, kelejian1999generalized}, quantile regressions \citep{koenker1978regression}, and machine-learning benchmarks \citep{mullainathan2017machine}---to a single dataset, enabling direct comparison of results across methodological frameworks and, in particular, delivering the first distributional (quantile-level) characterisation of the STR--rent association for a Canadian market. Third, it contributes to the ongoing policy debate about short-term rental regulation in Canadian cities by providing empirically grounded estimates of the magnitude and spatial reach of the Airbnb--rent association---quantities that bear directly on the geographic targeting of Quebec's registration-based regime---even as it highlights the limitations inherent in cross-sectional identification.
19 +The paper makes three contributions. First, it provides the first listing-level econometric analysis of the Airbnb--rent relationship for Quebec, and to our knowledge for any Canadian market, using coordinates precise enough for distance-based matching between the two sets of listings; the Canadian evidence to date is descriptive \citep{combs2020short} or qualitative \citep{grisdale2021displacement}. Second, it documents, within a single data set, how much of a typical cross-sectional STR--rent correlation survives neighbourhood fixed effects and spatially robust inference. The answer, about one fifth of the point estimate and little of its statistical significance, is informative for the reading of other cross-sectional studies and is consistent with the location-sorting mechanism emphasised by \citet{almagro2025location}. Third, it brings this evidence to bear on the design of Quebec's registration-based regime and Montreal's zoning rules, while being explicit that cross-sectional listing data cannot establish the causal effect that would justify a given level of restriction.
20 20
21 −The remainder of the paper is organised as follows. Section~\ref{sec:literature} reviews the related literature on short-term rentals and housing markets. Section~\ref{sec:data} describes the data sources, cleaning procedures, and spatial merge strategy. Section~\ref{sec:methodology} presents the econometric framework. Section~\ref{sec:results} reports the main empirical results. Section~\ref{sec:robustness} provides robustness checks and sensitivity analyses. Section~\ref{sec:discussion} discusses policy implications and limitations. Section~\ref{sec:conclusion} concludes.
21 +The remainder of the paper is organised as follows. Section~\ref{sec:literature} reviews the literature on STR platforms and housing markets and the methods we use. Section~\ref{sec:data} describes the data, their limitations and the spatial merge. Section~\ref{sec:methodology} sets out the econometric framework, including the fixed-effects, spatial and inference choices. Section~\ref{sec:results} reports the results, Section~\ref{sec:robustness} the robustness analyses, Section~\ref{sec:discussion} the interpretation, policy implications and limitations, and Section~\ref{sec:conclusion} concludes.
modified paper/sections/02_literature.tex +16 −16
@@ -4,50 +4,50 @@
4 4 % =============================================================================
5 5 \section{Literature Review}\label{sec:literature}
6 6
7 −This section reviews the empirical and methodological literatures on which the paper builds. We organise the review thematically rather than chronologically: we first survey the evidence on short-term rental (STR) platforms and housing costs, moving from the early correlational studies to the more recent quasi-experimental designs (Section~\ref{sec:lit_str}); we then turn to the Canadian and Quebec evidence (Section~\ref{sec:lit_canada}), the broader economics of peer-to-peer accommodation markets (Section~\ref{sec:lit_p2p}), and the pricing of STR listings themselves (Section~\ref{sec:lit_strpricing}). The remaining subsections cover the methodological foundations of the paper: hedonic pricing theory and practice (Section~\ref{sec:lit_hedonic}), spatial econometrics (Section~\ref{sec:lit_spatial}), distributional analysis via quantile regression (Section~\ref{sec:lit_quantile}), and machine learning in housing economics (Section~\ref{sec:lit_ml}). Section~\ref{sec:lit_regulation} reviews the tourism-gentrification and regulation literature that frames the policy discussion, and Section~\ref{sec:lit_gap} states the gap this paper fills.
7 +This section reviews the empirical and methodological literatures on which the paper builds. We first survey the evidence on STR platforms and housing costs, from early correlational studies to quasi-experimental designs (Section~\ref{sec:lit_str}), then the Canadian and Quebec evidence (Section~\ref{sec:lit_canada}), the economics of peer-to-peer accommodation (Section~\ref{sec:lit_p2p}) and the pricing of STR listings (Section~\ref{sec:lit_strpricing}). The remaining subsections cover the methodological foundations: hedonic pricing and its identification problems (Section~\ref{sec:lit_hedonic}), spatial econometrics and spatial inference (Section~\ref{sec:lit_spatial}), quantile regression (Section~\ref{sec:lit_quantile}) and machine learning in housing economics (Section~\ref{sec:lit_ml}). Section~\ref{sec:lit_regulation} reviews the tourism-gentrification and regulation literature, and Section~\ref{sec:lit_gap} states the gap the paper addresses.
8 8
9 9 \subsection{Short-Term Rentals and Housing Costs}\label{sec:lit_str}
10 10
11 −Housing costs respond to shifts in effective supply, and markets with inelastic supply capitalise demand shocks into prices and rents \citep{glaeser2005urban, saiz2010geographic, gyourko2005superstar}. STR platforms create precisely such a shift at the margin: by raising the return to allocating a dwelling to visitors rather than tenants, they can withdraw units from the long-term rental stock. The empirical literature testing this mechanism has developed in two waves.
11 +Housing costs respond to shifts in effective supply, and markets with inelastic supply capitalise demand shocks into prices and rents \citep{glaeser2005urban, saiz2010geographic, gyourko2005superstar}. STR platforms create such a shift at the margin: by raising the return to allocating a dwelling to visitors rather than tenants, they can withdraw units from the long-term stock. The empirical literature testing this mechanism has developed in two waves.
12 12
13 −\paragraph{Correlational and panel evidence.} The seminal large-scale study is \citet{barron2021effect}, who exploit zipcode-level variation in Airbnb penetration across the United States, instrumenting Airbnb growth with the interaction of Google Trends search interest and a measure of touristiness. They estimate that a 1\% increase in Airbnb listings raises rents by 0.018\% and house prices by 0.026\%, and attribute the effect to the reallocation of units from long-term to short-term supply. \citet{horn2017airbnb} use listing-level asking rents in Boston and find that a one-standard-deviation increase in Airbnb density is associated with rents approximately 0.4\% higher, an effect concentrated where Airbnb listings are entire homes. \citet{sheppard2016airbnb} document property-value capitalisation in New York City, and \citet{wachsmuth2018airbnb} show that the ``rent gap'' opened by STR revenue potential is systematically related to gentrification pressure. In a similar spirit, \citet{ayouba2020airbnb} apply spatial panel methods to eight French cities and find significant rent effects of Airbnb density in Lyon, Montpellier, and Paris but not elsewhere---early evidence that the association is heterogeneous across markets. Using proprietary platform data and a structural model of landlord choice, \citet{li2022market} show that Airbnb entry shifts landlords at the margin between long-term and short-term supply, with the incidence falling on long-term tenants in high-demand markets.
13 +\paragraph{Correlational and panel evidence.} The first large-scale study is \citet{barron2021effect}, who exploit zipcode-level variation in Airbnb penetration across the United States and instrument Airbnb growth with the interaction of Google search interest for Airbnb and a measure of touristiness. They estimate that a 1\% increase in Airbnb listings raises rents by 0.018\% and house prices by 0.026\%, and attribute the effect to the reallocation of units from long-term to short-term supply. \citet{horn2017airbnb} use listing-level asking rents in Boston and find that a one-standard-deviation increase in Airbnb listings is associated with asking rents 0.4\% higher, with the effect concentrated where listings are entire homes. \citet{sheppard2016airbnb} document property-value capitalisation in New York City; \citet{lee2016airbnb} documents the removal of units from the Los Angeles rental stock; and \citet{wachsmuth2018airbnb} show that the ``rent gap'' opened by STR revenue potential is systematically related to gentrification pressure. \citet{ayouba2020airbnb} apply spatial panel methods to eight French cities and find significant rent effects of Airbnb density in Lyon, Montpellier and Paris but not elsewhere, early evidence that the association is heterogeneous across markets. Using platform data and a structural model of landlord choice, \citet{li2022market} show that Airbnb entry shifts landlords at the margin between long-term and short-term supply, with the incidence falling on long-term tenants in high-demand markets. \citet{calderwang2021distributional} estimates a structural model of the New York City rental market and finds that the rent burden created by Airbnb falls disproportionately on higher-income renters.
14 14
15 −\paragraph{Quasi-experimental evidence.} A second wave exploits policy discontinuities and regulatory shocks. \citet{garcia2020airbnb} use the staggered, spatially uneven diffusion of Airbnb across Barcelona neighbourhoods and estimate that Airbnb activity raised rents by 1.9\% and transaction prices by 4.6--7\% in high-activity areas. \citet{koster2021short} exploit Home-Sharing Ordinances adopted by some Los Angeles-area cities but not others in a spatial regression-discontinuity design: ordinances reduced Airbnb listings by roughly 50\% and lowered house prices and rents by around 2\% in treated areas, implying a substantial positive effect of STR activity in the absence of regulation. \citet{valentin2021regulating} finds that New Orleans' licensing reform capitalised into property values where STR use was legalised. \citet{duso2024airbnb} use two Berlin regulatory shocks and estimate that each nearby Airbnb listing raises asking rents by roughly 7--13 euros per month, while \citet{franco2021impact} document positive effects of Airbnb density on both prices and rents across Portuguese municipalities, strongest in tourist-intensive locations. For London, \citet{shabrina2022airbnb} link neighbourhood-level Airbnb ``misuse'' (de facto commercial operation) to higher local rents.
15 +\paragraph{Quasi-experimental evidence.} A second wave exploits policy discontinuities and regulatory shocks. \citet{garcia2020airbnb} use the staggered, spatially uneven diffusion of Airbnb across Barcelona neighbourhoods together with an instrumental-variables strategy and estimate that Airbnb activity raised rents by 1.9\%, transaction prices by 4.6\% and posted prices by 3.7\% in the average neighbourhood, and rents by about 7\% in the neighbourhoods with the most Airbnb activity. \citet{koster2021short} exploit Home Sharing Ordinances adopted by some Los Angeles-area cities but not others in a spatial regression-discontinuity design: the ordinances reduced Airbnb listings by about 50\% and lowered house prices and rents by about 3\% in treated areas, with much larger effects close to tourist attractions. \citet{valentin2021regulating} finds that New Orleans' licensing reform capitalised into property values where STR use was legalised. \citet{duso2024airbnb} use two Berlin regulatory shocks and estimate that each additional commercial Airbnb listing displaces 0.23--0.37 long-term rental units and raises rents per square metre by 1.3--2.4\%. \citet{franco2021impact} document positive effects of Airbnb density on both prices and rents across Portuguese municipalities, strongest in tourist-intensive locations, and \citet{shabrina2022airbnb} link neighbourhood-level commercial Airbnb use to higher rents in London.
16 16
17 −Taken together, this literature finds positive, modest-per-listing, spatially concentrated associations between STR activity and residential housing costs, with quasi-experimental designs generally confirming---and sometimes exceeding---the magnitudes suggested by earlier correlational work. Our estimates are best read against this benchmark: a cross-sectional design cannot adjudicate causality, but it can establish whether the conditional correlations in a previously unstudied market are consistent with the causal magnitudes established elsewhere.
17 +Taken together, this literature finds positive, spatially concentrated associations between STR activity and housing costs, with quasi-experimental designs generally confirming, and sometimes exceeding, the magnitudes suggested by correlational work. Two features of the quasi-experimental studies matter for the present paper. First, they rely on within-neighbourhood variation over time, which removes time-invariant neighbourhood amenities from the comparison. Second, their per-listing effects are expressed for well-defined treatments, such as commercial or high-availability listings. A cross-sectional design cannot replicate the first feature, but it can test how much of its estimate depends on between-neighbourhood variation, which is what we do.
18 18
19 19 \subsection{Canadian and Quebec Evidence}\label{sec:lit_canada}
20 20
21 −Evidence for Canada is comparatively scarce and largely descriptive. \citet{combs2020short} provide the first national analysis of Canadian STR markets, documenting rapid but spatially uneven growth, strong revenue concentration among commercial multi-listing operators, and an estimate of roughly 31{,}000 housing units removed from Canadian long-term rental markets by frequently rented entire-home listings in 2018---with Montreal among the three dominant markets. \citet{grisdale2021displacement} traces the political economy of STR-driven displacement in Toronto, linking commercial Airbnb operation to rental-supply loss in central neighbourhoods. Beyond descriptive market measurement and critical urban geography, however, there is little listing-level econometric evidence for Canadian markets, and none, to our knowledge, for Quebec---a striking gap given that the province combines one of Canada's largest STR markets, distinctive provincial registration requirements, and acute rental-market tightness. This paper addresses that gap.
21 +Evidence for Canada is comparatively scarce and largely descriptive. \citet{combs2020short} provide the first national analysis of Canadian STR markets, documenting rapid but spatially uneven growth, strong revenue concentration among multi-listing operators, and between 17{,}000 and 43{,}000 entire homes rented frequently enough in 2018 to be unlikely to house a permanent resident, with Montreal among the three dominant markets. \citet{grisdale2021displacement} traces the political economy of STR-driven displacement in Toronto, linking commercial Airbnb operation to rental-supply loss in central neighbourhoods. Beyond market measurement and critical urban geography there is little listing-level econometric evidence for Canadian markets, and none, to our knowledge, for Quebec, although the province combines a large STR market, a distinctive provincial registration regime and a tight rental market.
22 22
23 23 \subsection{The Economics of Peer-to-Peer Accommodation}\label{sec:lit_p2p}
24 24
25 −A complementary literature studies STR platforms as peer-to-peer markets. \citet{einav2016peer} analyse how platforms reduce transaction costs and enable trade in underutilised assets, and \citet{sundararajan2016sharing} surveys the rise of ``crowd-based capitalism.'' \citet{guttentag2015airbnb} frames Airbnb as a disruptive innovation in tourism accommodation. On market impacts, \citet{zervas2017rise} estimate that Airbnb entry reduced hotel revenues in the most affected Texas segments by 8--10\%, and \citet{farronato2022welfare} quantify the welfare effects of peer entry in the accommodation industry, showing that flexible peer supply expands capacity precisely when demand peaks, generating consumer surplus while eroding hotel profits. This literature matters for our purposes because it establishes the economic incentive at the heart of the housing channel: peer hosts respond elastically to short-term rental returns, and the same responsiveness that creates accommodation-market surplus is what reallocates dwellings away from long-term tenants when STR returns exceed residential rents.
25 +A complementary literature studies STR platforms as peer-to-peer markets. \citet{einav2016peer} analyse how platforms reduce transaction costs and enable trade in underutilised assets, and \citet{sundararajan2016sharing} surveys the rise of ``crowd-based capitalism.'' \citet{guttentag2015airbnb} frames Airbnb as a disruptive innovation in tourism accommodation. On market impacts, \citet{zervas2017rise} estimate that Airbnb entry reduced hotel revenues in the most affected Texas segments by 8--10\%, and \citet{farronato2022welfare} show that flexible peer supply expands capacity when demand peaks, generating consumer surplus while eroding hotel profits. This literature establishes the incentive at the heart of the housing channel: hosts respond elastically to STR returns, and the same responsiveness that creates accommodation-market surplus reallocates dwellings away from long-term tenants when STR returns exceed residential rents. It also points to a second channel: STR guests change local consumption amenities, which \citet{hidalgo2024effect} document for Madrid and \citet{almagro2025location} embed in a model of location sorting for Amsterdam. Endogenous amenities are a reason why STR density and rents can be correlated even in the absence of supply withdrawal, and a reason to control for neighbourhood characteristics as finely as the data permit.
26 26
27 27 \subsection{Pricing of Short-Term Rental Listings}\label{sec:lit_strpricing}
28 28
29 −A distinct strand estimates hedonic models of Airbnb nightly prices, which informs our Model~2. \citet{wang2017price} study some 180{,}000 listings in 33 cities and find that entire-home status, capacity, and host attributes (notably superhost status) are dominant price determinants. \citet{gibbs2018pricing} estimate hedonic price equations for five Canadian Airbnb markets---the study closest to our Model~2 in geographic scope---and document significant premia for entire homes and location. \citet{ert2016trust} show that host reputation and trust signals are capitalised into Airbnb prices. Notably, these studies generally find positive superhost premia, whereas our within-city estimates yield a superhost \textit{discount}; we return to this disagreement in Sections~\ref{sec:results} and~\ref{sec:discussion} and interpret it as a composition effect specific to Quebec's mix of urban and resort listings.
29 +A distinct strand estimates hedonic models of Airbnb nightly prices, which informs our Model~2. \citet{wang2017price} study some 180{,}000 listings in 33 cities and find that entire-home status, capacity and host attributes, notably superhost status, are dominant price determinants. \citet{gibbs2018pricing} estimate hedonic price equations for five Canadian Airbnb markets, the study closest to our Model~2 in geographic scope, and document significant premia for entire homes and location. \citet{ert2016trust} show that host reputation and trust signals are capitalised into prices. These studies consistently report positive superhost premia and explanatory power well above what we obtain on the full sample of scraped prices; we show in Section~\ref{sec:results} that the discrepancy is a data-quality issue in the scraped price field rather than a Quebec-specific pricing pattern.
30 30
31 −\subsection{Hedonic Pricing: Theory and Practice}\label{sec:lit_hedonic}
31 +\subsection{Hedonic Pricing: Theory, Practice and Identification}\label{sec:lit_hedonic}
32 32
33 −The hedonic framework descends from \citet{lancaster1966new}, who recast consumer demand as demand for characteristics, and \citet{rosen1974hedonic}, who formalised the market equilibrium in which the prices of differentiated products reveal implicit characteristic prices. In housing applications, the hedonic price of a locational attribute---here, exposure to nearby STR activity---is identified from cross-sectional price variation conditional on structural characteristics \citep{palmquist2005property}. Surveys of five decades of empirical practice document both the workhorse status and the fragility of hedonic estimates: \citet{sirmans2005composition} catalogue the composition of hundreds of published models; \citet{malpezzi2003hedonic} reviews functional-form and specification choices; and \citet{kuminoff2010which} show in large-scale simulations that spatial fixed effects and flexible functional forms are the most effective safeguards against omitted-variable bias in cross-sectional hedonics---a prescription our specification follows (city fixed effects; count, density, and logarithmic exposure forms; extensive robustness analysis). \citet{parmeter2010applied} discuss the identification threats that remain.
33 +The hedonic framework descends from \citet{lancaster1966new}, who recast consumer demand as demand for characteristics, and \citet{rosen1974hedonic}, who formalised the market equilibrium in which the prices of differentiated goods reveal implicit characteristic prices. In housing applications the implicit price of a locational attribute, here exposure to nearby STR activity, is identified from cross-sectional price variation conditional on structural characteristics \citep{palmquist2005property}. Surveys of empirical practice document both the workhorse status and the fragility of hedonic estimates: \citet{sirmans2005composition} catalogue the composition of hundreds of published models, \citet{malpezzi2003hedonic} reviews specification choices, and \citet{parmeter2007nonparametric} illustrate the gains from flexible functional forms. The identification literature is more sobering. \citet{kuminoff2010which} show in large-scale simulations that spatial fixed effects are the most effective safeguard against omitted-variable bias in cross-sectional hedonics; \citet{kuminoff2014capitalization} show that capitalisation estimates recover marginal willingness to pay only under restrictive conditions; and \citet{bishop2020best} summarise current best practice, including the use of fine spatial fixed effects and quasi-experimental variation. \citet{oster2019unobservable} formalises the use of coefficient movements across control sets to gauge the potential importance of selection on unobservables. Our design follows this guidance as far as a cross-section permits: we compare city and neighbourhood fixed effects, report how the coefficient moves as controls are added, and interpret the city-fixed-effects estimate as an upper bound.
34 34
35 −\subsection{Spatial Econometrics in Housing Research}\label{sec:lit_spatial}
35 +\subsection{Spatial Econometrics and Spatial Inference}\label{sec:lit_spatial}
36 36
37 −Housing prices are spatially dependent: nearby dwellings share unobserved amenities, and pricing spillovers propagate through comparable-based valuation. Ignoring this dependence invalidates inference and can bias coefficients when spatially correlated unobservables are also correlated with regressors \citep{dubin1988estimation, can1992specification}. The canonical modelling responses are the spatial autoregressive (SAR) and spatial error (SEM) models \citep{anselin1988spatial}, with feasible estimation by spatial two-stage least squares and generalised moments developed by \citet{kelejian1998generalized} and \citet{kelejian1999generalized}---the estimators we employ---and comprehensive treatment in \citet{lesage2009introduction}. Our buffer-count exposure variable is itself a spatially weighted aggregate, so the spatial models play a dual role in this paper: they absorb residual spatial dependence, and they provide a conservative check on whether the Airbnb--rent association merely proxies for spatially correlated unobservables.
37 +Housing prices are spatially dependent: nearby dwellings share unobserved amenities, and valuation spillovers propagate through comparable-based pricing. Ignoring this dependence invalidates inference and can bias coefficients when spatially correlated unobservables are also correlated with regressors \citep{dubin1988estimation, can1992specification}. The canonical modelling responses are the spatial autoregressive (SAR) and spatial error (SEM) models \citep{anselin1988spatial}, with feasible estimation by spatial two-stage least squares and generalised moments developed by \citet{kelejian1998generalized, kelejian1999generalized}, the estimators we employ. \citet{lesage2009introduction} emphasise that in a SAR model the regression coefficients are not marginal effects; the appropriate summary measures are the average direct, indirect and total impacts implied by the spatial multiplier, which we report. A separate literature addresses inference under spatial dependence without modelling it: \citet{conley1999gmm} proposes a spatial heteroskedasticity-and-autocorrelation-consistent (HAC) covariance estimator with a distance kernel, \citet{kelejian2007hac} extend it to spatial regression models, and \citet{cameron2015practitioner} discuss cluster-robust alternatives and their failure when a single cluster dominates the sample. Our buffer-count exposure variable is itself a spatial moving average of Airbnb locations, so neighbouring rental listings have mechanically correlated regressors; this makes spatially robust inference a requirement rather than a refinement. Because any buffer or neighbourhood definition is a discretisation of a continuous spatial process, the modifiable areal unit problem \citep{fotheringham1991modifiable} also applies, which motivates the use of several radii and ring decompositions.
38 38
39 39 \subsection{Distributional Effects and Quantile Regression}\label{sec:lit_quantile}
40 40
41 −Mean regression can mask heterogeneity across the conditional price distribution. Quantile regression \citep{koenker1978regression, koenker2001quantile} recovers characteristic prices at arbitrary quantiles, and housing applications consistently find that implicit prices differ across the distribution: \citet{zietz2008determinants} show that buyers of higher-priced homes value certain attributes differently from buyers of lower-priced homes, and \citet{mcmillen2008changes} decomposes changes in the house-price distribution into characteristics and coefficient effects. In the STR context, distributional heterogeneity is economically meaningful: if STR pressure is concentrated where rents are already high, the affordability consequences differ sharply from those of a uniform shift. Our Model~5 provides, to our knowledge, the first quantile-level evidence on the Airbnb--rent association for a Canadian market.
41 +Mean regression can mask heterogeneity across the conditional price distribution. Quantile regression \citep{koenker1978regression, koenker2001quantile} recovers implicit prices at arbitrary quantiles, and housing applications consistently find that implicit prices differ across the distribution: \citet{zietz2008determinants} show that buyers of higher-priced homes value certain attributes differently from buyers of lower-priced homes, and \citet{mcmillen2008changes} decomposes changes in the house-price distribution into characteristics and coefficient effects. In the STR context, distributional heterogeneity matters for policy: if STR pressure is concentrated where rents are already high, the affordability consequences differ from those of a uniform shift. Our Model~5 provides, to our knowledge, the first quantile-level evidence on the Airbnb--rent association for a Canadian market.
42 42
43 43 \subsection{Machine Learning in Housing Economics}\label{sec:lit_ml}
44 44
45 −Machine-learning methods enter modern hedonic practice in two roles: as prediction benchmarks and as data-driven specification checks \citep{mullainathan2017machine, athey2019machine}. We use the LASSO \citep{tibshirani1996regression} and the elastic net \citep{zou2005regularization} for regularised variable selection, and random forests \citep{breiman2001random} and gradient boosting \citep{friedman2001greedy} as flexible nonlinear benchmarks, with SHAP values \citep{lundberg2017unified} for feature attribution; all models are implemented in scikit-learn \citep{pedregosa2011scikit}. The comparison between OLS and the flexible learners serves an econometric purpose articulated by \citet{mullainathan2017machine}: if a linear hedonic attains predictive accuracy close to the flexible frontier, linearity is an adequate approximation for inference; where it falls short, the gap signals nonlinearities---in our data, primarily geographic---that fixed effects and buffer construction must absorb.
45 +Machine-learning methods enter hedonic practice as prediction benchmarks and as data-driven specification checks \citep{mullainathan2017machine, athey2019machine}. We use the LASSO \citep{tibshirani1996regression} and the elastic net \citep{zou2005regularization} for regularised variable selection, random forests \citep{breiman2001random} and gradient boosting \citep{friedman2001greedy} as flexible nonlinear benchmarks, and SHAP values \citep{lundberg2017unified} for feature attribution; all models are implemented in scikit-learn \citep{pedregosa2011scikit}. The comparison between OLS and the flexible learners serves an econometric purpose: if a linear hedonic model attains predictive accuracy close to the flexible frontier, linearity is an adequate approximation for inference; where it falls short, the gap signals nonlinearities that fixed effects and exposure construction must absorb. With geographic coordinates among the features, however, tree-based learners can reproduce neighbourhood rent levels from the locations of nearby training listings, so that random train--test splits overstate their accuracy for new neighbourhoods; spatially blocked cross-validation, in which whole neighbourhoods are held out, addresses this and is the counterpart in prediction of the fixed-effects comparison in estimation.
46 46
47 47 \subsection{Tourism Gentrification and Short-Term Rental Regulation}\label{sec:lit_regulation}
48 48
49 −Finally, a critical urban literature situates STRs within longer-running processes of tourism-driven neighbourhood change. \citet{gotham2005tourism} coined ``tourism gentrification'' to describe the transformation of New Orleans' Vieux Carr\'e; \citet{cocola2016holiday} identifies holiday rentals as a distinct gentrification battlefront in which transient visitors replace residents; and \citet{wachsmuth2018airbnb} connect this process explicitly to platform-enabled rent gaps. The commercialisation of nominally peer-to-peer platforms is central to this critique: \citet{ke2017sharing} documents that professional multi-listing hosts account for a disproportionate share of Airbnb supply and revenue. On the policy side, \citet{gurran2017when} ask how urban planners should respond to Airbnb; \citet{nieuwland2020regulating} compare regulatory regimes across cities, from outright prohibition to registration and cap systems; and \citet{agyeman2020airbnb} examine the equity dimensions of STR regulation. In Quebec, provincial law requires STR operators to register with the Corporation de l'industrie touristique du Qu\'ebec (CITQ), and Montreal restricts commercial STRs to designated zones---a regime whose spatial targeting our decay results speak to directly.
49 +A critical urban literature situates STRs within longer-running processes of tourism-driven neighbourhood change. \citet{gotham2005tourism} coined ``tourism gentrification'' to describe the transformation of New Orleans' Vieux Carr\'e; \citet{cocola2016holiday} identifies holiday rentals as a distinct gentrification front in which transient visitors replace residents; \citet{cocola2021airbnb} document the buy-to-let investment channel and displacement in Lisbon; and \citet{wachsmuth2018airbnb} connect this process to platform-enabled rent gaps. The commercialisation of nominally peer-to-peer platforms is central to this critique: \citet{ke2017sharing} shows that multi-listing hosts account for a disproportionate share of Airbnb supply and revenue. On the policy side, \citet{gurran2017when} ask how planners should respond to Airbnb, and \citet{nieuwland2020regulating} compare regulatory regimes across cities, from prohibition to registration and cap systems. Quebec's regime combines provincial registration of all STR establishments, including primary residences, with municipal zoning; Montreal further restricts primary-residence STRs to a summer window and bans them in some boroughs (Section~\ref{sec:discussion}).
50 50
51 51 \subsection{Positioning and Contribution}\label{sec:lit_gap}
52 52
53 −Three gaps emerge from this review. First, despite a mature international literature spanning correlational and quasi-experimental designs, there is no listing-level econometric evidence on the STR--rent relationship for Quebec, and Canadian evidence more broadly stops at descriptive market measurement \citep{combs2020short} and critical urban geography \citep{grisdale2021displacement}. Second, few studies examine the \textit{distributional} incidence of the association---most report mean effects---although the affordability debate turns on who bears the pressure. Third, the pricing side and the rent side of the market are rarely analysed jointly in the same data, despite the opportunity-cost logic that connects them. This paper addresses all three gaps: it provides the first listing-level, multi-method quantification of the Airbnb--rent association in Quebec, characterises the association across the full conditional rent distribution, and estimates both sides of the market with mutually consistent variable constructions. We are equally deliberate about what the paper does not do: with a single cross-section we do not identify causal effects, and we position our estimates as conditional correlations to be read against---and, as it turns out, found consistent with---the quasi-experimental magnitudes surveyed above.
53 +Three gaps emerge from this review. First, despite a mature international literature spanning correlational and quasi-experimental designs, there is no listing-level econometric evidence on the STR--rent relationship for Quebec, and Canadian evidence more broadly stops at market measurement \citep{combs2020short} and critical urban geography \citep{grisdale2021displacement}. Second, the cross-sectional studies that dominate the evidence base for most markets rarely report how their estimates respond to neighbourhood fixed effects or to spatially robust inference, although the identification literature identifies these as the first-order checks. Third, the distributional incidence of the association is seldom examined. This paper addresses the three gaps with a single data set: it provides listing-level estimates for Quebec, documents the attenuation of the Airbnb--rent coefficient from city to neighbourhood fixed effects and the inflation of standard errors under spatial dependence, and characterises the association across the conditional rent distribution. We are explicit about what the paper does not do: with a single cross-section we do not identify a causal effect, and we read our estimates against, rather than as substitutes for, the quasi-experimental magnitudes surveyed above.
modified paper/sections/03_data.tex +41 −31
@@ -4,45 +4,49 @@
4 4 % =============================================================================
5 5 \section{Data}\label{sec:data}
6 6
7 −This section describes the two primary datasets, the cleaning procedures applied to each, the spatial merge strategy used to link them, and the construction of key variables.
7 +This section describes the two data sets, the cleaning procedures, the spatial merge that links them, the construction of the exposure and neighbourhood variables, and the limitations of the data. Both data sets were collected in early 2026; the Realtor.ca extraction is dated 8 January 2026, and the Airbnb file carries no timestamp.
8 8
9 −\subsection{Airbnb Listings}
9 +\subsection{Airbnb Listings}\label{sec:data_airbnb}
10 10
11 −Our Airbnb data consist of approximately 5{,}000 listings scraped from the Airbnb platform for the province of Quebec, Canada. Each listing record contains the following fields: listing name, city, latitude and longitude coordinates, property type, nightly price (in Canadian dollars), star rating, number of reviews, superhost status, guest-favourite designation, pet-friendliness, and price/rating category indicators.
11 +The Airbnb data were scraped from the public platform for the province of Quebec and comprise 5{,}000 listings. Each record contains the listing name, city, latitude and longitude, property type, displayed price, star rating, number of reviews, number of bedrooms and bathrooms, guest capacity, amenities count, superhost status, guest-favourite designation and pet policy. The listings span the province, with the largest concentrations in Montreal, Quebec City, Mont-Tremblant, Gatineau and resort communities in the Laurentians, Charlevoix and the Eastern Townships. Property types are \textit{Rental unit} (the most common), \textit{Cabin/Chalet}, \textit{House}, \textit{Other}, \textit{Condo} and \textit{Apartment}.
12 12
13 −The listings span multiple cities across Quebec, with the largest concentrations in Montreal, Quebec City (Qu\'{e}bec), Sherbrooke, and various resort/cottage communities in the Laurentians and Eastern Townships. Property types include \textit{Rental unit}, \textit{Cabin/Chalet}, \textit{House}, \textit{Condo}, and \textit{Apartment}, with Rental unit being the most common category.
13 +\paragraph{Cleaning.} We standardise city names by merging accented and unaccented variants and consolidating aliases (Appendix~\ref{app:data}). The price field is missing for 1{,}544 listings (30.9\%), which we drop, leaving 3{,}456 listings; prices are then winsorised at the 1st and 99th percentiles. Missing ratings (16\%) are imputed with the sample median, on the assumption that unrated listings are recent and of average quality, and missing review counts are set to zero. An indicator \texttt{is\_entire\_home} identifies the property types House, Cabin/Chalet and Condo, which are typically let in their entirety; the platform's room-type field was not captured by the scraper, so this is a proxy. Superhosts account for 53\% of the cleaned listings and entire homes for 47\% (Table~\ref{tab:summary_airbnb}).
14 14
15 −\paragraph{Cleaning.} We standardise city names by merging accented and unaccented variants (e.g., ``Montr\'{e}al'' and ``Montreal'') and consolidating aliases (e.g., ``Quebec City'' and ``Qu\'{e}bec City'' mapped to ``Qu\'{e}bec''). We drop listings with missing or non-positive nightly prices, which yields a cleaned sample of 3{,}456 listings, and winsorise the price distribution at the 1st and 99th percentiles to mitigate the influence of extreme outliers. The log-transformed price, $\ln(\text{price\_numeric})$, is used as the dependent variable in the Airbnb pricing model. Missing ratings are imputed with the sample median, reflecting the assumption that unrated listings represent recently created properties whose quality is, on average, comparable to the centre of the distribution. Missing review counts are set to zero. An indicator variable, \texttt{is\_entire\_home}, is constructed to identify listings of types House, Cabin/Chalet, and Condo, which are typically rented in their entirety.
15 +\paragraph{A caveat on the price field.} The distribution of the scraped price is bimodal (Figure~\ref{fig:dist_airbnb_logprice}). The median is \$220 per night and 71\% of listings are priced below \$600, but a second mode lies between roughly \$1{,}400 and \$3{,}300 and 26.5\% of listings carry a ``nightly'' price above \$1{,}000, a category that the scraper itself labelled ``Ultra-Luxury.'' Prices of this order for one night are implausible for most of the listings concerned, which include ordinary rental units in Montreal, and the pattern most plausibly reflects total-stay or multi-night prices captured for part of the sample. We cannot recover the intended nightly price from the available fields. The price variable therefore enters the analysis in two ways. For the Airbnb pricing model (Model~2) we report estimates on the full sample and on the subsample priced at or below \$1{,}000 per night (1{,}699 listings with a matched city), and we treat the latter as the more credible. For the rent regressions the price field plays no role in the main exposure measure, which is a count; it affects only the mean nearby Airbnb price used as a secondary exposure variable and as a machine-learning feature, which we interpret with corresponding caution.
16 16
17 −\subsection{Residential Rental Listings}
17 +\subsection{Residential Rental Listings}\label{sec:data_rent}
18 18
19 −The rental data consist of approximately 8{,}300 listings scraped from Realtor.ca, Canada's primary real-estate listing platform, for the province of Quebec. Each record contains: address, latitude and longitude, property type, monthly lease rent (in Canadian dollars), building type, number of bedrooms, number of bathrooms, interior size, number of storeys, and postal code.
19 +The rental data consist of 8{,}356 listings scraped from Realtor.ca, Canada's main real-estate listing platform, for the province of Quebec. Each record contains the address, latitude and longitude, property type, lease rent, building type, number of bedrooms and bathrooms, interior size, number of storeys and postal code. After restricting the sample to single-family residential listings with a monthly rental period and a positive parsed rent, 8{,}303 listings remain, all with valid coordinates. Building types are \textit{Apartment} ($n=7{,}513$), \textit{House} ($n=742$) and \textit{Row/Townhouse} ($n=48$). The geographic distribution is concentrated in the Montreal metropolitan area (Montreal proper accounts for 59\% of listings), with clusters in Laval, Longueuil, Gatineau, Trois-Rivi\`eres, Quebec City and Sherbrooke; 253 municipalities are represented.
20 20
21 −Building types in the rental data are dominated by \textit{Apartment} ($n \approx 7{,}515$), followed by \textit{House} ($n \approx 745$) and \textit{Row/Townhouse} ($n \approx 48$). The geographic distribution is heavily concentrated in the Montreal metropolitan area, with additional clusters in Quebec City, Gatineau, Sherbrooke, and Laval.
22 −
23 −\paragraph{Cleaning.} Monthly rent values are extracted from the lease-rent string and converted to numeric format. We restrict the sample to listings with monthly rental periods and positive rent values. Extreme rent values are handled through winsorisation at the 1st and 99th percentiles. The log of monthly rent, $\ln(\text{rent})$, serves as the dependent variable in the hedonic rent model. Bedroom and bathroom counts are cleaned and converted to numeric types. Listings with missing geographic coordinates are dropped prior to spatial merging.
21 +\paragraph{Cleaning.} Monthly rents are extracted from the lease-rent string and winsorised at the 1st and 99th percentiles; the log of monthly rent is the dependent variable of the hedonic rent model. Bedroom and bathroom counts are converted to numeric values; bedrooms are missing for 378 listings, which are excluded from regressions that use them, so that the baseline estimation sample comprises 7{,}925 listings. Interior size is reported for 3{,}699 listings and is used only in robustness checks; it contains implausible extreme values at both ends (Table~\ref{tab:summary_rent}), which we do not correct. The postal code is complete and defines the forward sortation area (FSA, its first three characters), a Canada Post delivery zone that we use as a neighbourhood identifier: the sample spans 333 FSAs, 180 of which contain at least ten listings and together account for 93\% of the sample; Montreal alone has 103.
24 22
25 23 \subsection{Spatial Merge Strategy}\label{sec:spatial_merge}
26 24
27 −The core challenge in linking the Airbnb and rental datasets is that they share no common listing identifiers. We exploit the fact that both datasets contain precise latitude and longitude coordinates to construct a spatial buffer merge. For each rental listing $i$, we compute the Haversine (great-circle) distance to every Airbnb listing $j$ and count the number of Airbnb listings falling within four concentric buffers: 250\,m, 500\,m, 1\,km, and 2\,km.
28 −
29 −Formally, the Airbnb count for rental listing $i$ within buffer radius $r$ is:
25 +The two data sets share no common identifier, so we link them through their coordinates. For each rental listing $i$ we compute the Haversine (great-circle) distance $d(i,j)$ to every Airbnb listing $j$ (Appendix~\ref{app:haversine}) and count the Airbnb listings within four concentric radii, $r \in \{250\,\text{m}, 500\,\text{m}, 1\,\text{km}, 2\,\text{km}\}$:
30 26 \begin{equation}\label{eq:buffer_count}
31 − \texttt{airbnb\_count}_{i,r} = \sum_{j=1}^{N_{\text{Airbnb}}} \mathbf{1}\left[ d(i, j) \leq r \right],
27 + A_{i,r} = \sum_{j=1}^{N_{A}} \mathbf{1}\left[ d(i, j) \leq r \right],
32 28 \end{equation}
33 −where $d(i, j)$ is the Haversine distance between listings $i$ and $j$, and $\mathbf{1}[\cdot]$ is the indicator function.
29 +where $N_A = 3{,}456$ and $\mathbf{1}[\cdot]$ is the indicator function. Within each radius we also construct the Airbnb density $A_{i,r}/(\pi r^2)$ (listings per km$^2$), the mean nightly price, the share of entire-home listings, the mean rating and the superhost share; the composition variables are undefined when $A_{i,r}=0$.
34 30
35 −In addition to the count, we construct several exposure metrics within each buffer: Airbnb density (count divided by buffer area, $\pi r^2$), mean Airbnb nightly price, share of entire-home listings, mean rating, and superhost share. These variables capture not only the intensity of Airbnb activity but also its composition and quality.
31 +Two properties of this construction matter for the econometrics. First, the buffers are nested: $A_{i,2\text{km}}$ contains $A_{i,1\text{km}}$, which contains $A_{i,500\text{m}}$, and so on, so coefficients at different radii are not independent pieces of evidence and a ring decomposition (Section~\ref{sec:robustness}) is needed to separate near from far exposure. Second, the buffers of neighbouring rental listings overlap, so that the same Airbnb listing enters the exposure of many rental listings. This is not double counting in the regression, each rental listing's exposure being correctly measured, but it makes the regressor a spatial moving average of Airbnb locations and induces strong spatial correlation in both the regressor and, plausibly, the error. Section~\ref{sec:inference} addresses the consequences for inference.
36 32
37 −At the preferred 500\,m radius, the mean Airbnb count per rental listing is approximately 8 listings, with substantial variation across urban and rural areas.
33 +Table~\ref{tab:exposure} summarises the exposure counts. The distribution is highly skewed and zero-inflated: at 500\,m the mean count is 7.9 and the standard deviation 14.2, but the median is 1 and 44\% of rental listings have no Airbnb listing within 500\,m (61\% at 250\,m, 27\% at 1\,km, 13\% at 2\,km). The extensive margin, having any Airbnb nearby, is therefore a substantial part of the variation in exposure, which motivates the extensive/intensive decomposition and the logarithmic specification in Sections~\ref{sec:results} and~\ref{sec:robustness}. Within FSAs, the standard deviation of the 500\,m count is 7.2, and about 26\% of its total variance is within-FSA variation, so neighbourhood fixed effects leave meaningful identifying variation.
34 +
35 +\begin{table}[htbp]
36 + \centering
37 + \caption{Airbnb Exposure of Rental Listings by Buffer Radius}
38 + \label{tab:exposure}
39 + \small
40 + \input{../results/tables/exposure_summary.tex}
41 +\end{table}
38 42
39 43 \subsection{City-Level Aggregation}
40 44
41 −As a complementary linkage strategy, we aggregate Airbnb data to the city level and merge city-level summary statistics---total Airbnb count, mean nightly price, share of entire-home listings---onto the rental data using the city name as the merge key. This approach sacrifices the within-city spatial variation that drives our buffer-based analysis but provides a useful benchmark for examining cross-city relationships.
45 +As a complementary linkage, we aggregate the Airbnb data to the city level and merge the total Airbnb count, the mean nightly price and the entire-home share onto the rental data by standardised city name. Of the 253 municipalities in the rental data, 153 have at least one Airbnb listing and enter the city-level regressions of Section~\ref{sec:results_city}; for the Airbnb pricing model, 2{,}437 Airbnb listings are located in a city with rental listings and thus have a city mean rent. This linkage discards the within-city spatial variation that drives the buffer-based analysis and is used only as a descriptive benchmark.
42 46
43 47 \subsection{Summary Statistics}
44 48
45 −Tables~\ref{tab:summary_airbnb} and~\ref{tab:summary_rent} present summary statistics for the cleaned Airbnb and rental datasets, respectively.
49 +Tables~\ref{tab:summary_airbnb} and~\ref{tab:summary_rent} report summary statistics for the two cleaned data sets. The median monthly rent is \$1{,}950 (mean \$2{,}142), with an interquartile range of \$1{,}615 to \$2{,}495 after winsorisation; the typical listing has two bedrooms and one bathroom. The Airbnb listings are heterogeneous, from budget rooms to large chalets sleeping up to sixteen guests; the mean nightly price of \$1{,}233 reflects the bimodality discussed above and should not be read as a typical price. Appendix Table~\ref{tab:correlation} reports the pairwise correlations between log rent, the 500\,m exposure measures and the dwelling controls. The raw correlation between log rent and the 500\,m count is 0.14; the count is negatively correlated with bedrooms ($-0.19$), reflecting the smaller units found in dense, Airbnb-rich neighbourhoods, a pattern that explains why the Airbnb coefficient rises when dwelling controls are added (Section~\ref{sec:results_baseline}).
46 50
47 51 \begin{table}[htbp]
48 52 \centering
@@ -50,6 +54,8 @@ Tables~\ref{tab:summary_airbnb} and~\ref{tab:summary_rent} present summary stati
50 54 \label{tab:summary_airbnb}
51 55 \small\setlength{\tabcolsep}{4pt}
52 56 \input{../results/tables/summary_stats_airbnb.tex}
57 + \par\vspace{4pt}
58 + \parbox{\textwidth}{\footnotesize Cleaned sample of 3{,}456 listings with a non-missing price (winsorised at the 1st and 99th percentiles). Ratings are median-imputed for 16\% of listings. The nightly-price distribution is bimodal (Figure~\ref{fig:dist_airbnb_logprice}); see Section~\ref{sec:data_airbnb}.}
53 59 \end{table}
54 60
55 61 \begin{table}[htbp]
@@ -58,16 +64,13 @@ Tables~\ref{tab:summary_airbnb} and~\ref{tab:summary_rent} present summary stati
58 64 \label{tab:summary_rent}
59 65 \small\setlength{\tabcolsep}{4pt}
60 66 \input{../results/tables/summary_stats_rent.tex}
67 + \par\vspace{4pt}
68 + \parbox{\textwidth}{\footnotesize Cleaned sample of 8{,}303 monthly rental listings (rent winsorised at the 1st and 99th percentiles). Bedrooms are missing for 378 listings; interior size is reported for 3{,}699 listings and contains implausible extreme values that are not corrected.}
61 69 \end{table}
62 70
63 −Key features of the data are worth noting. The median Airbnb nightly price is approximately \$220 CAD, while the median monthly rent is approximately \$1{,}950 CAD. There is substantial variation in both prices, reflecting the heterogeneity of listings in terms of location, size, and quality. The Airbnb data span a wide range of property types, from budget-oriented rental units to luxury chalets, while the rental data are dominated by apartment units.
64 −
65 −% Table removed: buffer_summary.tex not generated as a separate file.
66 −% Buffer-based exposure statistics are described in Section~\ref{sec:spatial_merge}.
67 −
68 71 \subsection{Geographic Distribution}
69 72
70 −Figures~\ref{fig:map_airbnb} and~\ref{fig:map_rent} display the geographic distribution of Airbnb and rental listings, respectively. The spatial overlap between the two datasets is concentrated in the Montreal metropolitan area and, to a lesser extent, in Quebec City and resort regions.
73 +Figures~\ref{fig:map_airbnb} and~\ref{fig:map_rent} display the geographic distribution of the two samples. Their overlap is concentrated in the Montreal metropolitan area and, to a lesser extent, in Quebec City and Gatineau; many Airbnb listings are in resort areas with few or no rental listings, and the rental sample in turn covers suburban municipalities with little STR activity. Figure~\ref{fig:price_distributions} shows the distributions of Airbnb nightly prices and monthly rents in levels, and Figure~\ref{fig:dist_airbnb_logprice} the nightly-price distribution on a logarithmic scale, where the two modes are apparent.
71 74
72 75 \begin{figure}[htbp]
73 76 \centering
@@ -83,27 +86,34 @@ Figures~\ref{fig:map_airbnb} and~\ref{fig:map_rent} display the geographic distr
83 86 \label{fig:map_rent}
84 87 \end{figure}
85 88
86 −Figure~\ref{fig:price_distributions} shows the distributions of Airbnb nightly prices and monthly rents (both in levels, trimmed above the 99th percentile for readability).
87 −
88 89 \begin{figure}[htbp]
89 90 \centering
90 91 \begin{subfigure}[t]{0.48\textwidth}
91 92 \centering
92 93 \includegraphics[width=\textwidth]{dist_airbnb_price.pdf}
93 − \caption{Airbnb nightly price (CAD)}
94 + \caption{Airbnb nightly price (CAD, trimmed at the 99th percentile)}
94 95 \label{fig:dist_airbnb}
95 96 \end{subfigure}
96 97 \hfill
97 98 \begin{subfigure}[t]{0.48\textwidth}
98 99 \centering
99 100 \includegraphics[width=\textwidth]{dist_rent.pdf}
100 − \caption{Monthly rent (CAD)}
101 + \caption{Monthly rent (CAD, trimmed at the 99th percentile)}
101 102 \label{fig:dist_rent}
102 103 \end{subfigure}
103 104 \caption{Distributions of Airbnb Nightly Prices and Monthly Rents}
104 105 \label{fig:price_distributions}
105 106 \end{figure}
106 107
107 −\subsection{Data Limitations}
108 +\begin{figure}[htbp]
109 + \centering
110 + \includegraphics[width=0.7\textwidth]{dist_airbnb_logprice.pdf}
111 + \caption{Distribution of Scraped Airbnb Nightly Prices on a Logarithmic Scale}
112 + \label{fig:dist_airbnb_logprice}
113 + \par\vspace{4pt}
114 + \parbox{0.9\textwidth}{\footnotesize The dashed line marks \$1{,}000 per night. The second mode above this threshold (26.5\% of listings) most plausibly reflects total-stay prices captured by the scraper; see Section~\ref{sec:data_airbnb}.}
115 +\end{figure}
116 +
117 +\subsection{Data Limitations}\label{sec:data_limitations}
108 118
109 −Several limitations of the data should be acknowledged. First, the data are cross-sectional, representing a single snapshot in time. We cannot observe how Airbnb entry or exit affects rents over time, nor can we control for time-varying confounders. Second, we do not observe host identifiers, which precludes the construction of multi-listing indicators at the host level---a variable that has been important in prior studies for distinguishing professional from casual hosts. Third, the Airbnb data are scraped from the public-facing platform and may not capture all listings, particularly those that are inactive, delisted, or hidden behind search filters. Fourth, the rental data from Realtor.ca represent \textit{asking} rents rather than \textit{transacted} rents; to the extent that there is systematic negotiation between posted and final rents, our dependent variable may be measured with noise. Fifth, there may be spatial selection in the data: the coverage of both platforms is likely denser in urban areas, particularly Montreal, which limits the generalisability of our findings to rural and peripheral markets.
119 +Several limitations should be stated at the outset. First, the data are a single cross-section: we observe neither the entry and exit of Airbnb listings nor the evolution of rents, and we cannot control for time-varying confounders. Second, we do not observe host identifiers, which precludes multi-listing indicators distinguishing commercial from casual hosts, a distinction that matters in the Canadian debate \citep{combs2020short}. Third, the Airbnb data are scraped from the public platform and omit listings that were inactive, calendar-blocked or filtered out at the time of collection; the price field is affected by the measurement problem described above; and the room type is not observed. The collection took place in winter, when the composition of active listings (resort chalets versus urban apartments) differs from the summer peak and when Montreal's seasonal rules for primary-residence STRs were not in their permitted window, so the Montreal listings observed are those operating in commercial zones or outside the rules. Fourth, the rental data are \textit{asking} rents for units advertised on Realtor.ca rather than contract rents for the occupied stock, and Realtor.ca covers the agent-listed segment of the market, which over-represents newer and higher-priced units relative to the stock as a whole; the coverage of both platforms is also denser in urban areas, which limits generalisation to peripheral markets. Fifth, because the composition measures are undefined for rental listings with no Airbnb within the radius, specifications that use them (Model~1e, the machine-learning benchmark) are estimated on the 4{,}370 listings with positive 500\,m exposure, a selected subsample. We return to these limitations in Section~\ref{sec:discussion}.
modified paper/sections/04_methodology.tex +43 −51
@@ -4,87 +4,79 @@
4 4 % =============================================================================
5 5 \section{Methodology}\label{sec:methodology}
6 6
7 −This section presents the econometric models employed to quantify the association between Airbnb activity and residential rents, discusses identification, and describes the machine-learning robustness framework.
7 +This section presents the econometric models, the fixed-effects strategy, the treatment of spatial dependence in estimation and in inference, and the machine-learning benchmark. Throughout, $i$ indexes rental listings, $j$ Airbnb listings, $c$ cities and $g$ forward sortation areas (FSAs).
8 8
9 −\subsection{Model 1: Hedonic Rent Model with Airbnb Exposure}\label{sec:model1}
10 −
11 −Our baseline specification is a hedonic rent equation \citep{rosen1974hedonic, malpezzi2003hedonic} in which the log of monthly rent is regressed on a measure of nearby Airbnb activity and a vector of dwelling-level controls:
9 +\subsection{Model 1: Hedonic Rent Function with Airbnb Exposure}\label{sec:model1}
12 10
11 +The baseline specification is a hedonic rent function \citep{rosen1974hedonic, malpezzi2003hedonic} in which the log of the monthly asking rent is regressed on the Airbnb count within radius $r$ and a vector of dwelling characteristics:
13 12 \begin{equation}\label{eq:hedonic_rent}
14 − \ln(\text{rent}_i) = \alpha + \beta \cdot \texttt{airbnb\_count}_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma} + \sum_{c} \delta_c \cdot \mathbf{1}[\text{city}_i = c] + \varepsilon_i,
13 + \ln(\text{rent}_i) = \alpha + \beta\, A_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma} + \delta_{c(i)} + \varepsilon_i,
15 14 \end{equation}
15 +where $A_{i,r}$ is defined in Equation~\eqref{eq:buffer_count} (the reference radius is $r = 500$\,m); $\mathbf{X}_i$ contains the number of bedrooms, the number of bathrooms and building-type indicators (House and Row/Townhouse, with Apartment as the reference category), with interior size added in a robustness check; $\delta_{c(i)}$ is a fixed effect for the city of listing $i$; and $\varepsilon_i$ is an error term. The coefficient $\beta$ is a semi-elasticity: $100\beta$ is approximately the percentage difference in rent associated with one additional Airbnb listing within the radius, conditional on dwelling characteristics and city, and $100(e^{\beta}-1)$ is the exact percentage difference. Columns (1d) and (1e) of Table~\ref{tab:hedonic_rent} replace $A_{i,r}$ with the Airbnb density, which at a fixed radius is the count divided by $\pi r^2$ and therefore a rescaling, and with the entire-home share within the buffer, which is defined only when $A_{i,r}>0$.
16 +
17 +City fixed effects absorb all city-level determinants of rent, including average neighbourhood quality, labour-market conditions, housing-market tightness, tourism infrastructure and municipal regulation. The identifying variation in Equation~\eqref{eq:hedonic_rent} is therefore the within-city, between-neighbourhood and between-block variation in Airbnb density.
16 18
17 −\noindent where $\text{rent}_i$ is the monthly rent of listing $i$; $\texttt{airbnb\_count}_{i,r}$ is the number of Airbnb listings within buffer radius $r$ of listing $i$ (our preferred specification uses $r = 500$\,m); $\mathbf{X}_i$ is a vector of dwelling characteristics including the number of bedrooms, number of bathrooms, building type (Apartment, House, Row/Townhouse), and interior size (where available); $\delta_c$ denotes city fixed effects that absorb all time-invariant, city-level unobservables (including average neighbourhood quality, local labour-market conditions, and municipal regulations); and $\varepsilon_i$ is a mean-zero error term.
19 +\subsection{Neighbourhood Fixed Effects}\label{sec:model_fsa}
18 20
19 −The coefficient of interest, $\beta$, has a semi-elasticity interpretation: it measures the approximate percentage change in monthly rent associated with one additional Airbnb listing within the buffer, conditional on observed dwelling characteristics and city. A positive and statistically significant $\hat{\beta}$ is consistent with the hypothesis that Airbnb activity is associated with higher residential rents, though it does not, by itself, establish causality. The reliance on spatial fixed effects and multiple functional forms of the exposure variable follows the specification guidance of \citet{kuminoff2010which}, whose simulation evidence identifies these as the most effective safeguards against omitted-variable bias in cross-sectional hedonic models.
21 +Within a city, Airbnb listings concentrate in neighbourhoods with tourist attractions, restaurants, transit and architectural character, which also command higher rents. City fixed effects do not absorb these neighbourhood-level unobservables. Following the specification guidance of \citet{kuminoff2010which} and \citet{bishop2020best}, we therefore also estimate
22 +\begin{equation}\label{eq:hedonic_fsa}
23 + \ln(\text{rent}_i) = \alpha + \beta^{F} A_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma}^{F} + \theta_{g(i)} + \varepsilon_i,
24 +\end{equation}
25 +where $\theta_{g(i)}$ is a fixed effect for the FSA of listing $i$. FSAs are nested within cities in practice (the first character identifies the region, the second the urban or rural character and the third a delivery zone), so Equation~\eqref{eq:hedonic_fsa} compares rental listings within the same postal-code neighbourhood that differ in the number of Airbnb listings within 500\,m. The fixed effects are absorbed by the within transformation, and FSAs with a single listing are dropped. Comparing $\hat\beta$ and $\hat\beta^{F}$ is a direct test of how much of the city-level association is driven by between-neighbourhood sorting. In the spirit of \citet{oster2019unobservable}, we also report how the coefficient moves from the bivariate regression to the specifications with dwelling controls, city fixed effects and FSA fixed effects; a coefficient that is stable across control sets is more credible than one that moves substantially, and the direction of movement indicates the direction of the omitted-variable bias that the added controls remove.
20 26
21 −We estimate Equation~\eqref{eq:hedonic_rent} by ordinary least squares (OLS) with heteroskedasticity-robust standard errors (HC1).
27 +Within Equation~\eqref{eq:hedonic_fsa} we also decompose exposure into an extensive and an intensive margin, replacing $\beta^{F} A_{i,r}$ with $\beta^{F}_0 \mathbf{1}[A_{i,r}>0] + \beta^{F}_1 A_{i,r}$, and we use the concave transformation $\ln(1+A_{i,r})$, under which the coefficient is approximately the percentage change in rent associated with a one-percent increase in $1+A_{i,r}$. These forms address the zero inflation documented in Table~\ref{tab:exposure}.
22 28
23 29 \subsection{Model 2: Hedonic Airbnb Pricing Model}\label{sec:model2}
24 30
25 −To examine the pricing determinants of Airbnb listings and the relationship between local rents and short-term rental prices, we estimate a hedonic model of Airbnb nightly prices:
26 −
31 +To examine whether STR pricing responds to local long-term rents, we estimate a hedonic model of Airbnb nightly prices:
27 32 \begin{equation}\label{eq:hedonic_airbnb}
28 − \ln(\text{price}_j) = \alpha' + \theta \cdot \overline{\text{rent}}_c + \mathbf{Z}_j' \boldsymbol{\lambda} + \sum_{c} \delta'_c \cdot \mathbf{1}[\text{city}_j = c] + u_j,
33 + \ln(\text{price}_j) = \alpha' + \theta\, \overline{\ln(\text{rent})}_{c(j)} + \mathbf{Z}_j' \boldsymbol{\lambda} + u_j,
29 34 \end{equation}
35 +where $\overline{\ln(\text{rent})}_{c(j)}$ is the mean log monthly rent in the city of listing $j$, computed from the rental data, and $\mathbf{Z}_j$ contains bedrooms, bathrooms, guest capacity, the amenities count, superhost status and the entire-home indicator. Because the two price variables are in logarithms, $\theta$ is an elasticity. A positive $\theta$ would be consistent with an opportunity-cost channel in which hosts facing higher forgone rents set higher nightly prices. When city fixed effects are added, $\overline{\ln(\text{rent})}_{c(j)}$ is constant within city and perfectly collinear with them, so $\theta$ is not identified; the fixed-effects columns therefore omit it and serve to estimate the within-city implicit prices of listing characteristics. Given the measurement problem in the price field (Section~\ref{sec:data_airbnb}), we estimate Equation~\eqref{eq:hedonic_airbnb} on all 2{,}437 listings with a matched city and on the 1{,}699 listings priced at or below \$1{,}000 per night.
30 36
31 −\noindent where $\text{price}_j$ is the nightly price of Airbnb listing $j$; $\overline{\text{rent}}_c$ is the mean log monthly rent in city $c$ (obtained from the rental dataset); $\mathbf{Z}_j$ includes listing characteristics---the number of bedrooms and bathrooms, guest capacity, amenities count, superhost status, and the entire-home indicator; and $u_j$ is an error term.
32 −
33 −The coefficient $\theta$ captures the association between the local residential rent level and Airbnb pricing. A positive $\hat{\theta}$ would suggest that Airbnb hosts in higher-rent cities charge higher nightly prices, consistent with the opportunity-cost channel: when the forgone rental income from listing a unit on Airbnb is higher, hosts set higher nightly prices to compensate. Note that when city fixed effects are included, $\overline{\text{rent}}_c$ is collinear with the city dummies; in such specifications, $\theta$ is identified from the city-level variation absorbed by the fixed effects, and we report results both with and without city fixed effects.
34 −
35 −\subsection{Model 3: City-Level Interaction Model}\label{sec:model3}
36 −
37 −To characterise the bidirectional relationship between Airbnb activity and rents at the city level, we estimate a forward and a reverse aggregate regression:
37 +\subsection{Model 3: City-Level Regressions}\label{sec:model3}
38 38
39 +To describe the cross-city co-movement of Airbnb activity and rents, we estimate a forward and a reverse aggregate regression,
39 40 \begin{align}
40 − \overline{\ln(\text{rent})}_c &= a_1 + b_1 \cdot \text{airbnb\_count}_c + \mathbf{W}_c' \boldsymbol{\phi}_1 + e_{1c}, \label{eq:city_rent} \\[6pt]
41 − \text{airbnb\_count}_c &= a_2 + b_2 \cdot \overline{\ln(\text{rent})}_c + \mathbf{W}_c' \boldsymbol{\phi}_2 + e_{2c}, \label{eq:city_airbnb}
41 + \overline{\ln(\text{rent})}_c &= a_1 + b_1\, A_c + \mathbf{W}_c' \boldsymbol{\phi}_1 + e_{1c}, \label{eq:city_rent} \\[4pt]
42 + A_c &= a_2 + b_2\, \overline{\ln(\text{rent})}_c + \mathbf{W}_c' \boldsymbol{\phi}_2 + e_{2c}, \label{eq:city_airbnb}
42 43 \end{align}
44 +where $A_c$ is the total number of Airbnb listings in city $c$ and $\mathbf{W}_c$ contains the city means of bedrooms and bathrooms. The 153 cities with at least one Airbnb listing enter these regressions; most contribute few underlying listings, and the regressions are descriptive.
43 45
44 −\noindent where overlines denote city-level means, $\text{airbnb\_count}_c$ is the total number of Airbnb listings in city $c$, and $\mathbf{W}_c$ contains city-level mean bedrooms and bathrooms. The coefficients $b_1$ and $b_2$ describe the cross-city co-movement of rents and Airbnb activity. Because many of the 153 cities in the aggregated sample contribute few underlying listings, these regressions should be interpreted as descriptive rather than inferential.
45 −
46 −\subsection{Model 4: Spatial Analysis}\label{sec:model4}
47 −
48 −To account for spatial dependence in rents, we estimate a spatial autoregressive (SAR) model and a spatial error model (SEM) alongside the OLS baseline. The SAR model augments the hedonic equation with a spatial lag of the dependent variable:
46 +\subsection{Model 4: Spatial Lag and Spatial Error Models}\label{sec:model4}
49 47
48 +Rents are spatially dependent beyond what observed characteristics and fixed effects capture. We estimate a spatial autoregressive (SAR) model and a spatial error model (SEM) alongside OLS. Let $\mathbf{W}$ be an $n \times n$ row-standardised $k$-nearest-neighbour matrix with $k=5$: $w_{ik} = 1/5$ if rental listing $k$ is among the five listings closest to $i$ in projected (kilometre) coordinates, excluding $i$ itself, and $w_{ik}=0$ otherwise (Appendix~\ref{app:spatial_weights}). The SAR model is
50 49 \begin{equation}\label{eq:spatial_lag}
51 − \ln(\text{rent}_i) = \alpha'' + \rho \cdot \sum_{k} w_{ik} \ln(\text{rent}_k) + \beta' \cdot \texttt{airbnb\_count}_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma}' + \sum_{c} \delta''_c \cdot \mathbf{1}[\text{city}_i = c] + \eta_i,
50 + \ln(\text{rent}_i) = \alpha'' + \rho \sum_{k} w_{ik} \ln(\text{rent}_k) + \beta'\, A_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma}' + \delta''_{c(i)} + \eta_i,
52 51 \end{equation}
52 +so that $\sum_k w_{ik}\ln(\text{rent}_k)$ is the mean log rent of the five nearest rental listings and $\rho$ measures the strength of spatial co-movement. The SEM places the spatial process in the disturbance, $\eta_i = \lambda \sum_k w_{ik} \eta_k + \nu_i$, capturing spatially correlated unobservables. Because the spatial lag is correlated with $\eta_i$, OLS estimation of Equation~\eqref{eq:spatial_lag} is inconsistent; we use the spatial two-stage least squares estimator of \citet{kelejian1998generalized}, which instruments the lag with spatially lagged exogenous regressors, with heteroskedasticity-robust standard errors, and the generalised-moments estimator of \citet{kelejian1999generalized} for the SEM (\texttt{GM\_Lag} and \texttt{GM\_Error} in \texttt{spreg}). To keep the instrument matrix well conditioned, the spatial models include fixed effects for the fifteen largest cities with the remaining cities grouped, and the OLS column of the spatial table uses the same fixed effects.
53 53
54 −\noindent where $\mathbf{W} = [w_{ik}]$ is a row-standardised $k$-nearest-neighbour spatial weights matrix with $k = 5$, so that $\sum_k w_{ik} \ln(\text{rent}_k)$ is the mean log rent of the five nearest rental listings. The spatial autoregressive parameter $\rho$ captures the degree to which rents co-move within a spatial neighbourhood, after controlling for observed characteristics. The SEM instead places the spatial process in the disturbance, $\eta_i = \lambda \sum_k w_{ik} \eta_k + \nu_i$, capturing spatially correlated unobservables. Both models are estimated by the feasible generalised-moments procedures of \citet{kelejian1998generalized} and \citet{kelejian1999generalized} (\texttt{GM\_Lag} and \texttt{GM\_Error}), which avoid the simultaneity bias that OLS estimation of Equation~\eqref{eq:spatial_lag} would entail; see \citet{anselin1988spatial} and \citet{lesage2009introduction} for the underlying theory.
55 −
56 −This specification serves two purposes. First, the spatial models absorb variation from spatially correlated unobservables (e.g., neighbourhood amenities that affect both rents and Airbnb desirability). Second, comparing $\hat{\beta}'$ from Equation~\eqref{eq:spatial_lag} with $\hat{\beta}$ from Equation~\eqref{eq:hedonic_rent} provides a diagnostic for the sensitivity of the Airbnb coefficient to spatial confounders.
57 −
58 −In addition to the spatial lag model, we examine the robustness of the Airbnb exposure measure by varying the buffer radius $r$ across 250\,m, 500\,m, 1\,km, and 2\,km. This exercise traces out the spatial decay of the association: if the Airbnb--rent relationship is genuinely local, we expect $\hat{\beta}$ to be largest at small radii and to attenuate as the buffer expands.
54 +In a SAR model the coefficient $\beta'$ is not the marginal effect of exposure. Writing Equation~\eqref{eq:spatial_lag} in matrix form and solving, $\mathbf{y} = (\mathbf{I}-\rho\mathbf{W})^{-1}(\mathbf{X}\boldsymbol{\beta} + \boldsymbol{\eta})$, so the matrix of partial derivatives of $\mathbf{y}$ with respect to a regressor $x$ is $(\mathbf{I}-\rho\mathbf{W})^{-1}\beta_x$. Following \citet{lesage2009introduction} we report the average direct impact, $n^{-1}\,\mathrm{tr}[(\mathbf{I}-\rho\mathbf{W})^{-1}]\,\beta_x$, the average total impact, which for a row-standardised $\mathbf{W}$ equals $\beta_x/(1-\rho)$, and the average indirect (spillover) impact, their difference:
55 +\begin{equation}\label{eq:impacts}
56 + \text{Direct}_x = \frac{\beta_x}{n}\,\mathrm{tr}\!\left[(\mathbf{I}-\rho\mathbf{W})^{-1}\right], \qquad
57 + \text{Total}_x = \frac{\beta_x}{1-\rho}, \qquad
58 + \text{Indirect}_x = \text{Total}_x - \text{Direct}_x .
59 +\end{equation}
60 +Standard errors for the impacts are obtained by simulation from the estimated asymptotic distribution of $(\hat\beta_x, \hat\rho)$ (Appendix~\ref{app:spatial_weights}). The spatial models serve two purposes: they absorb residual spatial dependence that would otherwise distort inference, and the comparison of the SEM coefficient with OLS indicates whether the Airbnb coefficient proxies for spatially correlated unobservables at the scale of the five nearest listings. They do not, however, substitute for neighbourhood fixed effects, because a five-neighbour lag operates at the block scale whereas the sorting of STR supply operates at the neighbourhood scale.
59 61
60 62 \subsection{Model 5: Quantile Regression}\label{sec:model5}
61 63
62 −To investigate heterogeneity in the Airbnb--rent association across the conditional rent distribution, we estimate quantile regressions \citep{koenker1978regression, koenker2001quantile}:
63 −
64 +To examine heterogeneity across the conditional rent distribution we estimate quantile regressions \citep{koenker1978regression, koenker2001quantile},
64 65 \begin{equation}\label{eq:quantile}
65 − Q_{\tau}\!\left[\ln(\text{rent}_i) \mid \mathbf{X}_i, \texttt{airbnb\_count}_{i,r}\right] = \alpha_\tau + \beta_\tau \cdot \texttt{airbnb\_count}_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma}_\tau + \sum_{c} \delta_{c,\tau} \cdot \mathbf{1}[\text{city}_i = c],
66 + Q_{\tau}\!\left[\ln(\text{rent}_i) \mid A_{i,r}, \mathbf{X}_i, c(i)\right] = \alpha_\tau + \beta_\tau\, A_{i,r} + \mathbf{X}_i' \boldsymbol{\gamma}_\tau + \delta_{c(i),\tau},
66 67 \end{equation}
68 +for $\tau \in \{0.10, 0.25, 0.50, 0.75, 0.90\}$ and on a finer grid for the figure. To keep the linear-programming problem well conditioned, the city fixed effects are restricted to the five largest cities with the remainder grouped; the companion OLS column uses the same fixed effects. The coefficient $\beta_\tau$ is the marginal association between exposure and the $\tau$th conditional quantile of log rent. Standard errors are the kernel-based asymptotic estimates implemented in \texttt{statsmodels} (Appendix~\ref{app:methods}).
67 69
68 −\noindent for quantile indices $\tau \in \{0.10, 0.25, 0.50, 0.75, 0.90\}$. City fixed effects are restricted to the five largest cities (with the remainder grouped) to keep the quantile estimation well conditioned. The quantile-specific coefficient $\beta_\tau$ measures the marginal association between Airbnb exposure and the $\tau$th quantile of log rent. If the effect of Airbnb is larger at the upper tail of the distribution, this may indicate that short-term rental activity disproportionately affects higher-quality or higher-rent segments of the market. Standard errors are the asymptotic kernel-based estimates of \citet{koenker1978regression} as implemented in \texttt{statsmodels}.
69 −
70 −\subsection{Model 6: Machine-Learning Robustness}\label{sec:model6}
71 −
72 −We complement the parametric analysis with four machine-learning methods: the LASSO \citep{tibshirani1996regression}, the elastic net \citep{zou2005regularization}, random forests \citep{breiman2001random}, and gradient boosting \citep{friedman2001greedy}, alongside an OLS benchmark; all are implemented in scikit-learn \citep{pedregosa2011scikit}. These models are trained to predict $\ln(\text{rent}_i)$ from the Airbnb exposure measures at the 500\,m radius (count, density, mean price, entire-home share), dwelling characteristics (bedrooms, bathrooms), and geographic coordinates, and are evaluated on a held-out test set (20\% of the sample) using root mean squared error (RMSE), mean absolute error (MAE), and $R^2$.
73 −
74 −The machine-learning models serve three purposes. First, they provide a benchmark for the predictive accuracy of the hedonic model: if the OLS model achieves comparable $R^2$ to the flexible ML models, this suggests that the linear specification is not severely misspecified. Second, LASSO and elastic net coefficients reveal which variables are selected as predictors, providing a data-driven assessment of the importance of Airbnb exposure relative to dwelling characteristics. Third, random forest and gradient boosting models yield variable-importance measures (SHAP values) that quantify the contribution of each feature to predictive accuracy, without imposing functional-form assumptions.
70 +\subsection{Model 6: Machine-Learning Benchmark}\label{sec:model6}
75 71
76 −\subsection{Identification and Endogeneity}\label{sec:identification}
72 +We complement the parametric analysis with the LASSO \citep{tibshirani1996regression}, the elastic net \citep{zou2005regularization}, random forests \citep{breiman2001random} and gradient boosting \citep{friedman2001greedy}, alongside OLS, all implemented in scikit-learn \citep{pedregosa2011scikit}. The models predict $\ln(\text{rent}_i)$ from the 500\,m exposure measures (count, density, mean nearby price, entire-home share), bedrooms, bathrooms and the geographic coordinates; because two of the exposure measures are undefined for listings without nearby Airbnb, the sample is the 4{,}370 listings with positive 500\,m exposure. Performance is evaluated in two ways. First, on a random 80/20 hold-out split, as in the original design. Second, by five-fold cross-validation under two fold designs: random folds, and spatially blocked folds in which whole FSAs are assigned to folds so that no test listing shares a neighbourhood with a training listing. The difference between the two designs measures how much of a learner's apparent accuracy comes from interpolating the rent levels of nearby training listings rather than from generalisable structure \citep{mullainathan2017machine}. SHAP values \citep{lundberg2017unified} computed on the hold-out set describe the contribution of each feature to the gradient-boosting predictions.
77 73
78 −We are explicit about the identification challenges inherent in our cross-sectional design. The primary concern is that Airbnb listing density is endogenous to local rent levels and neighbourhood desirability. Three channels of endogeneity are relevant:
74 +\subsection{Identification}\label{sec:identification}
79 75
80 −\begin{enumerate}[label=(\roman*)]
81 − \item \textbf{Reverse causality:} High rents may attract Airbnb hosts (because the opportunity cost of leaving a unit vacant is high, and short-term rental income can offset high carrying costs), creating a positive bias in the estimated $\hat{\beta}$.
82 − \item \textbf{Omitted variables:} Neighbourhood amenities---such as proximity to cultural attractions, restaurants, and transit---that are unobserved in our data may simultaneously attract Airbnb guests and drive up residential rents, again biasing $\hat{\beta}$ upward.
83 − \item \textbf{Spatial sorting:} Airbnb hosts may select locations based on unobserved characteristics (e.g., architectural charm, noise tolerance norms) that also affect residential rents.
84 −\end{enumerate}
76 +We are explicit about what the cross-sectional design can identify. Three channels make Airbnb exposure endogenous in Equation~\eqref{eq:hedonic_rent}. Reverse causality: high rents may attract hosts, because the opportunity cost of a vacant unit is high and STR income can offset carrying costs. Omitted neighbourhood amenities: proximity to attractions, restaurants and transit raises both tourist demand and residential rents. Spatial sorting: hosts may select locations on unobserved characteristics, such as architectural character, that also raise rents. All three channels bias $\hat\beta$ upward. The quasi-experimental literature addresses them with regulatory shocks or instruments \citep{koster2021short, barron2021effect, garcia2020airbnb, duso2024airbnb}; neither is available in a single cross-section of listings.
85 77
86 −Our city fixed effects control for all time-invariant, city-level confounders, including differences in local housing-market tightness, tourism infrastructure, and regulatory regimes. Within-city variation in Airbnb density is our identifying variation, and this variation is plausibly driven by both locational amenities (tourist attractiveness) and the supply of suitable housing units---neither of which is fully exogenous. We therefore interpret our estimates as conditional correlations rather than causal effects. The inclusion of spatial lags, robustness checks across buffer radii, and machine-learning diagnostics provides indirect evidence on the plausibility and stability of our estimates, but a definitive causal statement would require either panel data with suitable fixed effects or a credible instrument for Airbnb supply---neither of which is available in our setting.
78 +Our strategy is instead to make the identification problem measurable. City fixed effects remove city-level confounders; FSA fixed effects additionally remove neighbourhood-level confounders that are constant within a postal-code zone, leaving within-neighbourhood variation that is closer to, though still not, the variation exploited by quasi-experimental designs. The remaining threat under FSA fixed effects is block-level sorting within neighbourhoods, which the spatial error model partly addresses and which we cannot rule out. We therefore interpret the city-fixed-effects estimate as an upper bound on any causal effect, the FSA-fixed-effects estimate as the closest the data come to a within-neighbourhood comparison, and both as conditional associations rather than causal effects.
87 79
88 −\subsection{Standard Errors}
80 +\subsection{Standard Errors}\label{sec:inference}
89 81
90 −Throughout the analysis, we report heteroskedasticity-robust standard errors (HC1) as our baseline; Section~\ref{sec:robustness} re-computes the preferred specification with standard errors clustered at the city level. For the quantile regressions, we report the asymptotic standard errors produced by the kernel-based estimator in \texttt{statsmodels}. For the machine-learning models, we report held-out test-set performance metrics, with regularisation parameters selected by 5-fold cross-validation.
82 +The exposure variable is a spatial moving average and the error term is spatially correlated (Table~\ref{tab:spatial_results} reports $\hat\lambda \approx 0.54$), so the independence assumption underlying heteroskedasticity-robust standard errors fails. We report four alternatives for the key coefficient. HC1 standard errors are the baseline, for comparability with the original analysis and with most of the cross-sectional literature. Cluster-robust standard errors by city \citep{cameron2015practitioner} allow arbitrary dependence within cities, but Montreal contains 59\% of the sample, and cluster-robust inference is unreliable when one cluster dominates; we therefore also cluster by FSA, which yields several hundred more balanced clusters. Finally, the Conley \citeyearpar{conley1999gmm} spatial HAC estimator weights the cross-products of scores for pairs of listings by a Bartlett kernel $K(d_{ik}) = \max\{0,\, 1 - d_{ik}/\bar d\}$ of their great-circle distance, with cutoffs $\bar d$ of 1, 2, 5 and 10\,km \citep{kelejian2007hac}; it imposes no partition and lets dependence decline smoothly with distance. For the quantile regressions we report the asymptotic kernel-based standard errors, and for the machine-learning models held-out performance with regularisation parameters chosen by five-fold cross-validation.
modified paper/sections/05_results.tex +81 −54
@@ -4,11 +4,11 @@
4 4 % =============================================================================
5 5 \section{Results}\label{sec:results}
6 6
7 −This section presents the empirical results for each of the six models described in Section~\ref{sec:methodology}. Throughout, we use cautious language to reflect the conditional nature of our estimates: the terms ``associated with'' and ``conditional correlation'' are used in place of ``effect'' or ``impact,'' consistent with the limitations of our cross-sectional identification strategy.
7 +This section presents the estimates in the order of the identification argument: the baseline hedonic rent model with city fixed effects, the neighbourhood-fixed-effects estimates, the comparison of standard errors, the spatial models and their impacts, the quantile regressions, the Airbnb pricing and city-level models, and the machine-learning benchmark. Throughout, we describe estimates as conditional associations; the terms ``effect'' and ``impact'' are used only in their technical spatial-econometric sense.
8 8
9 −\subsection{Baseline Hedonic Rent Model}
9 +\subsection{Baseline Hedonic Rent Model}\label{sec:results_baseline}
10 10
11 −Table~\ref{tab:hedonic_rent} reports the OLS estimates of the hedonic rent model (Equation~\ref{eq:hedonic_rent}). Column~(1a) presents the bivariate specification with only the Airbnb count within 500\,m; column~(1b) adds dwelling controls (bedrooms, bathrooms, building type); and column~(1c)---our preferred specification---adds city fixed effects. Columns~(1d) and~(1e) replace the Airbnb count with two alternative exposure measures, the Airbnb density and the share of entire-home listings within the buffer.
11 +Table~\ref{tab:hedonic_rent} reports OLS estimates of Equation~\eqref{eq:hedonic_rent}. Column (1a) is the bivariate regression of log rent on the 500\,m Airbnb count; column (1b) adds bedrooms, bathrooms and building type; column (1c), the reference specification, adds city fixed effects; columns (1d) and (1e) replace the count with the Airbnb density and with the entire-home share within the buffer.
12 12
13 13 \begin{table}[htbp]
14 14 \centering
@@ -17,75 +17,71 @@ Table~\ref{tab:hedonic_rent} reports the OLS estimates of the hedonic rent model
17 17 \input{../results/tables/hedonic_rent_baseline.tex}
18 18 \end{table}
19 19
20 −The coefficient on $\texttt{airbnb\_count\_500m}$ is positive and statistically significant across all specifications. In the preferred specification (column~1c), each additional Airbnb listing within 500\,m is associated with an approximate 0.4\% increase in monthly rent, holding dwelling characteristics and city constant. This semi-elasticity is economically modest but statistically robust: at the median monthly rent of approximately \$1{,}950, one additional nearby Airbnb listing corresponds to a rent differential of roughly \$6--\$10 per month. However, the practical significance compounds when one considers that many urban rental listings have 10 or more Airbnb listings within 500\,m, implying cumulative differentials that are economically meaningful.
20 +The coefficient on the 500\,m count is positive and statistically significant in columns (1a)--(1d). In the reference specification each additional Airbnb listing within 500\,m is associated with a monthly rent approximately 0.39\% higher ($\hat\beta = 0.0039$, HC1 standard error 0.0002), holding dwelling characteristics and city constant; at the median rent of \$1{,}950 this is about \$8 per month per listing, and one standard deviation of the count (14.2 listings) corresponds to about 5.5\%. The coefficient moves substantially across control sets: it is 0.0020 without controls, 0.0048 with dwelling controls and 0.0039 with city fixed effects. The rise from (1a) to (1b) reflects the negative correlation between Airbnb density and unit size documented in Appendix Table~\ref{tab:correlation}: dense, Airbnb-rich neighbourhoods have smaller units, so the bivariate coefficient understates the conditional association. The fall from (1b) to (1c) reflects the opposite force at the city level, since cities with many Airbnb listings also have higher rents for reasons unrelated to STR activity. Both movements are large relative to the coefficient, which already signals that the estimate is sensitive to the set of location controls, a point Section~\ref{sec:results_fsa} develops.
21 21
22 −Among the control variables, dwelling size is the dominant predictor of rent: each additional bedroom is associated with approximately 11--13\% higher rent, and each additional bathroom with approximately 23--30\% higher rent. Building type (House and Row/Townhouse relative to Apartment) also enters significantly. City fixed effects raise the explanatory power of the model considerably, confirming substantial cross-city variation in rent levels.
22 +Among the controls, dwelling size dominates: each additional bedroom is associated with 12--14\% higher rent and each additional bathroom with 26--30\% higher rent in columns (1b)--(1d) (exact percentages, $100(e^{\hat\gamma}-1)$). Houses rent for about 9\% more and row houses for about 10\% more than apartments in column (1c). City fixed effects raise the $R^2$ from 0.47 to 0.57, confirming substantial cross-city variation in rent levels; the adjusted $R^2$ of 0.56 leaves a considerable residual, consistent with unobserved unit quality and micro-location. The density coefficient in column (1d) is the count coefficient rescaled by the buffer area and carries the same information. The entire-home share in column (1e) is small, negative and insignificant; this column is estimated on the 4{,}370 listings with at least one Airbnb within 500\,m, for which the share is defined, and compares the composition of nearby STR supply conditional on its presence.
23 23
24 −The adjusted $R^2$ of the preferred specification is approximately 0.56, indicating that observed dwelling characteristics and city fixed effects explain a substantial share of the cross-sectional variation in rents, though a considerable residual remains, consistent with the importance of unobserved unit-specific and micro-locational factors.
24 +\subsection{Neighbourhood Fixed Effects}\label{sec:results_fsa}
25 25
26 −\subsection{Hedonic Airbnb Pricing Model}
27 −
28 −Table~\ref{tab:hedonic_airbnb} reports the estimates of the Airbnb pricing model (Equation~\ref{eq:hedonic_airbnb}).
26 +Table~\ref{tab:neighbourhood_fe} replaces city fixed effects with FSA fixed effects (Equation~\ref{eq:hedonic_fsa}). Column (F1) re-estimates the reference specification with the fixed effects absorbed and singleton cities dropped, and reproduces the coefficient of 0.0039 on a sample of 7{,}860 listings in 187 cities. Column (F2) uses fixed effects for 289 FSAs. The $R^2$ rises from 0.56 to 0.63, and the coefficient on the 500\,m count falls to 0.0008 (HC1 standard error 0.0004), about one fifth of the city-fixed-effects estimate. At the median rent this is \$1.6 per month per listing; one standard deviation of the count corresponds to 1.2\%, and one within-FSA standard deviation (7.2 listings) to 0.6\%.
29 27
30 28 \begin{table}[htbp]
31 29 \centering
32 − \caption{Hedonic Airbnb Pricing Model --- OLS Results}
33 − \label{tab:hedonic_airbnb}
34 − \input{../results/tables/hedonic_airbnb_pricing.tex}
30 + \caption{Neighbourhood (FSA) Fixed Effects --- Hedonic Rent Model}
31 + \label{tab:neighbourhood_fe}
32 + \footnotesize\setlength{\tabcolsep}{4pt}
33 + \input{../results/tables/neighbourhood_fe.tex}
35 34 \end{table}
36 35
37 −Contrary to the opportunity-cost hypothesis, the city-level mean rent does not enter significantly in any specification: the coefficient $\hat{\theta}$ is small and statistically indistinguishable from zero, with a negative point estimate in columns~(2a) and~(2b) and a positive one in column~(2c). Airbnb nightly prices in our sample are therefore not systematically higher in higher-rent cities once listing characteristics are taken into account; the pricing of short-term rentals appears to be driven primarily by the properties of the listing itself rather than by conditions in the local long-term rental market.
38 −
39 −Among the listing-level controls, dwelling size matters most: bedrooms and, especially, bathrooms are associated with significantly higher nightly prices, in line with the STR pricing literature \citep{wang2017price, gibbs2018pricing}. Superhost status carries a significant \textit{negative} coefficient---a notable departure from the positive reputation premia typically reported \citep{wang2017price, ert2016trust}---which likely reflects composition effects: superhosts in our Quebec sample are concentrated in more modest, high-volume urban units rather than in the luxury chalet segment, and guest capacity enters negatively once size is controlled for. The entire-home indicator is positive and significant once city fixed effects are included (column~2c), consistent with whole units commanding a premium over rooms in shared dwellings within the same market \citep{gibbs2018pricing}.
36 +The remaining columns show that this attenuation is not specific to the linear 500\,m count. The 250\,m count, the most local exposure measure and the one with the largest city-fixed-effects coefficient (Section~\ref{sec:robustness_buffer}), has a within-FSA coefficient of 0.0008 with a standard error of 0.0009 (column F3). Decomposing exposure into an extensive and an intensive margin (column F4) yields a negative and significant coefficient on the indicator for any Airbnb within 500\,m ($-0.028$) and a count coefficient of 0.0010: within a neighbourhood, rental listings with at least one Airbnb nearby rent for about 2.8\% less than otherwise comparable listings with none, and the intensive-margin association is small. The logarithmic exposure measure (column F5) has a coefficient of 0.002 with a standard error of 0.005, against 0.048 with city fixed effects (Table~\ref{tab:extended_robustness}). Adding interior size on the subsample that reports it (column F6) reduces the count coefficient to 0.0003 with a standard error of 0.0006.
40 37
41 −When city fixed effects are included, the listing-level coefficients retain their signs and broad magnitudes, suggesting that the within-city pricing structure of Airbnb listings is largely independent of the cross-city rent variation.
38 +Three readings of these results are possible, and the data do not distinguish them. The first is that the city-fixed-effects association is driven by neighbourhood-level sorting: Airbnb supply concentrates in neighbourhoods that command high rents for reasons unrelated to STR activity, and comparing listings within neighbourhoods removes this confound along with most of the association. The second is that STR-induced rent pressure operates at the neighbourhood rather than the block scale, so that fixed effects at the FSA level absorb the effect itself; this reading requires that supply withdrawal within a neighbourhood raise rents uniformly across its blocks, which is possible but leaves the between-neighbourhood estimate exposed to the first reading. The third is attenuation from measurement error, which is more severe within neighbourhoods where the signal-to-noise ratio of the exposure count is lower; given that a quarter of the variance of the count is within FSAs, this can explain part but not all of a fivefold reduction. Under any reading, the city-fixed-effects estimate is an upper bound on the within-neighbourhood association, and it is the within-neighbourhood association that corresponds most closely to the variation exploited by quasi-experimental studies. The negative extensive-margin coefficient in column (F4) is consistent with the first reading: within neighbourhoods, Airbnb listings cluster on blocks with commercial frontage or less residential character, which rent for less.
42 39
43 −\subsection{City-Level Results}
40 +\subsection{Inference under Spatial Dependence}\label{sec:results_inference}
44 41
45 −Table~\ref{tab:city_level} presents the city-level regressions (Equations~\ref{eq:city_rent} and~\ref{eq:city_airbnb}).
42 +Table~\ref{tab:inference} reports, for the city- and FSA-fixed-effects estimates of the 500\,m coefficient, the HC1 standard error, cluster-robust standard errors by city and by FSA, and Conley spatial HAC standard errors at cutoffs of 1, 2, 5 and 10\,km.
46 43
47 44 \begin{table}[htbp]
48 45 \centering
49 − \caption{City-Level Regressions}
50 − \label{tab:city_level}
51 − \input{../results/tables/city_level_interaction.tex}
46 + \caption{Alternative Standard Errors for the Airbnb Coefficient}
47 + \label{tab:inference}
48 + \footnotesize\setlength{\tabcolsep}{3pt}
49 + \input{../results/tables/inference_comparison.tex}
52 50 \end{table}
53 51
54 −The forward regression shows a positive and statistically significant---though economically small---cross-city association between the total number of Airbnb listings and mean log rents: cities with more Airbnb listings tend to have somewhat higher average rents, conditional on average dwelling size. The reverse regression, by contrast, has essentially no explanatory power ($R^2 = 0.01$), and mean rent does not significantly predict city-level Airbnb counts. Although the aggregation yields 153 city-level observations, most cities contribute only a handful of underlying listings, which limits the statistical power of these regressions and amplifies the influence of individual city outliers. We interpret these results as descriptive patterns that motivate the listing-level analysis rather than as evidence of a causal relationship.
52 +For the city-fixed-effects estimate the HC1 standard error is 0.0002 and the $t$-statistic 17. Clustering by city reduces the standard error to 0.0001 and raises the $t$-statistic to 36, an implausible tightening that illustrates the unreliability of cluster-robust inference when one cluster (Montreal) contains 59\% of the observations \citep{cameron2015practitioner}; we do not rely on it. Clustering by FSA and the Conley estimator at every cutoff agree closely: the standard error is 0.0007, three to three and a half times the HC1 value, and the $t$-statistic falls to between 5 and 6. The city-fixed-effects association is therefore statistically robust to spatial dependence, but conventional heteroskedasticity-robust errors overstate its precision by a factor of about three, and the same is likely true of cross-sectional STR--rent estimates elsewhere that report robust standard errors on buffer-based exposure measures. For the FSA-fixed-effects estimate the HC1 $t$-statistic of 2.3 falls to 1.1--1.2 with FSA-clustered or short-range Conley standard errors and to 1.7--2.0 at the 5 and 10\,km cutoffs. The within-neighbourhood association is thus marginal at best, and we describe it below as not statistically distinguishable from zero under spatial inference.
55 53
56 −\subsection{Spatial Model Results}
54 +\subsection{Spatial Lag and Spatial Error Models}\label{sec:results_spatial}
57 55
58 −Table~\ref{tab:spatial_results} reports the OLS baseline alongside the spatial lag (SAR) and spatial error (SEM) models of Equation~\ref{eq:spatial_lag}.
56 +Table~\ref{tab:spatial_results} reports OLS, SAR and SEM estimates of Equation~\eqref{eq:spatial_lag}, all with fixed effects for the fifteen largest cities, and Table~\ref{tab:spatial_impacts} the direct, indirect and total impacts implied by the SAR estimates (Equation~\ref{eq:impacts}).
59 57
60 58 \begin{table}[htbp]
61 59 \centering
62 60 \caption{Spatial Regression Models}
63 61 \label{tab:spatial_results}
62 + \small
64 63 \input{../results/tables/spatial_models.tex}
65 64 \end{table}
66 65
67 −The spatial autoregressive coefficient ($\hat{\rho}$, the coefficient on $W \cdot \ln(\text{rent})$) is positive and strongly significant, and the spatial error parameter $\hat{\lambda}$ in the SEM is large (0.54), confirming substantial spatial dependence in rents: the rents of nearby listings carry systematic information about a given listing's rent, even after controlling for dwelling characteristics and city fixed effects. This finding is consistent with the large literature on spatial autocorrelation in housing markets.
68 −
69 −Importantly, the coefficient on $\texttt{airbnb\_count\_500m}$ ($\hat{\beta}'$) remains positive and statistically significant in both spatial specifications: it is mildly attenuated in the SAR model (0.0034 versus 0.0038 in the OLS baseline) and essentially unchanged in the SEM. The mild attenuation is expected: to the extent that the Airbnb coefficient in the baseline model partly reflected spatially correlated omitted variables (captured by the spatial terms), the spatial models provide more conservative estimates. The persistence of a significant positive association strengthens confidence that the Airbnb--rent correlation is not solely an artefact of spatial confounding.
70 −
71 −Figure~\ref{fig:buffer_decay} illustrates the spatial decay of the Airbnb coefficient across buffer radii.
72 −
73 −\begin{figure}[htbp]
66 +\begin{table}[htbp]
74 67 \centering
75 − \includegraphics[width=0.75\textwidth]{coefficient_buffer_comparison.pdf}
76 − \caption{Estimated Airbnb Coefficient by Buffer Radius}
77 − \label{fig:buffer_decay}
78 −\end{figure}
68 + \caption{Average Direct, Indirect and Total Impacts in the SAR Model}
69 + \label{tab:spatial_impacts}
70 + \small
71 + \input{../results/tables/spatial_impacts.tex}
72 +\end{table}
73 +
74 +Spatial dependence is substantial. The spatial autoregressive parameter is $\hat\rho = 0.134$ (standard error 0.022) and the spatial error parameter $\hat\lambda = 0.544$: the rents of the five nearest listings carry systematic information about a listing's rent after controlling for its characteristics and city, and the disturbances are strongly spatially correlated, which is the dependence that the Conley standard errors above account for. The coefficient on the 500\,m count is 0.0034 in the SAR model and 0.0039 in the SEM, against 0.0038 by OLS on the same sample. The SAR coefficient is not comparable to the OLS coefficient without the spatial multiplier: the average direct impact is 0.0034, the indirect impact 0.0005 and the total impact 0.0040 (standard error 0.0002), so that once feedback through neighbouring rents is included the SAR model implies the same marginal association as OLS. With a five-nearest-neighbour weights matrix the multiplier is modest ($n^{-1}\mathrm{tr}[(\mathbf{I}-\hat\rho\mathbf{W})^{-1}] = 1.003$, $1/(1-\hat\rho) = 1.155$), so direct impacts nearly coincide with coefficients and indirect impacts are about 13\% of the total. The SEM estimate is essentially the OLS estimate with a larger standard error (0.0004), which is the expected consequence of modelling the error correlation.
79 75
80 −The per-listing coefficient is largest at the 250\,m radius and declines monotonically as the buffer expands, consistent with a localised association between Airbnb activity and rents. At the 2\,km radius, the coefficient remains positive but is substantially smaller in magnitude, reflecting the dilution of the Airbnb signal over a larger geographic area. This spatial decay pattern is consistent with prior findings in the literature and suggests that the Airbnb--rent association operates at a highly localised scale.
76 +These results qualify, rather than contradict, the neighbourhood-fixed-effects findings. Spatial lag and error processes defined on the five nearest listings operate at the scale of a block, and conditioning on them leaves the Airbnb coefficient intact; fixed effects defined at the scale of a postal-code neighbourhood remove most of it. The unobservables correlated with Airbnb exposure therefore vary across neighbourhoods more than across adjacent blocks, which is what one expects of tourist amenities and neighbourhood reputation.
81 77
82 −\subsection{Quantile Regression Results}
78 +\subsection{Quantile Regression Results}\label{sec:results_quantile}
83 79
84 −Table~\ref{tab:quantile} and Figure~\ref{fig:quantile_plot} present the quantile regression estimates of $\beta_\tau$ for $\tau \in \{0.10, 0.25, 0.50, 0.75, 0.90\}$.
80 +Table~\ref{tab:quantile} and Figure~\ref{fig:quantile_plot} report the quantile regression estimates of $\beta_\tau$ (Equation~\ref{eq:quantile}) with fixed effects for the five largest cities.
85 81
86 82 \begin{table}[htbp]
87 83 \centering
88 − \caption{Quantile Regression Results --- Coefficient on Airbnb Count (500m)}
84 + \caption{Quantile Regression Results --- Coefficient on the Airbnb Count (500\,m)}
89 85 \label{tab:quantile}
90 86 \small\setlength{\tabcolsep}{4pt}
91 87 \input{../results/tables/quantile_regression.tex}
@@ -94,45 +90,76 @@ Table~\ref{tab:quantile} and Figure~\ref{fig:quantile_plot} present the quantile
94 90 \begin{figure}[htbp]
95 91 \centering
96 92 \includegraphics[width=0.75\textwidth]{quantile_coefficients.pdf}
97 − \caption{Quantile Regression Coefficients on Airbnb Count (500m) with 95\% Confidence Intervals}
93 + \caption{Quantile Regression Coefficients on the Airbnb Count (500\,m) with 95\% Confidence Intervals}
98 94 \label{fig:quantile_plot}
99 95 \end{figure}
100 96
101 −The quantile regression results reveal meaningful heterogeneity in the Airbnb--rent association across the conditional rent distribution. The coefficient is positive and statistically significant at every quantile considered. It is roughly flat over the lower half of the distribution (0.0037 at $\tau = 0.10$, 0.0034--0.0035 at $\tau = 0.25$ and $\tau = 0.50$) and then rises in the upper tail, reaching 0.0041 at $\tau = 0.75$ and its largest value, 0.0047, at $\tau = 0.90$---roughly 25\% above the OLS estimate.
97 +The coefficient is positive at every quantile. It is roughly flat over the lower half of the distribution (0.0037 at $\tau=0.10$, 0.0034--0.0035 at $\tau=0.25$ and $\tau=0.50$) and rises in the upper tail to 0.0041 at $\tau=0.75$ and 0.0047 at $\tau=0.90$, about 25\% above the OLS estimate of 0.0038 on the same specification. The standard errors (0.0002--0.0003) are of the kernel-based asymptotic type and, like HC1, do not account for spatial dependence; the differences between quantiles are modest relative to the sampling uncertainty that Table~\ref{tab:inference} suggests, and we have not tested them formally. Taken at face value, the pattern indicates that the association is strongest in the upper segment of the rental market, where listings are located in the desirable neighbourhoods in which STR activity is also most intense \citep{zietz2008determinants, mcmillen2008changes}. Because these regressions condition only on coarse city groups, the quantile pattern inherits the between-neighbourhood character of the mean estimate; quantile regressions with FSA fixed effects would require penalised fixed-effects methods given the number of groups and are left for future work.
102 98
103 −This pattern is economically interpretable. High-rent listings---typically located in desirable neighbourhoods with strong tourist appeal---are precisely the locations where Airbnb activity is most intense and where the supply-withdrawal mechanism is most plausible. The finding that implicit prices vary across the conditional distribution echoes the broader hedonic evidence \citep{zietz2008determinants, mcmillen2008changes}, and extends it to STR exposure: the association between Airbnb and rents, while present throughout the distribution, is strongest in the upper segment of the rental market.
99 +\subsection{Hedonic Airbnb Pricing Model}\label{sec:results_airbnb_pricing}
104 100
105 −\subsection{Machine-Learning Robustness}
101 +Table~\ref{tab:hedonic_airbnb} reports the Airbnb pricing model (Equation~\ref{eq:hedonic_airbnb}). Columns (2a)--(2c) use the 2{,}437 listings with a matched city; columns (2d)--(2e) restrict the sample to the 1{,}699 listings priced at or below \$1{,}000 per night (Section~\ref{sec:data_airbnb}). Columns (2c) and (2e) include city fixed effects, which absorb the city mean rent.
106 102
107 −Table~\ref{tab:ml_performance} reports the out-of-sample predictive performance of the four machine-learning models alongside the OLS benchmark.
103 +\begin{table}[htbp]
104 + \centering
105 + \caption{Hedonic Airbnb Pricing Model --- OLS Results}
106 + \label{tab:hedonic_airbnb}
107 + \setlength{\tabcolsep}{3pt}
108 + \input{../results/tables/hedonic_airbnb_pricing.tex}
109 +\end{table}
110 +
111 +The city mean log rent does not enter significantly in any specification: the elasticity $\hat\theta$ is $-0.03$ and $-0.05$ in columns (2a) and (2b), with standard errors above 0.11, and $0.003$ (standard error 0.05) in the restricted sample. Airbnb nightly prices are not systematically higher in higher-rent cities once listing characteristics are taken into account, so the data offer no support for a simple opportunity-cost pricing channel at the city level. Part of the explanation is composition: the cross-city variation in Airbnb prices is dominated by resort municipalities with high nightly prices and few or inexpensive long-term rentals.
112 +
113 +The listing-level coefficients depend on the sample in a way that illustrates the price-field problem. On the full sample, explanatory power is very low ($R^2$ of 0.03 without and 0.14 with city fixed effects), guest capacity enters negatively, the amenities count is insignificant, and superhost status carries a large negative coefficient ($-0.35$ and $-0.28$), a discount of about 25--30\% that contradicts the positive reputation premia found by \citet{wang2017price}, \citet{ert2016trust} and \citet{gibbs2018pricing}. On the restricted sample the picture is conventional: the $R^2$ rises to 0.21 and 0.30, bedrooms and bathrooms carry premia of about 15--16\% each, each additional amenity adds about 0.3\%, the entire-home indicator carries a 14.7\% premium within cities ($e^{0.137}-1$), and the superhost coefficient is small, positive and insignificant. The superhost discount in the full sample is therefore an artefact of the bimodal price field, in which urban rental units operated by superhosts are more often recorded with plausible nightly prices while large chalets appear with multi-night totals, and not evidence of a Quebec-specific pricing pattern. We regard the restricted-sample estimates as the credible ones and note that even their explanatory power is below that of hedonic Airbnb models estimated on platform data with reliable prices and room types.
114 +
115 +\subsection{City-Level Results}\label{sec:results_city}
116 +
117 +Table~\ref{tab:city_level} presents the city-level regressions (Equations~\ref{eq:city_rent} and~\ref{eq:city_airbnb}) on the 153 cities with Airbnb listings.
118 +
119 +\begin{table}[htbp]
120 + \centering
121 + \caption{City-Level Regressions}
122 + \label{tab:city_level}
123 + \small
124 + \input{../results/tables/city_level_interaction.tex}
125 +\end{table}
126 +
127 +The forward regression shows a positive and statistically significant but small cross-city association: one hundred additional Airbnb listings in a city are associated with a mean log rent about 1\% higher, conditional on average dwelling size. The reverse regression has no explanatory power ($R^2 = 0.01$) and the mean rent does not predict the city's Airbnb count. Most of the 153 cities contribute few listings to either data set, so these regressions are descriptive and serve only to motivate the listing-level analysis.
128 +
129 +\subsection{Machine-Learning Benchmark}\label{sec:results_ml}
130 +
131 +Table~\ref{tab:ml_performance} reports hold-out performance on a random 80/20 split for the five models, estimated on the 4{,}370 listings with positive 500\,m exposure, and Table~\ref{tab:ml_spatial_cv} the five-fold cross-validation results under random and spatially blocked folds.
108 132
109 133 \begin{table}[htbp]
110 134 \centering
111 − \caption{Machine-Learning Model Performance (Test Set)}
135 + \caption{Machine-Learning Model Performance (Random Hold-Out Test Set)}
112 136 \label{tab:ml_performance}
137 + \small
113 138 \input{../results/tables/ml_comparison.tex}
114 139 \end{table}
115 140
116 −The random forest achieves the highest $R^2$ on the test set (0.71), closely followed by gradient boosting (0.69); the regularised linear models (LASSO and elastic net) perform essentially on par with OLS (test $R^2 \approx 0.51$). The gap between the tree-based and linear models indicates that nonlinear relationships and interactions among covariates---most plausibly involving the geographic coordinates---contribute meaningfully to rent variation beyond what the linear hedonic model captures. The linear specification nevertheless accounts for the bulk of the explainable variation and remains a reasonable approximation for inference on the Airbnb exposure coefficient.
141 +\begin{table}[htbp]
142 + \centering
143 + \caption{Random versus Spatially Blocked Cross-Validation}
144 + \label{tab:ml_spatial_cv}
145 + \small
146 + \input{../results/tables/ml_spatial_cv.tex}
147 +\end{table}
117 148
118 −Figure~\ref{fig:feature_importance} displays the mean absolute SHAP values from the gradient boosting model.
149 +On the random hold-out split the random forest attains the highest test $R^2$ (0.71), followed by gradient boosting (0.69); the regularised linear models perform on par with OLS (0.51), and the LASSO retains the Airbnb count with a positive coefficient. Taken alone, the gap of twenty percentage points would suggest important nonlinearities. The spatially blocked cross-validation shows that the gap is an artefact of the fold design. Under random folds the tree-based models again outperform the linear models (cross-validated $R^2$ of 0.65 against 0.48). When whole FSAs are held out, so that the learners cannot draw on training listings in the test neighbourhoods, the linear models are essentially unchanged (0.47) while the random forest and gradient boosting fall to 0.43 and 0.41, below OLS and with much larger variability across folds. With coordinates among the features, the tree-based learners were reconstructing neighbourhood rent levels from the locations of nearby training listings; they do not generalise to unseen neighbourhoods better than a linear hedonic model. This is the prediction counterpart of the fixed-effects result: the structure that flexible learners exploit, and that the city-fixed-effects regression attributes to Airbnb exposure, is neighbourhood-level variation in rent.
119 150
120 151 \begin{figure}[htbp]
121 152 \centering
122 153 \includegraphics[width=0.80\textwidth]{feature_importance.pdf}
123 − \caption{Feature Importance from Gradient Boosting Model}
154 + \caption{Mean Absolute SHAP Values, Gradient Boosting Model (Random Hold-Out Set)}
124 155 \label{fig:feature_importance}
125 156 \end{figure}
126 157
127 −Dwelling characteristics (bathrooms, bedrooms) and geographic coordinates are consistently the most important predictors of rent. The Airbnb exposure variables---mean nearby price, density, count, and entire-home share---each rank as moderately important features and jointly account for a non-trivial share of predictive power, confirming that Airbnb exposure carries information beyond what is captured by dwelling size and raw location. The LASSO and elastic net models retain the Airbnb count variable with a positive coefficient, consistent with the OLS results.
128 −
129 −Figure~\ref{fig:shap_summary} presents a SHAP summary plot, providing a more granular view of how each feature contributes to individual predictions.
130 −
131 158 \begin{figure}[htbp]
132 159 \centering
133 160 \includegraphics[width=0.80\textwidth]{shap_summary.pdf}
134 − \caption{SHAP Summary Plot from Gradient Boosting Model}
161 + \caption{SHAP Summary Plot, Gradient Boosting Model (Random Hold-Out Set)}
135 162 \label{fig:shap_summary}
136 163 \end{figure}
137 164
138 −The SHAP analysis confirms that higher Airbnb counts are associated with positive contributions to predicted rent, consistent with the parametric results. The distribution of SHAP values for the Airbnb count variable shows a rightward shift for listings with high Airbnb exposure, reinforcing the finding that nearby short-term rental activity is associated with higher rents.
165 +Figures~\ref{fig:feature_importance} and~\ref{fig:shap_summary} describe the gradient-boosting model fitted on the random split. Bathrooms, the geographic coordinates and bedrooms are the most important features; the exposure variables rank below them, and higher Airbnb counts contribute positively to predicted rents, consistent with the parametric estimates on the same (city-level) variation. Given the cross-validation results, the prominence of the coordinates should be read as the model's way of encoding neighbourhood rent levels, and the SHAP attributions as descriptions of the fitted model rather than as evidence about mechanisms.
modified paper/sections/06_robustness.tex +27 −44
@@ -4,120 +4,103 @@
4 4 % =============================================================================
5 5 \section{Robustness Checks}\label{sec:robustness}
6 6
7 −This section presents a battery of robustness tests designed to assess the sensitivity of our baseline estimates to alternative specifications, sample definitions, and exposure measures.
7 +This section assesses the sensitivity of the city-fixed-effects estimate to the buffer radius, the exposure measure, the sample, outliers, additional controls, the functional form and the exclusion of individual cities. The checks establish that the between-neighbourhood association of Section~\ref{sec:results_baseline} is a stable feature of the data; they do not, and cannot, address the identification issue raised by the neighbourhood-fixed-effects estimates, which Section~\ref{sec:discussion} takes up.
8 8
9 −\subsection{Buffer Radius Robustness}
9 +\subsection{Buffer Radius}\label{sec:robustness_buffer}
10 10
11 −Our baseline specification uses a 500\,m buffer to define Airbnb exposure. Table~\ref{tab:buffer_robustness} reports the coefficient on the Airbnb count variable for buffer radii of 250\,m, 500\,m, 1\,km, and 2\,km, estimated using the same hedonic specification (Equation~\ref{eq:hedonic_rent}) with the full set of dwelling controls and city fixed effects.
11 +Table~\ref{tab:buffer_robustness} and Figure~\ref{fig:buffer_coef_plot} report the coefficient on the Airbnb count for radii of 250\,m, 500\,m, 1\,km and 2\,km, with dwelling controls and the fifteen-city fixed effects used in the spatial models.
12 12
13 13 \begin{table}[htbp]
14 14 \centering
15 15 \caption{Buffer Radius Robustness --- Hedonic Rent Model}
16 16 \label{tab:buffer_robustness}
17 + \small
17 18 \input{../results/tables/buffer_robustness.tex}
18 19 \end{table}
19 20
20 −The results confirm the spatial decay pattern illustrated in Figure~\ref{fig:buffer_decay}. The per-listing coefficient is largest at the 250\,m radius, where the spatial signal is most concentrated, and decreases monotonically as the buffer expands---mechanically so, since a listing counted within a wide buffer is a weaker proxy for immediate proximity than one counted within a narrow buffer. At all radii, the coefficient is positive and statistically significant at the 1\% level. The consistency of the positive association across radii provides reassurance that the finding is not an artefact of the particular buffer choice.
21 −
22 −Figure~\ref{fig:buffer_coef_plot} visualises the coefficient estimates and their 95\% confidence intervals across buffer radii.
23 −
24 21 \begin{figure}[htbp]
25 22 \centering
26 23 \includegraphics[width=0.70\textwidth]{coefficient_buffer_comparison.pdf}
27 − \caption{Airbnb Count Coefficient Across Buffer Radii (with 95\% CI)}
24 + \caption{Airbnb Count Coefficient Across Buffer Radii (95\% HC1 Confidence Intervals)}
28 25 \label{fig:buffer_coef_plot}
29 26 \end{figure}
30 27
31 −\subsection{Alternative Exposure Measures}
32 −
33 −Our baseline uses the raw count of Airbnb listings as the exposure measure. We consider two alternative measures to assess whether the results are sensitive to the functional form of the exposure variable:
34 −
35 −\begin{enumerate}[label=(\roman*)]
36 − \item \textbf{Airbnb density:} the count divided by the buffer area ($\pi r^2$ in km$^2$), which normalises for the geometric expansion of the buffer.
37 − \item \textbf{Share of entire-home listings:} the fraction of Airbnb listings within the buffer that are classified as entire-home properties (House, Cabin/Chalet, Condo), capturing the composition of short-term rental activity.
38 −\end{enumerate}
28 +The per-listing coefficient is largest at 250\,m (0.0093) and declines monotonically with the radius (0.0038 at 500\,m, 0.0016 at 1\,km, 0.0006 at 2\,km), remaining significant at the 1\% level throughout. Part of this decline is mechanical: a listing counted within a wide buffer is a weaker indicator of proximity than one counted within a narrow buffer, and the counts themselves grow with the area. Multiplying each coefficient by the mean count at its radius gives the association for a listing with average exposure: 2.2\% at 250\,m, 3.0\% at 500\,m, 4.2\% at 1\,km and 5.0\% at 2\,km. The total association therefore accumulates with the radius while the per-listing association decays, which is what one expects if the relevant variation is the overall STR intensity of the surrounding neighbourhood rather than the presence of particular listings within a few hundred metres. The $R^2$ also rises with the radius (0.503 to 0.521). Because the buffers are nested, these four estimates are not independent, and the ring decomposition in Section~\ref{sec:robustness_extended} separates them.
39 29
40 −These alternative specifications are reported as Models~(1d) and~(1e) in Table~\ref{tab:hedonic_rent}.
30 +\subsection{Alternative Exposure Measures}
41 31
42 −The Airbnb density measure yields qualitatively identical results to the raw count, with a positive and significant coefficient---as expected, since at a fixed radius the density is a rescaling of the count. The share of entire-home listings, by contrast, is \textit{not} significantly associated with rents (the point estimate is small and negative): conditional on dwelling characteristics and city fixed effects, it is the intensity of nearby Airbnb activity, rather than its compositional tilt toward entire homes, that co-varies with rents in our data. This finding does not support the compositional prediction of the supply-withdrawal hypothesis, under which entire-home listings---the closest substitutes for long-term rental units---should matter most; we return to this point in Section~\ref{sec:discussion}.
32 +Columns (1d) and (1e) of Table~\ref{tab:hedonic_rent} replace the count by the Airbnb density and by the entire-home share within 500\,m. The density is the count divided by the buffer area and yields the same inference. The entire-home share is not significantly associated with rents conditional on dwelling characteristics and city fixed effects (point estimate $-0.004$, standard error 0.011), on the subsample of 4{,}370 listings with at least one Airbnb nearby. Conditional on STR presence, it is the intensity of nearby activity rather than its tilt toward entire homes that co-varies with rents. This does not support the compositional prediction of the supply-withdrawal hypothesis, under which entire-home listings, the closest substitutes for long-term units, should matter most \citep{horn2017airbnb, duso2024airbnb}. Two caveats apply: the entire-home indicator is a property-type proxy rather than the platform's room type, and the share is measured with considerable noise where few listings fall within the buffer.
43 33
44 34 \subsection{Subsample Analysis}
45 35
46 −To assess whether the baseline results are driven by a particular geographic segment or building type, we estimate the hedonic rent model separately for the following subsamples:
47 −
48 −\begin{enumerate}[label=(\roman*)]
49 − \item \textbf{Montreal vs.\ non-Montreal:} Montreal dominates both datasets and is the primary tourist destination. The Airbnb--rent association may be stronger in Montreal, where short-term rental activity is most concentrated, or weaker if the city's larger and more liquid rental market is better able to absorb the supply shock.
50 − \item \textbf{Apartments vs.\ Houses:} Apartments constitute the vast majority of rental listings and are arguably the closest substitute for Airbnb rental units. Houses, by contrast, are a more heterogeneous category and may operate in a partially segmented market.
51 −\end{enumerate}
52 −
53 −Table~\ref{tab:subsample} presents the results.
36 +Table~\ref{tab:subsample} estimates the model with bedrooms, bathrooms and city fixed effects on four subsamples: Montreal and the rest of the province, and apartments and houses.
54 37
55 38 \begin{table}[htbp]
56 39 \centering
57 40 \caption{Subsample Analysis --- Hedonic Rent Model}
58 41 \label{tab:subsample}
42 + \small
59 43 \input{../results/tables/robustness_subsamples.tex}
60 44 \end{table}
61 45
62 −The Montreal subsample yields a positive and significant Airbnb coefficient that is similar in magnitude to the full-sample estimate, confirming that the baseline results are not driven solely by the inclusion of non-Montreal observations. The non-Montreal subsample also produces a positive coefficient, though with lower precision due to the smaller sample size and the greater heterogeneity of non-Montreal markets (which include both urban centres and resort communities).
63 −
64 −The apartment subsample closely mirrors the full-sample results, which is unsurprising given that apartments constitute approximately 90\% of the rental sample. The house subsample yields a coefficient that is larger than the full-sample estimate (0.0067) and statistically significant despite the much smaller sample, though its wider confidence interval reflects the greater heterogeneity of house rentals.
46 +The Montreal subsample (4{,}578 listings) yields a coefficient of 0.0039, identical to the full-sample estimate; the non-Montreal subsample yields 0.0030 with a much larger standard error (0.0016), reflecting the smaller sample and the heterogeneity of the other markets, which include suburbs, regional cities and resort communities. The apartment subsample mirrors the full sample, as expected given that apartments are 90\% of it. The 741 houses yield a larger coefficient (0.0059, standard error 0.0023), significant at the 5\% level; houses are a heterogeneous category and the estimate is imprecise.
65 47
66 48 \subsection{Outlier Sensitivity}
67 49
68 −To assess the sensitivity of the results to extreme values, we re-estimate the baseline model on two trimmed samples: one that retains only listings with monthly rents between the 5th and 95th percentiles, and one that drops the top and bottom 1\% of observations by Airbnb count within 500\,m (i.e., listings in the most Airbnb-saturated locations).
50 +Table~\ref{tab:outlier_sensitivity} re-estimates the model on two trimmed samples: listings with monthly rents between the 5th and 95th percentiles, and listings outside the top and bottom 1\% of the 500\,m count.
69 51
70 52 \begin{table}[htbp]
71 53 \centering
72 54 \caption{Outlier Sensitivity --- Hedonic Rent Model}
73 55 \label{tab:outlier_sensitivity}
56 + \small
74 57 \input{../results/tables/robustness_outliers.tex}
75 58 \end{table}
76 59
77 −The results are stable across the outlier-handling approaches. Trimming the rent distribution at the 5th and 95th percentiles reduces the point estimate by roughly a fifth (from 0.0039 to 0.0031)---consistent with the quantile-regression finding that the association is strongest in the tails---while trimming extreme Airbnb counts slightly increases it (0.0042). In every case the coefficient remains positive and significant at the 1\% level, providing confidence that the baseline results are not driven by a small number of influential observations.
60 +Trimming the rent distribution reduces the coefficient by about a fifth, from 0.0039 to 0.0031, consistent with the quantile results, which locate the strongest association in the upper tail; trimming the most Airbnb-saturated locations raises it slightly, to 0.0042. The coefficient remains significant at the 1\% level in every case, so the baseline result is not driven by a small number of influential observations.
78 61
79 −\subsection{Additional Specification Checks}
62 +\subsection{Additional Specification Checks}\label{sec:robustness_extended}
80 63
81 −Table~\ref{tab:extended_robustness} subjects the preferred specification to four further checks. Column~(R1) reproduces the baseline for reference.
64 +Table~\ref{tab:extended_robustness} subjects the reference specification to four further checks; column (R1) reproduces the baseline.
82 65
83 66 \begin{table}[htbp]
84 67 \centering
85 − \caption{Extended Robustness --- Preferred Hedonic Specification}
68 + \caption{Extended Robustness --- Reference Hedonic Specification}
86 69 \label{tab:extended_robustness}
87 70 \small
88 71 \input{../results/tables/extended_robustness.tex}
89 72 \end{table}
90 73
91 −\paragraph{Clustered standard errors.} Column~(R2) re-computes the baseline standard errors clustering by city (153 clusters). HC1 standard errors assume independence across observations, which is questionable when listings are spatially concentrated. In our data, city-level clustering in fact \textit{tightens} the standard error on the Airbnb coefficient (0.0001 versus 0.0002 under HC1), so the baseline significance levels are, if anything, conservative on this dimension. Clustering does widen the confidence interval on some controls (bathrooms), as expected.
74 +\paragraph{City-clustered standard errors.} Column (R2) clusters standard errors by city (252 clusters). Clustering tightens the standard error on the Airbnb coefficient from 0.0002 to 0.0001 while widening it on bathrooms. As discussed in Section~\ref{sec:results_inference}, this tightening is not credible given Montreal's weight in the sample, and FSA-clustered or Conley standard errors, which are three times the HC1 value, are the appropriate reference.
92 75
93 −\paragraph{Interior size.} Column~(R3) adds the interior floor area (per 100 sq ft) as a control on the subsample of 3{,}531 listings that report it. Size enters positively and significantly, and the Airbnb coefficient remains positive and highly significant at 0.0032---about a fifth smaller than the baseline, consistent with size absorbing some quality variation, but leaving the qualitative conclusion intact.
76 +\paragraph{Interior size.} Column (R3) adds interior floor area (per 100 square feet) on the 3{,}531 listings that report it. Size enters positively and significantly, and the Airbnb coefficient falls to 0.0032, about a fifth below the baseline, consistent with size absorbing some quality variation; it remains significant.
94 77
95 −\paragraph{Functional form.} Column~(R4) replaces the linear count with $\ln(1 + \texttt{airbnb\_count\_500m})$. The elasticity-style coefficient (0.048) is positive and highly significant: doubling the nearby Airbnb count is associated with roughly 3.4\% higher rent. The fit improves marginally over the linear form, indicating mild concavity in the exposure--rent relationship.
78 +\paragraph{Functional form.} Column (R4) replaces the count with $\ln(1+A_{i,500\text{m}})$. The coefficient of 0.048 implies that doubling the nearby count (plus one) is associated with about 3.4\% higher rent, and the fit improves marginally over the linear form, indicating concavity in the exposure--rent relationship. With FSA fixed effects the same coefficient is 0.002 and insignificant (Table~\ref{tab:neighbourhood_fe}).
96 79
97 −\paragraph{Ring exposure.} Column~(R5) includes the 500\,m count jointly with the count in the 500\,m--1\,km annulus. Both enter positively and significantly. Splitting the exposure this way attenuates the inner-buffer coefficient (0.0013), and the annulus coefficient (0.0018) is of comparable magnitude per listing: the association is therefore not confined to the immediate 500\,m but extends to the kilometre scale, consistent with the buffer-radius results above, where the total (not per-listing) association accumulates over wider areas. Because the two counts are strongly correlated, the individual coefficients in this specification should be read as a decomposition of a common neighbourhood signal rather than as separate causal gradients.
80 +\paragraph{Ring exposure.} Column (R5) includes the 500\,m count jointly with the count in the 500\,m--1\,km annulus. Both enter positively and significantly, and the per-listing coefficients are of similar size (0.0013 within 500\,m, 0.0018 in the annulus). The association is thus not confined to the immediate 500\,m but extends to the kilometre scale, in line with the accumulation pattern of Section~\ref{sec:robustness_buffer}. Because the two counts are strongly correlated, the split should be read as a decomposition of a common neighbourhood signal rather than as separate gradients; a strictly local effect would have produced a much larger inner-ring than outer-ring coefficient.
98 81
99 82 \subsection{Leave-One-City-Out Sensitivity}
100 83
101 −Figure~\ref{fig:leave_one_out} re-estimates the preferred specification excluding, in turn, each of the eight cities with the most rental listings.
84 +Figure~\ref{fig:leave_one_out} re-estimates the reference specification excluding, in turn, each of the eight cities with the most rental listings.
102 85
103 86 \begin{figure}[htbp]
104 87 \centering
105 88 \includegraphics[width=0.80\textwidth]{leave_one_city_out.pdf}
106 − \caption{Leave-One-City-Out Sensitivity of the Airbnb Coefficient}
89 + \caption{Leave-One-City-Out Sensitivity of the Airbnb Coefficient (95\% HC1 Confidence Intervals)}
107 90 \label{fig:leave_one_out}
108 91 \end{figure}
109 92
110 −The coefficient is remarkably stable, ranging from 0.0038 to 0.0040 across exclusions. Notably, excluding Montreal---which accounts for more than half of the estimation sample---leaves the point estimate essentially unchanged (0.0038), albeit with a wider confidence interval; the association is thus not an artefact of any single market.
93 +The coefficient ranges from 0.0038 to 0.0040 across exclusions. Excluding Montreal, which accounts for 58\% of the estimation sample, leaves the point estimate at 0.0038 with a wider confidence interval; the between-neighbourhood association is not an artefact of a single market.
111 94
112 95 \subsection{Summary of Robustness}
113 96
114 −Figure~\ref{fig:robustness_summary} presents a coefficient plot summarising the Airbnb count coefficient across all robustness specifications.
97 +Figure~\ref{fig:robustness_summary} summarises the Airbnb coefficient across the buffer and subsample specifications.
115 98
116 99 \begin{figure}[htbp]
117 100 \centering
118 101 \includegraphics[width=0.80\textwidth]{coefficient_robustness.pdf}
119 − \caption{Summary of Airbnb Count Coefficients Across Specifications}
102 + \caption{Summary of Airbnb Count Coefficients Across Specifications (95\% HC1 Confidence Intervals)}
120 103 \label{fig:robustness_summary}
121 104 \end{figure}
122 105
123 −Across all specifications---varying the buffer radius, the exposure measure, the functional form, the control set, the sample, the outlier treatment, and the standard-error computation---the estimated association between Airbnb presence and residential rents is consistently positive. While the magnitude varies across specifications, the qualitative conclusion is robust: higher Airbnb density in the immediate vicinity of a rental listing is associated with higher monthly rents, conditional on observable dwelling characteristics and city-level heterogeneity.
106 +Across radii, exposure measures, functional forms, control sets, subsamples, trimming rules and the exclusion of individual cities, the association between Airbnb exposure and rents conditional on city fixed effects is consistently positive and of similar magnitude. The stability of the estimate across these dimensions is informative about its reliability as a description of the data; it is not informative about its interpretation, which depends on the single dimension along which the estimate is not stable, the spatial resolution of the location fixed effects.
modified paper/sections/07_discussion.tex +24 −34
@@ -4,62 +4,52 @@
4 4 % =============================================================================
5 5 \section{Discussion}\label{sec:discussion}
6 6
7 −This section places the empirical findings in the context of the international literature, interprets them for housing policy, discusses the mechanisms that may underlie the observed associations, and addresses the limitations of the analysis.
7 +This section places the estimates in the context of the international literature, interprets the contrast between the city- and neighbourhood-fixed-effects results, draws the implications for housing policy and STR regulation, and sets out the limitations of the analysis.
8 8
9 −\subsection{Findings in the Context of the Literature}\label{sec:discussion_context}
9 +\subsection{Magnitudes in the Context of the Literature}\label{sec:discussion_context}
10 10
11 −How do our magnitudes compare with prior work? Three benchmarks are instructive. First, \citet{duso2024airbnb}, using regulatory shocks in Berlin, estimate that each nearby Airbnb listing raises asking rents by roughly 7--13 euros per month; our preferred estimate implies \$6--10 CAD per listing at the median Quebec rent---the same order of magnitude, obtained from an entirely different market and design. Second, \citet{koster2021short} find that Los Angeles ordinances which halved Airbnb activity lowered local rents by about 2\%; read through our semi-elasticity, removing half of the mean nearby exposure in our sample would predict a rent differential of a comparable magnitude in Airbnb-dense neighbourhoods. Third, \citet{horn2017airbnb} report that a one-standard-deviation increase in Airbnb density in Boston is associated with 0.4\% higher asking rents; our per-listing coefficient of 0.4\%, combined with the dispersion of exposure in our data, implies a somewhat larger standardised association, consistent with Quebec's rental stock being more concentrated in dense, Airbnb-exposed neighbourhoods. Our estimates also sit comfortably within the range documented across European markets \citep{garcia2020airbnb, franco2021impact, ayouba2020airbnb}.
11 +The city-fixed-effects estimate implies that one additional Airbnb listing within 500\,m is associated with a rent about 0.4\% higher, and one within 250\,m with a rent about 0.9\% higher. How do these compare with the quasi-experimental literature? \citet{duso2024airbnb} estimate, from Berlin's regulatory shocks, that each additional commercial Airbnb listing raises rents per square metre by 1.3--2.4\%. Per listing, this is larger than our 500\,m coefficient, but their treatment is a commercial listing, whereas our count includes every listing, casual or commercial, so the two are not directly comparable. \citet{barron2021effect} report an elasticity of rents with respect to Airbnb listings of 0.018; our logarithmic specification with city fixed effects gives 0.048, more than twice as large, while the FSA-fixed-effects version is 0.002 and insignificant. \citet{horn2017airbnb} find that a one-standard-deviation increase in Airbnb listings in Boston is associated with asking rents 0.4\% higher; the corresponding standardised association in our data is 5.5\% with city fixed effects and 1.2\% with FSA fixed effects. \citet{garcia2020airbnb} estimate average rent effects of 1.9\% in Barcelona and about 7\% in the most exposed neighbourhoods; for a listing with the average 500\,m exposure of eight Airbnb listings our estimates imply 3.1\% with city fixed effects and 0.6\% with FSA fixed effects, and for a listing at the 90th percentile of exposure (30 listings) 11.7\% and 2.4\%. \citet{koster2021short} find that ordinances which halved Airbnb listings lowered rents by about 3\%; halving the average exposure in our sample would correspond to 1.5\% and 0.3\%.
12 12
13 −Two disagreements with the literature deserve emphasis rather than concealment. First, unlike most STR pricing studies \citep{wang2017price, ert2016trust, gibbs2018pricing}, we find a superhost \textit{discount} and no significant association between city-level rents and nightly prices (Model~2); we attribute both to composition---Quebec's STR market mixes urban apartments with resort chalets, and the cross-city dimension is dominated by resort communities where nightly prices are high but long-term rents are not. Second, the compositional prediction of the supply-withdrawal hypothesis---that entire-home listings should matter most \citep{horn2017airbnb, combs2020short}---is not supported in our data: the entire-home share within the buffer is statistically indistinguishable from zero once fixed effects are included (Model~1e). Either our property-type proxy for entire-home status is too coarse, or in Quebec the intensity of nearby STR activity matters more than its composition. Both null results are informative for the Canadian debate precisely because they were not guaranteed by the design.
13 +The pattern is consistent. When standardised, the city-fixed-effects estimates are larger than the quasi-experimental magnitudes, often by a factor of several, while the FSA-fixed-effects estimates are of the same order as, or smaller than, those magnitudes. This is what one expects if the city-fixed-effects estimate combines a causal component with the between-neighbourhood sorting that the quasi-experimental designs remove. The earlier version of this paper read the proximity of its point estimate to the Berlin per-listing figure as mutual corroboration; the comparison in standardised terms and the neighbourhood-fixed-effects results do not support that reading. Our estimates are best described as bracketing the quasi-experimental magnitudes from above (city fixed effects) and from below or around (FSA fixed effects), with the latter too imprecise to pin down.
14 14
15 −\subsection{Policy Implications for Housing Affordability}
15 +Two further findings are worth placing against the literature. First, the superhost discount and the implausibly low explanatory power of the Airbnb pricing model on the full sample, which the earlier version interpreted as a Quebec-specific composition effect, are artefacts of the scraped price field; on the plausibly priced subsample, the model recovers the entire-home premium and the size gradients that \citet{wang2017price} and \citet{gibbs2018pricing} report, and no superhost discount. Second, the compositional prediction of the supply-withdrawal hypothesis, that entire-home listings should matter most \citep{horn2017airbnb, duso2024airbnb}, is not supported: conditional on STR presence, the entire-home share within the buffer is unrelated to rents. Given the coarse property-type proxy for entire-home status, we regard this as inconclusive rather than as evidence against the hypothesis.
16 16
17 −Our finding of a positive association between Airbnb presence and residential rents, while not causal in the strict econometric sense, carries implications for housing affordability policy. If the association reflects, even in part, a genuine supply-withdrawal mechanism---whereby landlords convert long-term rental units into short-term Airbnb listings---then the cumulative effect on rents in high-tourism neighbourhoods could be substantial. At our estimated semi-elasticity of 0.3--0.5\% per additional Airbnb listing within 500\,m, a neighbourhood with 20 nearby Airbnb listings would be associated with 6--10\% higher rents relative to an otherwise identical dwelling in an Airbnb-free area, all else equal.
17 +\subsection{Between-Neighbourhood and Within-Neighbourhood Variation}\label{sec:discussion_between_within}
18 18
19 −For policymakers in Quebec and Montreal, these estimates suggest that short-term rental activity is a factor---though certainly not the only or dominant factor---in the rental affordability equation. The magnitude of the association is modest relative to the contribution of dwelling characteristics (bedrooms, bathrooms) and location (city fixed effects), but it is non-trivial in a market where vacancy rates are historically low and modest rent increases impose real burdens on lower-income tenants.
19 +The central empirical fact of the paper is the contrast between a stable, precisely estimated association with city fixed effects and a small, imprecise one with FSA fixed effects. We offered three readings in Section~\ref{sec:results_fsa}; here we weigh them.
20 20
21 −\subsection{Short-Term Rental Regulation}
21 +The sorting reading has the most support. It is the mechanism that the identification literature anticipates \citep{kuminoff2010which, bishop2020best}, it is consistent with the direct evidence on endogenous amenities and location sorting in tourist cities \citep{hidalgo2024effect, almagro2025location}, it is consistent with the finding that block-scale spatial lag and error processes leave the coefficient intact while neighbourhood-scale fixed effects remove it, and it is consistent with the negative within-neighbourhood coefficient on the presence of any Airbnb, which suggests that within a neighbourhood STR listings sit on the less residential blocks. It is also consistent with the behaviour of the machine-learning benchmark, where the predictive advantage of flexible learners vanishes once neighbourhoods are held out.
22 22
23 −The province of Quebec requires short-term rental operators to register with the Corporation de l'industrie touristique du Qu\'{e}bec (CITQ) and imposes minimum standards on registered operators. The City of Montreal has supplemented these provincial requirements with additional restrictions, including limits on the number of nights per year that a primary residence can be rented on a short-term basis and outright prohibitions on non-owner-occupied short-term rentals in certain boroughs.
23 +The scale reading, under which STR-induced rent pressure is a neighbourhood-level phenomenon absorbed by the fixed effects, cannot be excluded. Supply withdrawal does operate on a neighbourhood-wide rental market, and a tenant displaced from one block searches on neighbouring blocks. But the same argument implies that the between-neighbourhood comparison, which is where the estimate lives, is exactly the comparison most exposed to amenity confounding. The quasi-experimental studies resolve this tension with time variation within neighbourhoods; a cross-section cannot.
24 24
25 −Our results, while descriptive, provide empirical grounding for the policy rationale underlying these regulations. The spatial decay of the Airbnb--rent association (Section~\ref{sec:results}) suggests that the effects are highly localised, which supports geographically targeted interventions (e.g., borough-level restrictions) rather than blanket province-wide regulations. The quantile regression results further suggest that regulatory attention might focus on high-rent neighbourhoods, where the association is strongest and where the risk of supply withdrawal is most acute.
25 +The measurement-error reading explains part of the attenuation. The scraped Airbnb sample omits inactive and filtered listings and other platforms, so the count measures true STR exposure with error, and the share of signal in the within-FSA variation is smaller than in the total variation. Classical measurement error attenuates both estimates toward zero and the within-FSA estimate more; it cannot, however, account for a fivefold reduction when a quarter of the variance is within neighbourhoods, nor for the sign of the extensive-margin coefficient.
26 26
27 −However, regulation involves tradeoffs. Short-term rentals generate income for hosts, tax revenue for municipalities, and consumer surplus for travellers. Overly restrictive regulation may push short-term rental activity underground, reduce tourism revenues, and impose compliance costs on casual hosts who rent their primary residence occasionally. A well-calibrated regulatory framework would balance these considerations by targeting commercial operators---those who manage multiple entire-home listings---while preserving the ability of residents to engage in occasional home-sharing.
27 +On balance, we conclude that most of the Airbnb--rent association in these data is a between-neighbourhood association, that the city-fixed-effects estimate of 0.4\% per listing is an upper bound on any causal within-neighbourhood effect, and that the within-neighbourhood estimate of 0.08\% per listing, with a 95\% Conley confidence interval that includes zero and extends to about 0.2\%, is the more conservative summary of what the data show.
28 28
29 −\subsection{Professional Hosts and Commercialisation}
30 −
31 −The literature has documented the increasing commercialisation of Airbnb, with a growing share of listings operated by professional, multi-listing hosts \citep{ke2017sharing, wachsmuth2018airbnb}. Unfortunately, our data do not contain host identifiers, precluding direct measurement of multi-listing activity. The compositional evidence we can bring to bear is, moreover, not supportive of a simple commercialisation channel: the share of entire-home listings within the buffer---the listings most likely to be operated commercially---is not significantly associated with rents once dwelling characteristics and city fixed effects are controlled for (Model~1e in Table~\ref{tab:hedonic_rent}). In our cross-section, it is the overall intensity of nearby Airbnb activity, rather than its compositional tilt toward entire homes, that co-varies with rents. One interpretation is that our property-type proxy for entire-home status is too coarse to isolate commercial operations; another is that, within Quebec's market, casual and commercial listings are sufficiently co-located that composition adds little signal beyond the count.
32 −
33 −Future research with host-level data could decompose the Airbnb--rent association into contributions from commercial versus casual hosts, providing a sharper evidence base for regulatory targeting.
29 +\subsection{Implications for Housing Affordability}
34 30
35 −\subsection{The Tourism--Housing Tradeoff}
31 +The implications for affordability policy follow from the two bounds. At the upper bound, a dwelling with twenty Airbnb listings within 500\,m, roughly the 85th percentile of exposure, would rent for about 8\% more than an otherwise identical dwelling in an Airbnb-free location of the same city; at the FSA-fixed-effects estimate the differential would be about 1.6\% and not statistically distinguishable from zero. The first figure is the one a reader of the cross-sectional literature would take away, and it is economically meaningful in a market with low vacancy rates; the second is the one that survives the closest approximation to a within-neighbourhood comparison the data permit. In either case, dwelling characteristics and neighbourhood location explain far more of the variation in rents than STR exposure does, so STR activity is at most one factor among several in the rental affordability equation. The cross-sectional evidence from Quebec, read carefully, therefore does not by itself establish that STR activity raises rents within neighbourhoods; it establishes that STR activity is concentrated in high-rent neighbourhoods, which is relevant to where the costs of any effect fall but is a different proposition.
36 32
37 −At a broader level, the Airbnb--rent relationship exemplifies a fundamental tension in urban policy: the tradeoff between tourism-driven economic activity and residential affordability. Cities like Montreal derive substantial economic benefits from tourism---employment in hospitality, retail, and cultural sectors; tax revenues; and global visibility---but these benefits are unevenly distributed, while the costs of tourism-driven housing pressure fall disproportionately on renters. Short-term rental platforms amplify this tension by enabling the conversion of residential housing into tourism infrastructure at the level of individual units, bypassing the traditional regulatory apparatus that governs hotel and commercial accommodation.
33 +\subsection{Short-Term Rental Regulation}\label{sec:discussion_regulation}
38 34
39 −Our findings suggest that this tension is empirically present in the Quebec context, though its magnitude is moderate. The policy challenge is to design regulatory frameworks that capture the benefits of short-term rental activity while mitigating its externalities on the residential rental market---a challenge that requires ongoing empirical monitoring as the platform economy continues to evolve.
35 +Quebec regulates STRs at two levels.\footnote{The regulatory description reflects the rules in force in 2025--2026 as published by the Government of Quebec (\url{https://www.quebec.ca/tourisme-et-loisirs/hebergement-touristique}) and the City of Montreal; it is not based on the academic literature and should be verified against the current texts before being relied upon.} Since 2022 the provincial Tourist Accommodation Act requires every STR establishment, including a primary residence let occasionally, to hold a registration certificate, to display the registration number in every advertisement and to transmit it to the platform; a 2023 amendment made platforms liable for listings without a valid number, with substantial fines. Montreal adds zoning rules that confine commercial STRs to designated zones and, since 2025, restricts primary-residence STRs to a summer window (10 June to 10 September) and prohibits them in some boroughs. Our data were collected in January 2026, outside that window, so the Montreal listings we observe were either in commercial zones or non-compliant, which is itself a reminder that enforcement, not only rules, shapes STR supply.
40 36
41 −\subsection{Limitations}
37 +The results bear on this regime in three ways. First, the spatial pattern of the between-neighbourhood association, decaying per listing and accumulating with the radius, indicates that STR activity is a neighbourhood-scale phenomenon, which favours geographically targeted instruments such as zoning and borough-level rules over province-wide ones, as \citet{gurran2017when} and \citet{nieuwland2020regulating} argue more generally. Second, the quantile results locate the association in the upper segment of the rental market, so that any rent pressure attributable to STRs would fall first on neighbourhoods that are already expensive; whether this is an argument for or against restriction depends on distributional objectives \citep{calderwang2021distributional}. Third, and most importantly, the within-neighbourhood estimates imply that the cross-sectional correlation that often motivates regulation substantially overstates what can be attributed to STR activity itself. A regulatory rationale that rests on such correlations is weaker than it appears; one that rests on the quasi-experimental literature \citep{koster2021short, duso2024airbnb} remains intact but has not been established for Quebec. Regulation also involves trade-offs: STRs generate income for hosts, tax revenue for municipalities and consumer surplus for travellers \citep{farronato2022welfare}, and restrictive rules may push activity underground. A framework that targets commercial multi-listing operation while preserving occasional home-sharing, which is the direction Quebec's registration regime has taken, is consistent with the evidence, but its effects on rents are an open empirical question.
42 38
43 −We reiterate and expand upon the key limitations of our analysis:
44 −
45 −\begin{enumerate}[label=(\roman*)]
46 − \item \textbf{Cross-sectional identification:} Our data represent a single point in time. We cannot distinguish the causal effect of Airbnb on rents from reverse causality (high rents attracting Airbnb hosts) or confounding by unobserved neighbourhood characteristics. A credible causal estimate would require panel data---ideally combined with a policy shock that exogenously shifted Airbnb supply in some locations but not others, as in \citet{koster2021short}, \citet{valentin2021regulating}, and \citet{duso2024airbnb}---or a valid instrumental variable for Airbnb penetration in the spirit of \citet{barron2021effect}. That said, the consistency of our magnitudes with these designs (Section~\ref{sec:discussion_context}) suggests the cross-sectional bias, whatever its direction, is unlikely to be dramatic.
47 −
48 − \item \textbf{No host-level data:} The absence of host identifiers prevents us from identifying multi-listing operators and from distinguishing professional from casual hosts, a distinction that is central to the commercialisation debate \citep{ke2017sharing, combs2020short} and to well-targeted regulation \citep{gurran2017when}.
39 +\subsection{Professional Hosts and Commercialisation}
49 40
50 − \item \textbf{Asking vs.\ transacted rents:} Our dependent variable measures asking rents on Realtor.ca rather than actual contract rents. If asking rents systematically overstate transacted rents (due to landlord bargaining power or strategic posting), our estimates may be biased, though the direction of this bias is ambiguous. We note that several benchmark studies share this feature \citep{horn2017airbnb, duso2024airbnb}, which aids comparability even if it does not remove the concern.
41 +The literature documents the increasing commercialisation of Airbnb, with a growing share of listings operated by multi-listing hosts \citep{ke2017sharing, wachsmuth2018airbnb, combs2020short}. Our data contain no host identifiers, so we cannot measure multi-listing activity directly, and our compositional proxy, the entire-home share within the buffer, is unrelated to rents conditional on STR presence. Either the property-type proxy is too coarse to isolate commercial operation, or within Quebec's market casual and commercial listings are sufficiently co-located that composition adds little information beyond the count. Host-resolved data would allow the association to be decomposed by host type and would sharpen the evidence base for a regime that explicitly distinguishes commercial from occasional hosts.
51 42
52 − \item \textbf{Exposure measurement error and platform coverage:} Both datasets are scraped from specific platforms and may not capture the universe of short-term or long-term rental listings. Alternative STR platforms (e.g., VRBO, Booking.com) are not included, scraped snapshots miss delisted or calendar-blocked units, and the Realtor.ca data may underrepresent informal or unposted rentals. To the extent that measurement error in the buffer counts is classical, it attenuates $\hat{\beta}$ toward zero, making our estimates conservative; non-classical error correlated with neighbourhood type cannot be ruled out.
43 +\subsection{Limitations}\label{sec:discussion_limitations}
53 44
54 − \item \textbf{Buffer choice and aggregation:} Any distance-based exposure measure faces a modifiable-areal-unit-style sensitivity: results could, in principle, depend on the radii chosen. We address this directly by reporting four radii, a ring decomposition, density and logarithmic functional forms, and continuous-decay-consistent patterns (Section~\ref{sec:robustness}), but the discreteness of any buffer set remains a simplification of the underlying spatial process \citep{can1992specification}.
45 +The limitations of the analysis are of three kinds: design, data and specification.
55 46
56 − \item \textbf{External validity:} Our sample is dominated by Montreal and a handful of other Quebec cities and resort areas. The findings may not generalise to other Canadian provinces or to rural housing markets where short-term rental dynamics differ---a caution reinforced by the cross-market heterogeneity documented in France \citep{ayouba2020airbnb} and Canada \citep{combs2020short}.
47 +\paragraph{Design.} The data are a single cross-section. We cannot separate the effect of Airbnb on rents from reverse causality or from unobserved neighbourhood characteristics, and the fixed-effects comparison shows that the latter matter. A credible causal estimate requires panel data, ideally combined with a policy shock that shifted STR supply in some locations but not others, as in \citet{koster2021short}, \citet{valentin2021regulating} and \citet{duso2024airbnb}, or an instrument for Airbnb penetration in the spirit of \citet{barron2021effect} and \citet{garcia2020airbnb}. The analysis is also static and cannot capture supply responses to rising rents \citep{glaeser2005urban, saiz2010geographic} or host exit in response to enforcement.
57 48
58 − \item \textbf{Static analysis:} Our cross-sectional framework cannot capture dynamic adjustments in the housing market, such as the construction of new supply in response to rising rents \citep{glaeser2005urban, saiz2010geographic} or the exit of Airbnb hosts in response to regulatory pressure.
59 −\end{enumerate}
49 +\paragraph{Data.} The scraped Airbnb price field is bimodal and partly records total-stay rather than nightly prices, which invalidates the full-sample Airbnb pricing model and adds noise to the mean-nearby-price exposure variable; the count-based main results are unaffected. Room type and host identity are not observed, so entire-home status is a property-type proxy and commercial operation cannot be measured. The Airbnb sample omits inactive, blocked and filtered listings and other platforms, and was collected in winter, when the composition of active listings differs from the summer peak; measurement error in exposure attenuates the estimates, more so within neighbourhoods. The rental data are asking rents on Realtor.ca, which over-represents agent-listed, newer and higher-priced units relative to the occupied stock; several benchmark studies share the asking-rent feature \citep{horn2017airbnb, duso2024airbnb}, which aids comparability but not representativeness. The composition-based specifications and the machine-learning benchmark are estimated on the selected subsample of listings with positive exposure. Interior size is available for less than half the sample and contains implausible values.
60 50
61 −These limitations motivate the cautious interpretive stance adopted throughout the paper and underscore the need for future research with richer data structures.
51 +\paragraph{Specification.} Any distance-based exposure measure is a discretisation of a continuous spatial process and is subject to the modifiable areal unit problem \citep{fotheringham1991modifiable}; we report four radii, a ring decomposition and alternative functional forms, but the set of buffers remains a simplification \citep{can1992specification}. FSAs are administrative delivery zones rather than housing submarkets, and their size varies; the attenuation we document would plausibly be larger with finer neighbourhood definitions and smaller with coarser ones. The spatial models use a single weights specification ($k=5$ nearest neighbours) and coarse city groups; the quantile regressions use even coarser groups and standard errors that ignore spatial dependence. Finally, the sample is dominated by Montreal and a handful of other cities, which limits generalisation to peripheral and rural markets, where STR dynamics differ \citep{ayouba2020airbnb, combs2020short}.
62 52
63 53 \subsection{Future Work}
64 54
65 −Four extensions strike us as most valuable, in ascending order of data requirements. First, replicating the buffer-based design on repeated scrapes of the same platforms would deliver a listing-level panel for Quebec, enabling fixed-effects and event-study designs around the province's evolving registration regime. Second, Quebec's 2023 tightening of STR registration enforcement offers a natural policy discontinuity analogous to those exploited in Los Angeles \citep{koster2021short}, New Orleans \citep{valentin2021regulating}, and Berlin \citep{duso2024airbnb}; combining it with our exposure measures is the most direct route to causal estimates for Canada. Third, host-resolved data would permit separating commercial from casual supply, testing the commercialisation channel that our entire-home-share proxy cannot \citep{ke2017sharing, combs2020short}. Fourth, integrating administrative contract rents (e.g., lease registry data) would resolve the asking-rent measurement concern and allow distributional welfare analysis in the spirit of \citet{li2022market}.
55 +Four extensions follow directly. First, repeated scrapes of the same platforms would yield a listing-level panel for Quebec and allow fixed-effects and event-study designs around the province's registration regime and Montreal's 2025 seasonal rule, the most direct route to within-neighbourhood causal estimates for Canada. Second, host-resolved data would permit the commercial--casual decomposition that the entire-home proxy cannot deliver. Third, administrative contract rents, for instance from lease registries, would resolve the asking-rent and selection concerns and allow welfare analysis in the spirit of \citet{li2022market} and \citet{calderwang2021distributional}. Fourth, on the present data, quantile regressions with neighbourhood fixed effects, estimated with penalised fixed-effects methods, and spatial models with neighbourhood fixed effects would complete the within-neighbourhood picture.
modified paper/sections/08_conclusion.tex +5 −7
@@ -4,14 +4,12 @@
4 4 % =============================================================================
5 5 \section{Conclusion}\label{sec:conclusion}
6 6
7 −This paper has investigated the relationship between Airbnb short-term rental activity and residential rents in Quebec, Canada, using cross-sectional microdata comprising approximately 5{,}000 Airbnb listings and 8{,}300 residential rental listings. Employing a hedonic pricing framework augmented with spatial analysis, quantile regressions, and machine-learning benchmarks, we have documented a consistent positive association between nearby Airbnb presence and monthly rents.
7 +This paper has examined the relationship between Airbnb activity and residential rents in Quebec using a 2026 cross-section of 3{,}456 Airbnb listings and 8{,}303 rental listings linked by exact distance-based matching. It is, to our knowledge, the first listing-level econometric analysis of the question for Quebec and for a Canadian market, and it has been designed to make the identification problem of cross-sectional STR--rent studies measurable rather than merely acknowledged.
8 8
9 −Our key findings are as follows. First, each additional Airbnb listing within 500 metres of a rental unit is associated with an approximate 0.4\% increase in monthly rent, conditional on dwelling characteristics and city fixed effects---an estimate that is stable across spatial and trimmed-sample specifications (roughly 0.3--0.5\%). Second, this association exhibits spatial decay, with the per-listing coefficient largest at narrow buffer radii and attenuating at wider distances. Third, quantile regressions reveal that the association, while significant throughout the distribution, is strongest at the upper tail, suggesting that high-rent segments of the market are most strongly linked to Airbnb activity. Fourth, a complementary hedonic model of Airbnb nightly prices indicates that short-term rental pricing is driven primarily by listing characteristics; city-level mean rents carry no significant premium, offering no support for a simple opportunity-cost pricing channel in our cross-section. Fifth, machine-learning models confirm the predictive relevance of Airbnb exposure variables and the adequacy of the linear hedonic specification for inference.
9 +The findings have two layers. With city fixed effects, each additional Airbnb listing within 500\,m is associated with a monthly rent about 0.4\% higher, the per-listing association decays with distance while the total association accumulates with the radius, the association is largest at the upper quantiles of the conditional rent distribution, and it is unchanged in spatial lag and spatial error models, with a total impact of 0.40\% per listing. These results are stable across exposure measures, functional forms, subsamples, trimming rules and the exclusion of individual cities, and they are of the kind that the cross-sectional literature on STR platforms has generally reported.
10 10
11 −The principal contribution of this paper is to provide the first granular, listing-level econometric analysis of the Airbnb--rent nexus in Quebec---extending a Canadian evidence base that was previously descriptive \citep{combs2020short, grisdale2021displacement}---leveraging precise geographic coordinates for exact distance-based spatial matching. By applying multiple econometric and machine-learning methods to a single dataset, we demonstrate the consistency of the finding across methodological frameworks and provide a rich set of robustness checks that characterise the sensitivity of the estimates to alternative specifications. Notably, our per-listing magnitude is of the same order as those recovered from regulatory quasi-experiments in Berlin and Los Angeles \citep{duso2024airbnb, koster2021short}, which we read as mutual corroboration between designs.
11 +The second layer changes their interpretation. Standard errors that account for spatial dependence in a buffer-based exposure measure are about three times larger than the heteroskedasticity-robust errors conventionally reported, although the city-fixed-effects estimate remains significant. More importantly, once fixed effects for postal-code neighbourhoods absorb neighbourhood-level unobservables, the coefficient falls to about 0.08\% per listing and is no longer distinguishable from zero under spatial inference; the logarithmic and extensive-margin exposure measures behave in the same way, and within neighbourhoods the presence of any Airbnb listing is associated with lower rather than higher rents. The predictive advantage of tree-based machine-learning models over the linear hedonic model, which a random hold-out sample suggests, disappears when whole neighbourhoods are held out. In these data, the Airbnb--rent association is predominantly a between-neighbourhood phenomenon, consistent with STR supply concentrating in high-amenity, high-rent neighbourhoods. When standardised, the city-fixed-effects estimates exceed the magnitudes found by quasi-experimental studies in Berlin, Los Angeles, Barcelona and Boston, while the neighbourhood-fixed-effects estimates are of the same order or smaller; the two bracket the causal literature from above and below.
12 12
13 −We are candid about the limitations of our analysis. The cross-sectional nature of the data precludes causal identification: the positive association between Airbnb density and rents may reflect reverse causality, omitted neighbourhood characteristics, or spatial sorting, rather than---or in addition to---a genuine supply-withdrawal effect. Establishing causality in this domain requires panel data combined with plausibly exogenous variation in Airbnb supply, such as a regulatory discontinuity or a natural experiment. Our results should therefore be interpreted as well-controlled conditional correlations that are consistent with the supply-withdrawal hypothesis but do not definitively confirm it.
13 +Two subsidiary results concern the Airbnb side of the market. A hedonic model of nightly prices finds no association between city-level rents and STR prices, so the data offer no support for a simple opportunity-cost pricing channel. The model also reveals that the scraped price field is bimodal and partly records total-stay prices; on the plausibly priced subsample the conventional entire-home and size premia reappear and the superhost discount reported in an earlier version of this paper disappears.
14 14
15 −Several directions for future research emerge from this analysis. First, the construction of panel data---tracking the entry and exit of Airbnb listings and the evolution of rents over time at the neighbourhood level---would enable difference-in-differences or event-study designs that can more credibly isolate the causal effect. Second, the exploitation of regulatory shocks---such as the tightening of Montreal's short-term rental regulations or the introduction of provincial registration requirements---would provide natural-experiment variation for causal inference. Third, the integration of host-level data would allow researchers to distinguish the effects of commercial multi-listing operators from those of casual home-sharers, sharpening the policy relevance of the analysis. Fourth, extending the geographic scope to include other Canadian cities would improve external validity and enable cross-city comparisons of regulatory effectiveness.
16 −
17 −In sum, our findings add to a growing body of evidence---now spanning correlational, quasi-experimental, and structural designs \citep{barron2021effect, koster2021short, li2022market}---that short-term rental platforms are associated with higher residential rents, at least in localities with significant tourist appeal. While the estimated magnitudes are modest at the per-listing level, their cumulative significance in high-tourism neighbourhoods---combined with the documented concentration of effects at the upper end of the rent distribution---underscores the importance of evidence-based regulatory frameworks that balance the economic benefits of the platform economy with the imperative of housing affordability.
15 +For policy, the results counsel care in reading cross-sectional correlations between STR density and rents as evidence of STR-induced rent pressure. Such correlations describe where STR activity is located, which matters for the incidence of any effect, but in Quebec most of the correlation does not survive a within-neighbourhood comparison. The case for regulating STRs on affordability grounds therefore rests on the quasi-experimental evidence from other markets, and establishing it for Quebec requires panel data, ideally combined with the province's registration regime and Montreal's seasonal rules as sources of variation, together with host-resolved listings and contract rents. The present paper provides the baseline against which such work can be measured, and a template, neighbourhood fixed effects and spatially robust inference, for what cross-sectional STR studies should report.
added results/logs/pipeline_run_20261017.txt +321 −0
@@ -0,0 +1,321 @@
1 +===== 05_descriptive_analysis 20:52:10 =====
2 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/frame.py", line 16120, in quantile
3 + res_df = self.quantile(
4 + [q], # type: ignore[list-item]
5 + ...<3 lines>...
6 + method=method,
7 + )
8 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/frame.py", line 16165, in quantile
9 + res = data._mgr.quantile(qs=q, interpolation=interpolation)
10 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/internals/managers.py", line 1720, in quantile
11 + blk.quantile(qs=qs, interpolation=interpolation) for blk in self.blocks
12 + ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/internals/blocks.py", line 1495, in quantile
14 + result = quantile_compat(self.values, np.asarray(qs._values), interpolation)
15 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/array_algos/quantile.py", line 39, in quantile_compat
16 + return quantile_with_mask(values, mask, fill_value, qs, interpolation)
17 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/array_algos/quantile.py", line 97, in quantile_with_mask
18 + result = _nanquantile(
19 + values,
20 + ...<3 lines>...
21 + interpolation=interpolation,
22 + )
23 + File "/opt/homebrew/lib/python3.14/site-packages/pandas/core/array_algos/quantile.py", line 218, in _nanquantile
24 + return np.quantile(
25 + ~~~~~~~~~~~^
26 + values,
27 + ^^^^^^^
28 + ...<5 lines>...
29 + method=interpolation, # type: ignore[call-overload]
30 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
31 + )
32 + ^
33 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 4496, in quantile
34 + return _quantile_unchecked(
35 + a, q, axis, out, overwrite_input, method, keepdims, weights, weak_q)
36 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 4510, in _quantile_unchecked
37 + return _ureduce(a,
38 + func=_quantile_ureduce_func,
39 + ...<6 lines>...
40 + method=method,
41 + weak_q=weak_q)
42 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 3880, in _ureduce
43 + r = func(a, **kwargs)
44 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 4669, in _quantile_ureduce_func
45 + result = _quantile(arr,
46 + quantiles=q,
47 + ...<3 lines>...
48 + weights=wgt,
49 + weak_q=weak_q)
50 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 4807, in _quantile
51 + result = _lerp(previous,
52 + next,
53 + gamma,
54 + out=out)
55 + File "/opt/homebrew/lib/python3.14/site-packages/numpy/lib/_function_base_impl.py", line 4596, in _lerp
56 + diff_b_a = b - a
57 + ~~^~~
58 +TypeError: numpy boolean subtract, the `-` operator, is not supported, use the bitwise_xor, the `^` operator, or the logical_xor function instead.
59 +real 0,45
60 +user 0,38
61 +sys 0,06
62 +exit: 1
63 +===== 06_hedonic_models 20:52:10 =====
64 +========================================================================
65 +06 HEDONIC REGRESSION MODELS
66 +========================================================================
67 +
68 +Rent data: 8,303 rows, 43 cols
69 +Airbnb data: 3,456 rows, 21 cols
70 +
71 +------------------------------------------------------------------------
72 +MODEL 1: Baseline Hedonic Rent Model
73 +------------------------------------------------------------------------
74 +
75 + [1a] N=8,303 R2=0.0075 Adj-R2=0.0074
76 +
77 + [1b] N=7,925 R2=0.4705 Adj-R2=0.4702
78 +
79 + [1c] N=7,925 R2=0.5697 Adj-R2=0.5554
80 +
81 + [1d] N=7,925 R2=0.5697 Adj-R2=0.5554
82 +
83 + [1e] N=4,370 R2=0.4961 Adj-R2=0.4857
84 +Traceback (most recent call last):
85 + File "/Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/scripts/06_hedonic_models.py", line 321, in <module>
86 + main()
87 + ~~~~^^
88 + File "/Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/scripts/06_hedonic_models.py", line 311, in main
89 + model1_hedonic_rent(rent)
90 + ~~~~~~~~~~~~~~~~~~~^^^^^^
91 + File "/Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/scripts/06_hedonic_models.py", line 105, in model1_hedonic_rent
92 + results_to_latex(
93 + ~~~~~~~~~~~~~~~~^
94 + all_res,
95 + ^^^^^^^^
96 + ...<5 lines>...
97 + note="Models (1c)-(1e) include city fixed effects (not shown).",
98 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99 + )
100 + ^
101 + File "/Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/src/latex_tables.py", line 136, in results_to_latex
102 + vname = label(var)
103 + ^^^^^
104 +UnboundLocalError: cannot access local variable 'label' where it is not associated with a value
105 +real 1,04
106 +user 0,93
107 +sys 0,14
108 +exit: 1
109 +===== 07_spatial_models 20:52:11 =====
110 +/Users/simon-pierreboucher/Library/Python/3.14/lib/python/site-packages/libpysal/weights/distance.py:153: UserWarning: The weights matrix is not fully connected:
111 + There are 140 disconnected components.
112 + W.__init__(self, neighbors, id_order=ids, **kwargs)
113 + libpysal + spreg available — will run SAR / SEM
114 +========================================================================
115 +07 SPATIAL MODELS
116 +========================================================================
117 +
118 +Rent data: 8,303 rows
119 +
120 +------------------------------------------------------------------------
121 +MODEL 4: Spatial Models
122 +------------------------------------------------------------------------
123 + Complete cases for spatial analysis: 7,925
124 + [OLS baseline (spatial sample)] N=7,925 R2=0.5081
125 +
126 + Building KNN(k=5) spatial weights ...
127 + Estimating Spatial Lag Model (SAR) ...
128 +GM_Lag
129 + [SAR] N=7925 pseudo-R2=0.5508 rho=0.1340
130 + Estimating Spatial Error Model (SEM) ...
131 +GM_Error
132 + [SEM] N=7925 pseudo-R2=0.4973 lambda=0.5437
133 + Computing LeSage-Pace impacts ...
134 + rho=0.1340 mean diag exact=1.00258 series=1.00257
135 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/spatial_impacts.tex
136 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/spatial_models.tex
137 +
138 +------------------------------------------------------------------------
139 +Distance-buffer robustness (250m, 500m, 1km, 2km)
140 +------------------------------------------------------------------------
141 + [buffer 250m] N=7,925 R2=0.5026
142 + [buffer 500m] N=7,925 R2=0.5081
143 + [buffer 1km] N=7,925 R2=0.5167
144 + [buffer 2km] N=7,925 R2=0.5205
145 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/buffer_robustness.tex
146 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/coefficient_buffer_comparison.pdf
147 +
148 +========================================================================
149 +07 DONE
150 +========================================================================
151 +real 2,52
152 +user 2,14
153 +sys 0,29
154 +exit: 0
155 +===== 08_quantile_models 20:52:14 =====
156 +========================================================================
157 +08 QUANTILE REGRESSION MODELS
158 +========================================================================
159 +
160 +Rent data: 8,303 rows
161 + Top-5 cities for quantile FE: ['Montreal', 'Laval', 'Gatineau', 'Trois-Rivières', 'Longueuil']
162 + Complete cases: 7,925
163 +
164 +------------------------------------------------------------------------
165 +MODEL 5: Quantile Regressions
166 +------------------------------------------------------------------------
167 + tau=0.10 β(airbnb)=0.003687 SE=0.000323 p=0.0000*** pseudo-R2=0.2251
168 + tau=0.25 β(airbnb)=0.003426 SE=0.000255 p=0.0000*** pseudo-R2=0.2529
169 + tau=0.50 β(airbnb)=0.003528 SE=0.000234 p=0.0000*** pseudo-R2=0.2976
170 + tau=0.75 β(airbnb)=0.004133 SE=0.000228 p=0.0000*** pseudo-R2=0.3294
171 + tau=0.90 β(airbnb)=0.004715 SE=0.000328 p=0.0000*** pseudo-R2=0.3402
172 + OLS β(airbnb)=0.003849 SE=0.000221 R2=0.4849
173 +
174 + Building LaTeX table ...
175 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/quantile_regression.tex
176 + Building coefficient plot ...
177 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/quantile_coefficients.pdf
178 +
179 +========================================================================
180 +08 DONE
181 +========================================================================
182 +real 1,60
183 +user 1,42
184 +sys 0,16
185 +exit: 0
186 +===== 09_ml_robustness 20:52:15 =====
187 +Loading data ...
188 +Sample size after dropping NaN: 4,370
189 +Train: 3,496 | Test: 874
190 +Training OLS ...
191 + R2 train=0.4741 test=0.5094 RMSE=0.2242 MAE=0.1727
192 +Training LASSO ...
193 + R2 train=0.4740 test=0.5099 RMSE=0.2241 MAE=0.1725
194 +Training Elastic Net ...
195 + R2 train=0.4740 test=0.5099 RMSE=0.2241 MAE=0.1725
196 +Training Random Forest ...
197 + R2 train=0.9092 test=0.7079 RMSE=0.1730 MAE=0.1284
198 +Training Gradient Boosting ...
199 + R2 train=0.8762 test=0.6935 RMSE=0.1772 MAE=0.1319
200 +
201 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/ml_comparison.tex
202 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/ml_comparison.csv
203 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/ml_predicted_vs_actual.pdf
204 +
205 +SHAP library found — computing SHAP values ...
206 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/shap_summary.pdf
207 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/feature_importance.pdf
208 +
209 +Cross-validation (random vs FSA-blocked folds) ...
210 + [Random 5-fold] OLS R2=0.4767 (sd 0.0405) RMSE=0.2256
211 + [Random 5-fold] LASSO R2=0.4767 (sd 0.0406) RMSE=0.2256
212 + [Random 5-fold] Elastic Net R2=0.4767 (sd 0.0405) RMSE=0.2256
213 + [Random 5-fold] Random Forest R2=0.6473 (sd 0.0445) RMSE=0.1849
214 + [Random 5-fold] Gradient Boosting R2=0.6538 (sd 0.0334) RMSE=0.1834
215 + [Spatial 5-fold (FSA blocks)] OLS R2=0.4667 (sd 0.0539) RMSE=0.2261
216 + [Spatial 5-fold (FSA blocks)] LASSO R2=0.4668 (sd 0.0538) RMSE=0.2261
217 + [Spatial 5-fold (FSA blocks)] Elastic Net R2=0.4668 (sd 0.0538) RMSE=0.2261
218 + [Spatial 5-fold (FSA blocks)] Random Forest R2=0.4307 (sd 0.1594) RMSE=0.2306
219 + [Spatial 5-fold (FSA blocks)] Gradient Boosting R2=0.4140 (sd 0.1076) RMSE=0.2355
220 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/ml_spatial_cv.tex
221 +
222 +=== 09_ml_robustness.py complete ===
223 +real 28,48
224 +user 102,86
225 +sys 2,34
226 +exit: 0
227 +===== 10_robustness_tables_figures 20:52:44 =====
228 +Loading data ...
229 +Full sample: 8,303 observations
230 +
231 +--- Winsorization robustness ---
232 + Full sample coef=0.003891 N=7925
233 + Rent winsorized (5/95) coef=0.003057 N=7254
234 + Airbnb trimmed (1/99) coef=0.004222 N=7868
235 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/robustness_outliers.tex
236 +
237 +--- Subsample analysis ---
238 + Montreal only coef=0.003865 N=4578
239 + Outside Montreal coef=0.003046 N=3347
240 + Apartments only coef=0.003860 N=7136
241 + Houses only coef=0.005857 N=741
242 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/robustness_subsamples.tex
243 +
244 +--- Hexbin heatmap (Montreal) ---
245 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/rent_airbnb_heatmap.pdf
246 +
247 +--- Coefficient robustness plot ---
248 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/coefficient_robustness.pdf
249 +
250 +--- Rent by Airbnb quintiles ---
251 +Saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/rent_by_airbnb_bins.pdf
252 +
253 +=== 10_robustness_tables_figures.py complete ===
254 +real 1,58
255 +user 1,44
256 +sys 0,18
257 +exit: 0
258 +===== 11_extended_robustness 20:52:45 =====
259 +========================================================================
260 +11 EXTENDED ROBUSTNESS
261 +========================================================================
262 +
263 +Sample: 8,303 rows | interior size non-missing: 3,699
264 +
265 +--- Specifications R1-R5 ---
266 + [R1 baseline HC1] N=7,925 R2=0.5697 beta(airbnb_count_500m)=0.003878 SE=0.000225
267 + [R2 clustered] city clusters = 252
268 + [R2 clustered] N=7,925 R2=0.5697 beta(airbnb_count_500m)=0.003878 SE=0.000110
269 + [R3 + size] N=3,531 R2=0.6044 beta(airbnb_count_500m)=0.003162 SE=0.000275
270 + [R4 log(1+count)] N=7,925 R2=0.5726 beta(log1p_airbnb_500m)=0.048354 SE=0.002538
271 + [R5 ring] N=7,925 R2=0.5786 beta(airbnb_count_500m)=0.001280 SE=0.000295
272 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/extended_robustness.tex
273 +
274 +--- Leave-one-city-out ---
275 + [Full sample] N=7,925 R2=0.5697 beta(airbnb_count_500m)=0.003878 SE=0.000225
276 + [excl. Montreal] N=3,347 R2=0.7062 beta(airbnb_count_500m)=0.003773 SE=0.001639
277 + [excl. Laval] N=7,534 R2=0.5704 beta(airbnb_count_500m)=0.003880 SE=0.000226
278 + [excl. Gatineau] N=7,736 R2=0.5721 beta(airbnb_count_500m)=0.003870 SE=0.000225
279 + [excl. Trois-Rivières] N=7,811 R2=0.5720 beta(airbnb_count_500m)=0.003888 SE=0.000225
280 + [excl. Longueuil] N=7,757 R2=0.5690 beta(airbnb_count_500m)=0.003889 SE=0.000225
281 + [excl. Brossard] N=7,771 R2=0.5708 beta(airbnb_count_500m)=0.003883 SE=0.000225
282 + [excl. Québec] N=7,813 R2=0.5733 beta(airbnb_count_500m)=0.003952 SE=0.000227
283 + [excl. Salaberry-de-Valleyfield] N=7,816 R2=0.5644 beta(airbnb_count_500m)=0.003874 SE=0.000225
284 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/figures/leave_one_city_out.pdf
285 +
286 +========================================================================
287 +11 DONE
288 +========================================================================
289 +real 1,89
290 +user 1,81
291 +sys 0,19
292 +exit: 0
293 +===== 12_neighbourhood_fe_inference 20:52:47 =====
294 +========================================================================
295 +12 NEIGHBOURHOOD FIXED EFFECTS AND SPATIAL INFERENCE
296 +========================================================================
297 +
298 +Sample: 8,303 rows | FSAs: 333 | cities: 253
299 +
300 +--- Specifications ---
301 + [F1 city FE] N=7,860 groups=187 R2=0.5636 within R2=0.4703 beta(airbnb_count_500m)=0.003878 SE=0.000224
302 + [F2 FSA FE] N=7,883 groups=289 R2=0.6306 within R2=0.5189 beta(airbnb_count_500m)=0.000819 SE=0.000362
303 + [F3 FSA FE any+count] N=7,883 groups=289 R2=0.6313 within R2=0.5197 beta(any_airbnb_500m)=-0.027888 SE=0.008775
304 + [F4 FSA FE log1p] N=7,883 groups=289 R2=0.6303 within R2=0.5184 beta(log1p_airbnb_500m)=0.002230 SE=0.005297
305 + [F5 FSA FE + size] N=3,485 groups=222 R2=0.6505 within R2=0.5326 beta(airbnb_count_500m)=0.000327 SE=0.000579
306 + [bivariate] beta=0.001969 R2=0.0075
307 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/neighbourhood_fe.tex
308 +
309 +--- Inference comparison ---
310 + [City FE (Model 1c)] beta=0.003878 HC1=0.000224 city=0.000109 (187 cl.) fsa=0.000654 (318 cl.) Conley1km=0.000689 Conley2km=0.000728 Conley5km=0.000655 Conley10km=0.000721
311 + [FSA FE (F2)] beta=0.000819 HC1=0.000362 city=0.000359 (239 cl.) fsa=0.000727 (289 cl.) Conley1km=0.000719 Conley2km=0.000684 Conley5km=0.000473 Conley10km=0.000404
312 + -> saved /Users/simon-pierreboucher/Desktop/Recherche-UQO/immobilier/airbnb-rents-housing-pressure/results/tables/inference_comparison.tex
313 +
314 +========================================================================
315 +12 DONE
316 +========================================================================
317 +real 4,56
318 +user 4,37
319 +sys 0,16
320 +exit: 0
321 +ALL DONE 20:52:52
modified results/tables/buffer_robustness.tex +2 −2
@@ -1,7 +1,7 @@
1 1 \begin{tabular}{lcccc}
2 2 \toprule
3 3 & \textbf{250m} & \textbf{500m} & \textbf{1km} & \textbf{2km} \\
4 −Dep.\ var: & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} \\
4 +Dep.\ var: & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} \\
5 5 \midrule
6 6 Airbnb count & 0.009272*** & 0.003826*** & 0.001589*** & 0.000612*** \\
7 7 & (0.000636) & (0.000221) & (0.000080) & (0.000028) \\[4pt]
@@ -12,4 +12,4 @@ Observations & 7,925 & 7,925 & 7,925 & 7,925 \\
12 12 R$^2$ & 0.5026 & 0.5081 & 0.5167 & 0.5205 \\
13 13 \bottomrule
14 14 \end{tabular}
15 −\parbox{\textwidth}{\footnotesize Robust (HC1) standard errors in parentheses. Controls: bedrooms, bathrooms, building-type dummies. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
15 +\parbox{\textwidth}{\footnotesize Robust (HC1) standard errors in parentheses. Controls: bedrooms, bathrooms, building-type dummies; fixed effects for the 15 largest cities (remaining cities grouped), as in Table~\ref{tab:spatial_results}. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
modified results/tables/city_level_interaction.tex +6 −6
@@ -1,17 +1,17 @@
1 1 \begin{tabular}{lcc}
2 2 \toprule
3 3 & \textbf{(3-fwd)} & \textbf{(3-rev)} \\
4 −Dep.\ var: & \textit{mean\_log\_rent} & \textit{airbnb\_count\_city} \\
4 +Dep.\ var: & \textit{mean log rent} & \textit{Airbnb listings in city} \\
5 5 \midrule
6 −const & 6.9341*** & -40.9296 \\
6 +Constant & 6.9341*** & -40.9296 \\
7 7 & (0.0707) & (58.2750) \\[4pt]
8 −airbnb\_count\_city & 0.0001** & \\
8 +Airbnb listings in city & 0.0001** & \\
9 9 & (0.0000) & \\[4pt]
10 −mean\_bedrooms & 0.0882*** & -14.4332 \\
10 +Mean bedrooms & 0.0882*** & -14.4332 \\
11 11 & (0.0241) & (9.4579) \\[4pt]
12 −mean\_bathrooms & 0.3741*** & 11.6631* \\
12 +Mean bathrooms & 0.3741*** & 11.6631* \\
13 13 & (0.0528) & (6.4498) \\[4pt]
14 −mean\_log\_rent & & 10.2254 \\
14 +Mean log rent & & 10.2254 \\
15 15 & & (10.9040) \\[4pt]
16 16 \midrule
17 17 Observations & 153 & 153 \\
modified results/tables/correlation_matrix.tex +9 −8
@@ -1,13 +1,14 @@
1 1 \begin{tabular}{lrrrrrrr}
2 2 \toprule
3 − & log_rent & airbnb_count_500m & airbnb_density_500m & mean_airbnb_price_500m & share_entire_home_500m & bedrooms & bathrooms \\
3 + & (1) & (2) & (3) & (4) & (5) & (6) & (7) \\
4 4 \midrule
5 −log_rent & 1.00 & 0.14 & 0.14 & 0.07 & 0.07 & 0.53 & 0.60 \\
6 −airbnb_count_500m & 0.14 & 1.00 & 1.00 & 0.07 & -0.19 & -0.19 & 0.00 \\
7 −airbnb_density_500m & 0.14 & 1.00 & 1.00 & 0.07 & -0.19 & -0.19 & 0.00 \\
8 −mean_airbnb_price_500m & 0.07 & 0.07 & 0.07 & 1.00 & 0.14 & 0.02 & 0.07 \\
9 −share_entire_home_500m & 0.07 & -0.19 & -0.19 & 0.14 & 1.00 & 0.08 & 0.08 \\
10 −bedrooms & 0.53 & -0.19 & -0.19 & 0.02 & 0.08 & 1.00 & 0.48 \\
11 −bathrooms & 0.60 & 0.00 & 0.00 & 0.07 & 0.08 & 0.48 & 1.00 \\
5 +(1) Log monthly rent & 1.00 & & & & & & \\
6 +(2) Airbnb count (500 m) & 0.14 & 1.00 & & & & & \\
7 +(3) Airbnb density (500 m) & 0.14 & 1.00 & 1.00 & & & & \\
8 +(4) Mean Airbnb price (500 m) & 0.07 & 0.07 & 0.07 & 1.00 & & & \\
9 +(5) Entire-home share (500 m) & 0.07 & -0.19 & -0.19 & 0.14 & 1.00 & & \\
10 +(6) Bedrooms & 0.53 & -0.19 & -0.19 & 0.02 & 0.08 & 1.00 & \\
11 +(7) Bathrooms & 0.60 & 0.00 & 0.00 & 0.08 & 0.08 & 0.48 & 1.00 \\
12 12 \bottomrule
13 13 \end{tabular}
14 +\parbox{\textwidth}{\footnotesize Pearson correlations on the 4,370 rental listings with at least one Airbnb listing within 500\,m (the composition variables are undefined otherwise). At a fixed radius the density is a rescaling of the count, hence the correlation of 1.00.}
added results/tables/exposure_summary.csv +5 −0
@@ -0,0 +1,5 @@
1 +Radius,N,Mean,SD,Median,P90,Max,Share zero
2 +250 m,8303,2.4143080814163556,4.941878281499877,0.0,9.0,33,0.6118270504636878
3 +500 m,8303,7.920631097193786,14.199327381392465,1.0,30.0,84,0.44056365169215944
4 +1 km,8303,26.72853185595568,41.96470983975552,4.0,103.0,206,0.27411778875105386
5 +2 km,8303,81.4541731904131,118.89710508990204,16.0,280.8000000000002,438,0.13043478260869565
added results/tables/exposure_summary.tex +11 −0
@@ -0,0 +1,11 @@
1 +\begin{tabular}{lrrrrrrr}
2 +\toprule
3 +Radius & N & Mean & SD & Median & P90 & Max & Share zero \\
4 +\midrule
5 +250 m & 8,303 & 2.41 & 4.94 & 0 & 9 & 33 & 0.612 \\
6 +500 m & 8,303 & 7.92 & 14.20 & 1 & 30 & 84 & 0.441 \\
7 +1 km & 8,303 & 26.73 & 41.96 & 4 & 103 & 206 & 0.274 \\
8 +2 km & 8,303 & 81.45 & 118.90 & 16 & 281 & 438 & 0.130 \\
9 +\bottomrule
10 +\end{tabular}
11 +\parbox{\textwidth}{\footnotesize Number of Airbnb listings within each radius of a rental listing (Haversine distance), over all rental listings with valid coordinates. ``Share zero'' is the fraction of rental listings with no Airbnb listing within the radius.}
modified results/tables/extended_robustness.tex +2 −1
@@ -1,7 +1,7 @@
1 1 \begin{tabular}{lccccc}
2 2 \toprule
3 3 & \textbf{(R1)} & \textbf{(R2)} & \textbf{(R3)} & \textbf{(R4)} & \textbf{(R5)} \\
4 −Dep.\ var: & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} \\
4 +Dep.\ var: & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} \\
5 5 \midrule
6 6 Airbnb count (500m) & 0.0039*** & 0.0039*** & 0.0032*** & & 0.0013*** \\
7 7 & (0.0002) & (0.0001) & (0.0003) & & (0.0003) \\[4pt]
@@ -17,6 +17,7 @@ Interior size (100 sq ft) & & & 0.0044*** & & \\
17 17 & & & (0.0017) & & \\[4pt]
18 18 \midrule
19 19 Standard errors & HC1 & City cluster & HC1 & HC1 & HC1 \\
20 +Clusters & & 252 & & & \\
20 21 Building type \& city FE & Yes & Yes & Yes & Yes & Yes \\
21 22 Observations & 7,925 & 7,925 & 3,531 & 7,925 & 7,925 \\
22 23 R$^2$ & 0.5697 & 0.5697 & 0.6044 & 0.5726 & 0.5786 \\
modified results/tables/hedonic_airbnb_pricing.tex +23 −23
@@ -1,31 +1,31 @@
1 1 \small
2 −\begin{tabular}{lccc}
2 +\begin{tabular}{lccccc}
3 3 \toprule
4 − & \textbf{(2a)} & \textbf{(2b)} & \textbf{(2c)} \\
5 −Dep.\ var: & \textit{log\_price} & \textit{log\_price} & \textit{log\_price} \\
4 + & \textbf{(2a)} & \textbf{(2b)} & \textbf{(2c)} & \textbf{(2d)} & \textbf{(2e)} \\
5 +Dep.\ var: & \multicolumn{5}{c}{\textit{log nightly price}} \\
6 6 \midrule
7 −const & 6.1958*** & 6.3698*** & 4.7948*** \\
8 − & (0.8696) & (0.8889) & (0.7004) \\[4pt]
9 −mean\_rent\_city & -0.0296 & -0.0531 & 0.0307 \\
10 − & (0.1129) & (0.1180) & (0.1039) \\[4pt]
11 −bedrooms & & 0.0923** & 0.0852* \\
12 − & & (0.0448) & (0.0457) \\[4pt]
13 −bathrooms & & 0.1555*** & 0.1226*** \\
14 − & & (0.0428) & (0.0458) \\[4pt]
15 −guests\_count & & -0.0409** & -0.0187 \\
16 − & & (0.0182) & (0.0190) \\[4pt]
17 −amenities\_count & & 0.0008 & 0.0019 \\
18 − & & (0.0022) & (0.0024) \\[4pt]
19 −is\_superhost & & -0.3467*** & -0.2766*** \\
20 − & & (0.0621) & (0.0651) \\[4pt]
21 −is\_entire\_home & & -0.0722 & 0.1670** \\
22 − & & (0.0661) & (0.0749) \\[4pt]
7 +Constant & 6.1958*** & 6.3698*** & 5.0498*** & 4.4077*** & 4.3390*** \\
8 + & (0.8696) & (0.8889) & (0.2040) & (0.3910) & (0.1535) \\[4pt]
9 +City mean log rent & -0.0296 & -0.0531 & & 0.0029 & \\
10 + & (0.1129) & (0.1180) & & (0.0520) & \\[4pt]
11 +Bedrooms & & 0.0923** & 0.0852* & 0.1404*** & 0.1512*** \\
12 + & & (0.0448) & (0.0457) & (0.0271) & (0.0283) \\[4pt]
13 +Bathrooms & & 0.1555*** & 0.1226*** & 0.1654*** & 0.1494*** \\
14 + & & (0.0428) & (0.0458) & (0.0325) & (0.0359) \\[4pt]
15 +Guest capacity & & -0.0409** & -0.0187 & -0.0005 & -0.0014 \\
16 + & & (0.0182) & (0.0190) & (0.0107) & (0.0115) \\[4pt]
17 +Amenities count & & 0.0008 & 0.0019 & 0.0032*** & 0.0035*** \\
18 + & & (0.0022) & (0.0024) & (0.0012) & (0.0013) \\[4pt]
19 +Superhost (0/1) & & -0.3467*** & -0.2766*** & 0.0141 & 0.0420 \\
20 + & & (0.0621) & (0.0651) & (0.0336) & (0.0358) \\[4pt]
21 +Entire home (0/1) & & -0.0722 & 0.1670** & 0.0396 & 0.1368*** \\
22 + & & (0.0661) & (0.0749) & (0.0374) & (0.0464) \\[4pt]
23 23 \midrule
24 −Observations & 2437 & 2437 & 2437 \\
25 −R$^2$ & 0.0000 & 0.0300 & 0.1404 \\
26 −Adj.\ R$^2$ & -0.0004 & 0.0272 & 0.0804 \\
24 +Observations & 2,437 & 2,437 & 2,437 & 1,699 & 1,699 \\
25 +R$^2$ & 0.0000 & 0.0300 & 0.1404 & 0.2055 & 0.2981 \\
26 +Adj.\ R$^2$ & -0.0004 & 0.0272 & 0.0804 & 0.2022 & 0.2340 \\
27 27 \bottomrule
28 28 \end{tabular}
29 29 \vspace{4pt}
30 −\parbox{\textwidth}{\footnotesize Model (2c) includes city fixed effects (not shown).}
30 +\parbox{\textwidth}{\footnotesize Columns (2c) and (2e) include city fixed effects (not shown), which absorb the city mean log rent. Columns (2a)--(2c) use all listings with a matched city; columns (2d)--(2e) restrict the sample to listings with a nightly price of at most \$1,000 (see Section~3).}
31 31 \parbox{\textwidth}{\footnotesize Robust (HC1) standard errors in parentheses. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
modified results/tables/hedonic_rent_baseline.tex +10 −10
@@ -2,26 +2,26 @@
2 2 \begin{tabular}{lccccc}
3 3 \toprule
4 4 & \textbf{(1a)} & \textbf{(1b)} & \textbf{(1c)} & \textbf{(1d)} & \textbf{(1e)} \\
5 −Dep.\ var: & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} \\
5 +Dep.\ var: & \multicolumn{5}{c}{\textit{log rent}} \\
6 6 \midrule
7 −const & 7.5990*** & 7.0390*** & 7.2380*** & 7.2380*** & 7.2766*** \\
7 +Constant & 7.5990*** & 7.0390*** & 7.2380*** & 7.2380*** & 7.2766*** \\
8 8 & (0.0040) & (0.0139) & (0.0677) & (0.0677) & (0.0332) \\[4pt]
9 −airbnb\_count\_500m & 0.0020*** & 0.0048*** & 0.0039*** & & \\
9 +Airbnb count (500 m) & 0.0020*** & 0.0048*** & 0.0039*** & & \\
10 10 & (0.0003) & (0.0002) & (0.0002) & & \\[4pt]
11 −airbnb\_density\_500m & & & & 0.0030*** & \\
11 +Airbnb density (500 m, per km$^2$) & & & & 0.0030*** & \\
12 12 & & & & (0.0002) & \\[4pt]
13 −share\_entire\_home\_500m & & & & & -0.0041 \\
13 +Entire-home share (500 m) & & & & & -0.0041 \\
14 14 & & & & & (0.0107) \\[4pt]
15 −bedrooms & & 0.1118*** & 0.1276*** & 0.1276*** & 0.1215*** \\
15 +Bedrooms & & 0.1118*** & 0.1276*** & 0.1276*** & 0.1215*** \\
16 16 & & (0.0046) & (0.0046) & (0.0046) & (0.0057) \\[4pt]
17 −bathrooms & & 0.2604*** & 0.2287*** & 0.2287*** & 0.3033*** \\
17 +Bathrooms & & 0.2604*** & 0.2287*** & 0.2287*** & 0.3033*** \\
18 18 & & (0.0128) & (0.0126) & (0.0126) & (0.0104) \\[4pt]
19 −bt\_House & & 0.0880*** & 0.0825*** & 0.0825*** & 0.0305 \\
19 +House & & 0.0880*** & 0.0825*** & 0.0825*** & 0.0305 \\
20 20 & & (0.0128) & (0.0137) & (0.0137) & (0.0260) \\[4pt]
21 −bt\_Row / Townhouse & & 0.1493*** & 0.0981*** & 0.0981*** & 0.1187* \\
21 +Row/townhouse & & 0.1493*** & 0.0981*** & 0.0981*** & 0.1187* \\
22 22 & & (0.0375) & (0.0366) & (0.0366) & (0.0695) \\[4pt]
23 23 \midrule
24 −Observations & 8303 & 7925 & 7925 & 7925 & 4370 \\
24 +Observations & 8,303 & 7,925 & 7,925 & 7,925 & 4,370 \\
25 25 R$^2$ & 0.0075 & 0.4705 & 0.5697 & 0.5697 & 0.4961 \\
26 26 Adj.\ R$^2$ & 0.0074 & 0.4702 & 0.5554 & 0.5554 & 0.4857 \\
27 27 \bottomrule
added results/tables/inference_comparison.tex +20 −0
@@ -0,0 +1,20 @@
1 +\begin{tabular}{lcccc}
2 +\toprule
3 + & \multicolumn{2}{c}{\textbf{City FE (Model 1c)}} & \multicolumn{2}{c}{\textbf{FSA FE (F2)}} \\
4 + & \multicolumn{2}{c}{$\hat\beta = 0.0039$} & \multicolumn{2}{c}{$\hat\beta = 0.0008$} \\
5 +\cmidrule(lr){2-3}\cmidrule(lr){4-5}
6 +Standard errors & SE & $t$ & SE & $t$ \\
7 +\midrule
8 +Heteroskedasticity-robust (HC1) & (0.0002) & 17.3 & (0.0004) & 2.3 \\
9 +Clustered by city & (0.0001) & 35.7 & (0.0004) & 2.3 \\
10 +Clustered by FSA & (0.0007) & 5.9 & (0.0007) & 1.1 \\
11 +Conley spatial HAC, 1\,km cutoff & (0.0007) & 5.6 & (0.0007) & 1.1 \\
12 +Conley spatial HAC, 2\,km cutoff & (0.0007) & 5.3 & (0.0007) & 1.2 \\
13 +Conley spatial HAC, 5\,km cutoff & (0.0007) & 5.9 & (0.0005) & 1.7 \\
14 +Conley spatial HAC, 10\,km cutoff & (0.0007) & 5.4 & (0.0004) & 2.0 \\
15 +\midrule
16 +City clusters & \multicolumn{2}{c}{187} & \multicolumn{2}{c}{239} \\
17 +FSA clusters & \multicolumn{2}{c}{318} & \multicolumn{2}{c}{289} \\
18 +\bottomrule
19 +\end{tabular}
20 +\parbox{\textwidth}{\footnotesize Coefficient on the Airbnb count within 500\,m from the specification in the column (controls: bedrooms, bathrooms, building type; fixed effects absorbed, singleton groups dropped). Each row reports the standard error (in parentheses) and the implied $t$-statistic under a different covariance estimator: heteroskedasticity-robust (HC1); clustered by city and by FSA \citep{cameron2015practitioner}; and Conley spatial HAC with a Bartlett kernel declining linearly to zero at the stated great-circle cutoff \citep{conley1999gmm, kelejian2007hac}. Listings in the same building (identical coordinates) receive full weight in the Conley estimator.}
modified results/tables/ml_comparison.csv +1 −1
@@ -2,5 +2,5 @@ Model,R2_train,R2_test,RMSE_test,MAE_test
2 2 OLS,0.4741177154267531,0.5093654009877304,0.2242232339592205,0.17265875039921771
3 3 LASSO,0.47400794165005944,0.5099410720642269,0.22409165261983835,0.17251231878346804
4 4 Elastic Net,0.4739978180099471,0.5099126726551279,0.22409814569440273,0.17251299831932632
5 −Random Forest,0.9092409107926911,0.7079038624040863,0.1730073021177198,0.12841586215699632
5 +Random Forest,0.9092409107926911,0.7079038624040863,0.17300730211771984,0.12841586215699638
6 6 Gradient Boosting,0.8761672438495761,0.6934733510541368,0.17722935025730183,0.13190366914337534
added results/tables/ml_spatial_cv.csv +11 −0
@@ -0,0 +1,11 @@
1 +Design,Model,R2_cv,R2_cv_sd,RMSE_cv,MAE_cv
2 +Random 5-fold,OLS,0.4767076331125123,0.04054722349061911,0.2255771266817554,0.17367935309880062
3 +Random 5-fold,LASSO,0.47673153613132635,0.040554192264607894,0.2255718098071567,0.17367792732131973
4 +Random 5-fold,Elastic Net,0.47673259367703996,0.04054751835127774,0.22557164415526793,0.17367734600694149
5 +Random 5-fold,Random Forest,0.6473394091066538,0.044454131015486974,0.18488569332444751,0.13427520586888061
6 +Random 5-fold,Gradient Boosting,0.6537602112116933,0.0333646036728153,0.18337054845145911,0.1340073861246052
7 +Spatial 5-fold (FSA blocks),OLS,0.46669839736186525,0.05390403238845947,0.22613104234144404,0.17515714047744316
8 +Spatial 5-fold (FSA blocks),LASSO,0.4667783875687994,0.053833944469573486,0.22611524844683478,0.1751548599523451
9 +Spatial 5-fold (FSA blocks),Elastic Net,0.466783386669559,0.05382806350601209,0.2261144532756453,0.17515379065364373
10 +Spatial 5-fold (FSA blocks),Random Forest,0.4307191973013116,0.15936091944991487,0.23057849136384984,0.18030848998522503
11 +Spatial 5-fold (FSA blocks),Gradient Boosting,0.4139534665246014,0.1076356830391546,0.23553967385855987,0.18421799014046447
added results/tables/ml_spatial_cv.tex +21 −0
@@ -0,0 +1,21 @@
1 +\begin{tabular}{lcccc}
2 +\toprule
3 +Model & $R^2$ (mean) & $R^2$ (s.d.) & RMSE & MAE \\
4 +\midrule
5 +\multicolumn{5}{l}{\textit{Random 5-fold}} \\
6 +OLS & 0.4767 & 0.0405 & 0.2256 & 0.1737 \\
7 +LASSO & 0.4767 & 0.0406 & 0.2256 & 0.1737 \\
8 +Elastic Net & 0.4767 & 0.0405 & 0.2256 & 0.1737 \\
9 +Random Forest & 0.6473 & 0.0445 & 0.1849 & 0.1343 \\
10 +Gradient Boosting & 0.6538 & 0.0334 & 0.1834 & 0.1340 \\
11 +\addlinespace
12 +\multicolumn{5}{l}{\textit{Spatial 5-fold (FSA blocks)}} \\
13 +OLS & 0.4667 & 0.0539 & 0.2261 & 0.1752 \\
14 +LASSO & 0.4668 & 0.0538 & 0.2261 & 0.1752 \\
15 +Elastic Net & 0.4668 & 0.0538 & 0.2261 & 0.1752 \\
16 +Random Forest & 0.4307 & 0.1594 & 0.2306 & 0.1803 \\
17 +Gradient Boosting & 0.4140 & 0.1076 & 0.2355 & 0.1842 \\
18 +\addlinespace
19 +\bottomrule
20 +\end{tabular}
21 +\parbox{\textwidth}{\footnotesize Five-fold cross-validation of the models in Table~\ref{tab:ml_performance} on the same features and sample. Random folds shuffle listings; spatial folds assign whole forward sortation areas (181 FSA groups) to folds, so no test listing shares a neighbourhood with a training listing. Metrics are averaged over the five test folds; $R^2$ (s.d.) is the standard deviation across folds.}
added results/tables/neighbourhood_fe.json +164 −0
@@ -0,0 +1,164 @@
1 +{
2 + "F1 city FE": {
3 + "n": 7860,
4 + "groups": 187,
5 + "r2": 0.5635535940968947,
6 + "within_r2": 0.47025373885472554,
7 + "beta": {
8 + "airbnb_count_500m": 0.0038775338645417596,
9 + "bedrooms": 0.1275728983805275,
10 + "bathrooms": 0.2287446987855085,
11 + "bt_House": 0.08249565872431627,
12 + "bt_Row / Townhouse": 0.0981297168224721
13 + },
14 + "se_hc1": {
15 + "airbnb_count_500m": 0.00022392591745188148,
16 + "bedrooms": 0.004610655065018604,
17 + "bathrooms": 0.012528259656156036,
18 + "bt_House": 0.01367913484529655,
19 + "bt_Row / Townhouse": 0.03640094001964113
20 + }
21 + },
22 + "F2 FSA FE": {
23 + "n": 7883,
24 + "groups": 289,
25 + "r2": 0.6306056679526807,
26 + "within_r2": 0.5188560508389339,
27 + "beta": {
28 + "airbnb_count_500m": 0.0008187211004110956,
29 + "bedrooms": 0.15008796520670636,
30 + "bathrooms": 0.19800180745348286,
31 + "bt_House": 0.11403052482249038,
32 + "bt_Row / Townhouse": 0.13105397648415198
33 + },
34 + "se_hc1": {
35 + "airbnb_count_500m": 0.00036159891548742526,
36 + "bedrooms": 0.004678375032726685,
37 + "bathrooms": 0.012014288587224585,
38 + "bt_House": 0.01334042709781099,
39 + "bt_Row / Townhouse": 0.03499489388996995
40 + }
41 + },
42 + "F3 FSA FE 250m": {
43 + "n": 7883,
44 + "groups": 289,
45 + "r2": 0.6303268667206028,
46 + "within_r2": 0.5184929063231817,
47 + "beta": {
48 + "airbnb_count_250m": 0.0008111504037652498,
49 + "bedrooms": 0.15021375634890302,
50 + "bathrooms": 0.19777094625135722,
51 + "bt_House": 0.11381109853120383,
52 + "bt_Row / Townhouse": 0.13201265733874115
53 + },
54 + "se_hc1": {
55 + "airbnb_count_250m": 0.0008576997668286085,
56 + "bedrooms": 0.004680665963590751,
57 + "bathrooms": 0.01200962017675934,
58 + "bt_House": 0.013333292001032572,
59 + "bt_Row / Townhouse": 0.03512456159497399
60 + }
61 + },
62 + "F4 FSA FE any+count": {
63 + "n": 7883,
64 + "groups": 289,
65 + "r2": 0.6312572692208716,
66 + "within_r2": 0.5197047753055984,
67 + "beta": {
68 + "any_airbnb_500m": -0.027887526421282897,
69 + "airbnb_count_500m": 0.0009690236028595645,
70 + "bedrooms": 0.15003379909897335,
71 + "bathrooms": 0.1979325754598122,
72 + "bt_House": 0.11357342514554149,
73 + "bt_Row / Townhouse": 0.1324703708961111
74 + },
75 + "se_hc1": {
76 + "any_airbnb_500m": 0.00877486450038345,
77 + "airbnb_count_500m": 0.0003633535388213336,
78 + "bedrooms": 0.0046810935109620495,
79 + "bathrooms": 0.012034673584690375,
80 + "bt_House": 0.013375201936212692,
81 + "bt_Row / Townhouse": 0.035079344390116965
82 + }
83 + },
84 + "F5 FSA FE log1p": {
85 + "n": 7883,
86 + "groups": 289,
87 + "r2": 0.6302763845426398,
88 + "within_r2": 0.518427152216093,
89 + "beta": {
90 + "log1p_airbnb_500m": 0.002230048510269144,
91 + "bedrooms": 0.1502269235033579,
92 + "bathrooms": 0.19778751726403787,
93 + "bt_House": 0.11380706009528352,
94 + "bt_Row / Townhouse": 0.13177538387799423
95 + },
96 + "se_hc1": {
97 + "log1p_airbnb_500m": 0.005297108132052599,
98 + "bedrooms": 0.004678656054371134,
99 + "bathrooms": 0.012008420492194834,
100 + "bt_House": 0.013353021069268391,
101 + "bt_Row / Townhouse": 0.03511205054097275
102 + }
103 + },
104 + "F6 FSA FE + size": {
105 + "n": 3485,
106 + "groups": 222,
107 + "r2": 0.6505086402617897,
108 + "within_r2": 0.5325749316032939,
109 + "beta": {
110 + "airbnb_count_500m": 0.0003266759210386489,
111 + "bedrooms": 0.1478682952840955,
112 + "bathrooms": 0.18921328724817668,
113 + "size_100sqft": 0.003987343286219144,
114 + "bt_House": 0.0757071442827295,
115 + "bt_Row / Townhouse": 0.0808665881741878
116 + },
117 + "se_hc1": {
118 + "airbnb_count_500m": 0.0005794699184374527,
119 + "bedrooms": 0.008335843610699138,
120 + "bathrooms": 0.02003860605736048,
121 + "size_100sqft": 0.0016409258714837286,
122 + "bt_House": 0.022891359172576658,
123 + "bt_Row / Townhouse": 0.042355587812266775
124 + }
125 + },
126 + "bivariate": {
127 + "beta": 0.0019685033544233448,
128 + "se": 0.0002561015843052032,
129 + "r2": 0.0074907162076266465,
130 + "n": 8303
131 + },
132 + "inference": [
133 + {
134 + "spec": "City FE (Model 1c)",
135 + "beta": 0.0038775338645417596,
136 + "se_hc1": 0.00022392591745188148,
137 + "se_city": 0.00010876238813215868,
138 + "se_fsa": 0.000654139351263461,
139 + "se_conley": {
140 + "1.0": 0.000689320515796654,
141 + "2.0": 0.000728460152066934,
142 + "5.0": 0.0006546244138262017,
143 + "10.0": 0.0007211154682556746
144 + },
145 + "n_city": 187,
146 + "n_fsa": 318
147 + },
148 + {
149 + "spec": "FSA FE (F2)",
150 + "beta": 0.0008187211004110956,
151 + "se_hc1": 0.00036159891548742526,
152 + "se_city": 0.0003592918263770114,
153 + "se_fsa": 0.0007273298299465931,
154 + "se_conley": {
155 + "1.0": 0.0007193035903288408,
156 + "2.0": 0.0006840163474196736,
157 + "5.0": 0.0004733988020595961,
158 + "10.0": 0.00040401772755342094
159 + },
160 + "n_city": 239,
161 + "n_fsa": 289
162 + }
163 + ]
164 +}
\ No newline at end of file
added results/tables/neighbourhood_fe.tex +28 −0
@@ -0,0 +1,28 @@
1 +\begin{tabular}{lcccccc}
2 +\toprule
3 + & \textbf{(F1)} & \textbf{(F2)} & \textbf{(F3)} & \textbf{(F4)} & \textbf{(F5)} & \textbf{(F6)} \\
4 +Dep.\ var: & \multicolumn{6}{c}{\textit{log rent}} \\
5 +\midrule
6 +Any Airbnb within 500 m (0/1) & & & & -0.0279*** & & \\
7 + & & & & (0.0088) & & \\[4pt]
8 +Airbnb count (500 m) & 0.0039*** & 0.0008** & & 0.0010*** & & 0.0003 \\
9 + & (0.0002) & (0.0004) & & (0.0004) & & (0.0006) \\[4pt]
10 +Airbnb count (250 m) & & & 0.0008 & & & \\
11 + & & & (0.0009) & & & \\[4pt]
12 +log(1 + Airbnb count, 500 m) & & & & & 0.0022 & \\
13 + & & & & & (0.0053) & \\[4pt]
14 +Bedrooms & 0.1276*** & 0.1501*** & 0.1502*** & 0.1500*** & 0.1502*** & 0.1479*** \\
15 + & (0.0046) & (0.0047) & (0.0047) & (0.0047) & (0.0047) & (0.0083) \\[4pt]
16 +Bathrooms & 0.2287*** & 0.1980*** & 0.1978*** & 0.1979*** & 0.1978*** & 0.1892*** \\
17 + & (0.0125) & (0.0120) & (0.0120) & (0.0120) & (0.0120) & (0.0200) \\[4pt]
18 +Interior size (100 sq ft) & & & & & & 0.0040** \\
19 + & & & & & & (0.0016) \\[4pt]
20 +\midrule
21 +Fixed effects & City & FSA & FSA & FSA & FSA & FSA \\
22 +FE groups & 187 & 289 & 289 & 289 & 289 & 222 \\
23 +Observations & 7,860 & 7,883 & 7,883 & 7,883 & 7,883 & 3,485 \\
24 +R$^2$ & 0.5636 & 0.6306 & 0.6303 & 0.6313 & 0.6303 & 0.6505 \\
25 +Within R$^2$ & 0.4703 & 0.5189 & 0.5185 & 0.5197 & 0.5184 & 0.5326 \\
26 +\bottomrule
27 +\end{tabular}
28 +\parbox{\textwidth}{\footnotesize Heteroskedasticity-robust (HC1) standard errors in parentheses. All columns control for bedrooms, bathrooms and building type; fixed effects are absorbed (within transformation) and singleton groups are dropped. FSA = forward sortation area (first three characters of the postal code). Column (F3) uses the 250\,m count; column (F6) adds interior size on the subsample reporting it. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
modified results/tables/quantile_regression.tex +7 −7
@@ -1,19 +1,19 @@
1 1 \begin{tabular}{lcccccc}
2 2 \toprule
3 3 & \textbf{$\tau=0.10$} & \textbf{$\tau=0.25$} & \textbf{$\tau=0.50$} & \textbf{$\tau=0.75$} & \textbf{$\tau=0.90$} & \textbf{OLS} \\
4 −Dep.\ var: & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} & \textit{log\_rent} \\
4 +Dep.\ var: & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} & \textit{log rent} \\
5 5 \midrule
6 −const & 6.8249*** & 6.9035*** & 7.0339*** & 7.1237*** & 7.2461*** & 7.0508*** \\
6 +Constant & 6.8249*** & 6.9035*** & 7.0339*** & 7.1237*** & 7.2461*** & 7.0508*** \\
7 7 & (0.0258) & (0.0211) & (0.0209) & (0.0221) & (0.0328) & (0.0197) \\[4pt]
8 −airbnb\_count\_500m & 0.0037*** & 0.0034*** & 0.0035*** & 0.0041*** & 0.0047*** & 0.0038*** \\
8 +Airbnb count (500 m) & 0.0037*** & 0.0034*** & 0.0035*** & 0.0041*** & 0.0047*** & 0.0038*** \\
9 9 & (0.0003) & (0.0003) & (0.0002) & (0.0002) & (0.0003) & (0.0002) \\[4pt]
10 −bedrooms & 0.1236*** & 0.1034*** & 0.1071*** & 0.1360*** & 0.1418*** & 0.1152*** \\
10 +Bedrooms & 0.1236*** & 0.1034*** & 0.1071*** & 0.1360*** & 0.1418*** & 0.1152*** \\
11 11 & (0.0058) & (0.0043) & (0.0039) & (0.0038) & (0.0055) & (0.0046) \\[4pt]
12 −bathrooms & 0.2411*** & 0.2796*** & 0.2748*** & 0.2669*** & 0.2807*** & 0.2571*** \\
12 +Bathrooms & 0.2411*** & 0.2796*** & 0.2748*** & 0.2669*** & 0.2807*** & 0.2571*** \\
13 13 & (0.0103) & (0.0076) & (0.0072) & (0.0076) & (0.0115) & (0.0125) \\[4pt]
14 −bt\_House & 0.0608*** & 0.1079*** & 0.1382*** & 0.1079*** & 0.1094*** & 0.1201*** \\
14 +House & 0.0608*** & 0.1079*** & 0.1382*** & 0.1079*** & 0.1094*** & 0.1201*** \\
15 15 & (0.0139) & (0.0119) & (0.0120) & (0.0131) & (0.0205) & (0.0131) \\[4pt]
16 −bt\_Row / Townhouse & 0.1310*** & 0.0858** & 0.1602*** & 0.2501*** & 0.2274*** & 0.1753*** \\
16 +Row/townhouse & 0.1310*** & 0.0858** & 0.1602*** & 0.2501*** & 0.2274*** & 0.1753*** \\
17 17 & (0.0468) & (0.0383) & (0.0383) & (0.0417) & (0.0625) & (0.0378) \\[4pt]
18 18 \midrule
19 19 City FE (top 5) & Yes & Yes & Yes & Yes & Yes & Yes \\
modified results/tables/robustness_subsamples.tex +4 −4
@@ -2,11 +2,11 @@
2 2 \toprule
3 3 & (1) Montreal & (2) Outside Mtl & (3) Apartments & (4) Houses \\
4 4 \midrule
5 −Airbnb count (500m) & 0.003865*** & 0.003046* & 0.003860*** & 0.006699*** \\
6 − & (0.000226) & (0.001580) & (0.000226) & (0.001995) \\
5 +Airbnb count (500m) & 0.003865*** & 0.003046* & 0.003860*** & 0.005857** \\
6 + & (0.000226) & (0.001580) & (0.000226) & (0.002348) \\
7 7 \midrule
8 −N & 4,578 & 3,347 & 7,136 & 789 \\
9 −$R^2$ & 0.4587 & 0.6959 & 0.5046 & 0.6403 \\
8 +N & 4,578 & 3,347 & 7,136 & 741 \\
9 +$R^2$ & 0.4587 & 0.6959 & 0.5046 & 0.6441 \\
10 10 City FE & Yes & Yes & Yes & Yes \\
11 11 \bottomrule
12 12 \end{tabular}
added results/tables/spatial_impacts.tex +17 −0
@@ -0,0 +1,17 @@
1 +\begin{tabular}{lccc}
2 +\toprule
3 + & \textbf{Direct} & \textbf{Indirect} & \textbf{Total} \\
4 +\midrule
5 +Airbnb count (500 m) & 0.0034*** & 0.0005*** & 0.0040*** \\
6 + & (0.0002) & (0.0001) & (0.0002) \\[4pt]
7 +Bedrooms & 0.1225*** & 0.0186*** & 0.1411*** \\
8 + & (0.0043) & (0.0037) & (0.0065) \\[4pt]
9 +Bathrooms & 0.2291*** & 0.0348*** & 0.2639*** \\
10 + & (0.0125) & (0.0060) & (0.0127) \\[4pt]
11 +\midrule
12 +$\hat\rho$ & \multicolumn{3}{c}{0.1340} \\
13 +$n^{-1}\,\mathrm{tr}[(I-\hat\rho W)^{-1}]$ & \multicolumn{3}{c}{1.0026} \\
14 +Observations & \multicolumn{3}{c}{7,925} \\
15 +\bottomrule
16 +\end{tabular}
17 +\parbox{\textwidth}{\footnotesize Average direct, indirect and total impacts of the SAR model in Table~\ref{tab:spatial_results} \citep{lesage2009introduction}: total $=\hat\beta/(1-\hat\rho)$, direct $=\hat\beta\, n^{-1}\mathrm{tr}[(I-\hat\rho W)^{-1}]$, indirect $=$ total $-$ direct. Standard errors in parentheses from 2,000 draws of $(\hat\beta,\hat\rho)$ from their estimated asymptotic normal distribution. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
added results/tables/spatial_models.json +114 −0
@@ -0,0 +1,114 @@
1 +{
2 + "rho": 0.13399821282277458,
3 + "rho_se": 0.022215750437387934,
4 + "lambda": 0.5436869183136613,
5 + "sar": {
6 + "const": {
7 + "beta": 6.095784423859868,
8 + "se": 0.16534745496455436
9 + },
10 + "airbnb_count_500m": {
11 + "beta": 0.0034236794573713203,
12 + "se": 0.00021982601866927295
13 + },
14 + "bedrooms": {
15 + "beta": 0.12216652363972003,
16 + "se": 0.004355824190413317
17 + },
18 + "bathrooms": {
19 + "beta": 0.2285563599141014,
20 + "se": 0.012685719500362876
21 + },
22 + "bt_House": {
23 + "beta": 0.1181880488732574,
24 + "se": 0.01237521379360706
25 + },
26 + "bt_Row / Townhouse": {
27 + "beta": 0.16152692979274264,
28 + "se": 0.03325145575219913
29 + }
30 + },
31 + "sem": {
32 + "const": {
33 + "beta": 7.091828870044253,
34 + "se": 0.03307557745896154
35 + },
36 + "airbnb_count_500m": {
37 + "beta": 0.003948175822691717,
38 + "se": 0.0003601170668095246
39 + },
40 + "bedrooms": {
41 + "beta": 0.1548761218810486,
42 + "se": 0.0030125750329569466
43 + },
44 + "bathrooms": {
45 + "beta": 0.1797375521762241,
46 + "se": 0.005660736517606748
47 + },
48 + "bt_House": {
49 + "beta": 0.12613827967770175,
50 + "se": 0.009709805529421519
51 + },
52 + "bt_Row / Townhouse": {
53 + "beta": 0.15326738289458158,
54 + "se": 0.029535553435192846
55 + }
56 + },
57 + "ols": {
58 + "const": {
59 + "beta": 7.111444786275632,
60 + "se": 0.02110740993616811
61 + },
62 + "airbnb_count_500m": {
63 + "beta": 0.0038261544263680524,
64 + "se": 0.00022101903121251077
65 + },
66 + "bedrooms": {
67 + "beta": 0.11939644964679495,
68 + "se": 0.004499575281628543
69 + },
70 + "bathrooms": {
71 + "beta": 0.24321995237581767,
72 + "se": 0.01231168399426723
73 + },
74 + "bt_House": {
75 + "beta": 0.1342117572093995,
76 + "se": 0.0131071339537161
77 + },
78 + "bt_Row / Townhouse": {
79 + "beta": 0.1781601995586926,
80 + "se": 0.03593071885504502
81 + }
82 + },
83 + "impacts": {
84 + "airbnb_count_500m": {
85 + "direct": 0.0034325049012571118,
86 + "indirect": 0.000520927421938165,
87 + "total": 0.003953432323195277,
88 + "direct_se": 0.00021645382185272612,
89 + "indirect_se": 9.581122458766436e-05,
90 + "total_se": 0.0002416709566070393
91 + },
92 + "bedrooms": {
93 + "direct": 0.12248144032877607,
94 + "indirect": 0.01858815727324238,
95 + "total": 0.14106959760201845,
96 + "direct_se": 0.00429689276044209,
97 + "indirect_se": 0.0036888578789685124,
98 + "total_se": 0.0064680052476288954
99 + },
100 + "bathrooms": {
101 + "direct": 0.22914552468676133,
102 + "indirect": 0.03477582432002521,
103 + "total": 0.26392134900678654,
104 + "direct_se": 0.012515791369733801,
105 + "indirect_se": 0.005994381180230466,
106 + "total_se": 0.012742881397688276
107 + }
108 + },
109 + "mean_diag_exact": 1.0025777658205677,
110 + "n": 7925,
111 + "sar_pr2": 0.5507553778080813,
112 + "sem_pr2": 0.49732269162904447,
113 + "ols_r2": 0.5081291712321784
114 +}
\ No newline at end of file
modified results/tables/spatial_models.tex +17 −17
@@ -1,26 +1,26 @@
1 1 \begin{tabular}{lccc}
2 2 \toprule
3 3 & \textbf{OLS} & \textbf{SAR (GM\_Lag)} & \textbf{SEM (GM\_Error)} \\
4 −Dep.\ var: & \multicolumn{3}{c}{\textit{log\_rent}} \\
4 +Dep.\ var: & \multicolumn{3}{c}{\textit{log rent}} \\
5 5 \midrule
6 −const & 7.1114*** & 6.0767*** & 7.0905*** \\
7 − & (0.0211) & (0.1514) & (0.0328) \\[4pt]
8 −airbnb\_count\_500m & 0.0038*** & 0.0034*** & 0.0038*** \\
6 +Constant & 7.1114*** & 6.0958*** & 7.0918*** \\
7 + & (0.0211) & (0.1653) & (0.0331) \\[4pt]
8 +Airbnb count (500 m) & 0.0038*** & 0.0034*** & 0.0039*** \\
9 9 & (0.0002) & (0.0002) & (0.0004) \\[4pt]
10 −bedrooms & 0.1194*** & 0.1220*** & 0.1546*** \\
11 − & (0.0045) & (0.0032) & (0.0030) \\[4pt]
12 −bathrooms & 0.2432*** & 0.2285*** & 0.1795*** \\
13 − & (0.0123) & (0.0063) & (0.0057) \\[4pt]
14 −bt\_House & 0.1342*** & 0.1188*** & 0.1299*** \\
15 − & (0.0131) & (0.0101) & (0.0097) \\[4pt]
16 −bt\_Row / Townhouse & 0.1782*** & 0.1604*** & 0.1447*** \\
17 − & (0.0359) & (0.0313) & (0.0296) \\[4pt]
18 −W\_log\_rent & & 0.1367*** & \\
19 − & & (0.0199) & \\[4pt]
20 −$\lambda$ (spatial error) & & & 0.5393 \\
10 +Bedrooms & 0.1194*** & 0.1222*** & 0.1549*** \\
11 + & (0.0045) & (0.0044) & (0.0030) \\[4pt]
12 +Bathrooms & 0.2432*** & 0.2286*** & 0.1797*** \\
13 + & (0.0123) & (0.0127) & (0.0057) \\[4pt]
14 +House & 0.1342*** & 0.1182*** & 0.1261*** \\
15 + & (0.0131) & (0.0124) & (0.0097) \\[4pt]
16 +Row/townhouse & 0.1782*** & 0.1615*** & 0.1533*** \\
17 + & (0.0359) & (0.0333) & (0.0295) \\[4pt]
18 +$W \ln(\text{rent})$ & & 0.1340*** & \\
19 + & & (0.0222) & \\[4pt]
20 +$\lambda$ (spatial error) & & & 0.5437 \\
21 21 \midrule
22 22 Observations & 7925 & 7925 & 7925 \\
23 −R$^2$ / pseudo-R$^2$ & 0.5081 & 0.5503 & 0.4972 \\
23 +R$^2$ / pseudo-R$^2$ & 0.5081 & 0.5508 & 0.4973 \\
24 24 \bottomrule
25 25 \end{tabular}
26 −\parbox{\textwidth}{\footnotesize Standard errors in parentheses. SAR estimated via GM\_Lag; SEM via GM\_Error. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$. City FE included but not shown.}
26 +\parbox{\textwidth}{\footnotesize Standard errors in parentheses: HC1 (OLS), White-robust (SAR, spatial two-stage least squares, \texttt{GM\_Lag}), and the classical GM standard errors of \texttt{GM\_Error} (SEM; no standard error is reported for $\lambda$). $W$ is a row-standardised $k=5$ nearest-neighbour matrix on projected coordinates. All columns include building-type dummies and fixed effects for the 15 largest cities (remaining cities grouped), so the OLS column differs slightly from column (1c) of Table~\ref{tab:hedonic_rent}. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}
modified results/tables/summary_stats_airbnb.csv +2 −0
@@ -8,3 +8,5 @@ Amenities count,3456,45.78269675925926,15.73953887549991,7.0,35.0,46.0,57.0,109.
8 8 Number of images,3456,28.20341435185185,19.168941954671048,0.0,15.0,24.0,36.0,199.0
9 9 Number of reviews,3456,53.404513888888886,74.79929051100895,0.0,6.0,26.0,71.0,986.0
10 10 Quality score,3456,96.81504629629629,38.78591572140682,0.0,95.6,108.4,121.1,139.8
11 +Superhost (share),3456,0.5286458333333334,0.49925097659056017,0.0,0.0,1.0,1.0,1.0
12 +Entire home (share),3456,0.4681712962962963,0.49905811215048956,0.0,0.0,0.0,1.0,1.0
modified results/tables/summary_stats_airbnb.tex +2 −0
@@ -11,5 +11,7 @@ Amenities count & 3456 & 45.78 & 15.74 & 7.00 & 35.00 & 46.00 & 57.00 & 109.00 \
11 11 Number of images & 3456 & 28.20 & 19.17 & 0.00 & 15.00 & 24.00 & 36.00 & 199.00 \\
12 12 Number of reviews & 3456 & 53.40 & 74.80 & 0.00 & 6.00 & 26.00 & 71.00 & 986.00 \\
13 13 Quality score & 3456 & 96.82 & 38.79 & 0.00 & 95.60 & 108.40 & 121.10 & 139.80 \\
14 +Superhost (share) & 3456 & 0.53 & 0.50 & 0.00 & 0.00 & 1.00 & 1.00 & 1.00 \\
15 +Entire home (share) & 3456 & 0.47 & 0.50 & 0.00 & 0.00 & 0.00 & 1.00 & 1.00 \\
14 16 \bottomrule
15 17 \end{tabular}
modified results/tables/summary_stats_rent.csv +1 −0
@@ -2,3 +2,4 @@ Variable,N,Mean,SD,Min,P25,Median,P75,Max
2 2 Monthly rent (CAD),8303,2141.8125641334454,764.8694691020839,995.0799999999999,1615.0,1950.0,2495.0,5000.0
3 3 Bedrooms,7925,2.052744479495268,0.9421661386175844,1.0,1.0,2.0,3.0,10.0
4 4 Bathrooms,8303,1.215705166807178,0.4739252693779812,0.0,1.0,1.0,1.0,8.0
5 +Interior size (sq ft),3699,955.8085698837523,706.425375749557,1.05,643.0,880.0,1099.0,22029.0
modified results/tables/summary_stats_rent.tex +1 −0
@@ -5,5 +5,6 @@ Variable & N & Mean & SD & Min & P25 & Median & P75 & Max \\
5 5 Monthly rent (CAD) & 8303 & 2141.81 & 764.87 & 995.08 & 1615.00 & 1950.00 & 2495.00 & 5000.00 \\
6 6 Bedrooms & 7925 & 2.05 & 0.94 & 1.00 & 1.00 & 2.00 & 3.00 & 10.00 \\
7 7 Bathrooms & 8303 & 1.22 & 0.47 & 0.00 & 1.00 & 1.00 & 1.00 & 8.00 \\
8 +Interior size (sq ft) & 3699 & 955.81 & 706.43 & 1.05 & 643.00 & 880.00 & 1099.00 & 22029.00 \\
8 9 \bottomrule
9 10 \end{tabular}
modified scripts/05_descriptive_analysis.py +87 −6
@@ -26,6 +26,7 @@ use_descriptive_style()
26 26
27 27 import matplotlib.pyplot as plt # noqa: E402
28 28 import matplotlib.ticker as mticker # noqa: E402
29 +import numpy as np # noqa: E402
29 30 import pandas as pd # noqa: E402
30 31
31 32 from src.config import ( # noqa: E402
@@ -55,7 +56,7 @@ def summary_stats(df: pd.DataFrame, cols: list[str], labels: dict | None = None)
55 56 for c in cols:
56 57 if c not in df.columns:
57 58 continue
58 − s = df[c].dropna()
59 + s = df[c].dropna().astype(float) # booleans -> shares
59 60 label = (labels or {}).get(c, c)
60 61 rows.append({
61 62 "Variable": label,
@@ -93,10 +94,12 @@ def make_tables(airbnb: pd.DataFrame, rent: pd.DataFrame, merged: pd.DataFrame):
93 94 airbnb_vars = [
94 95 "price_numeric", "rating", "bedrooms", "bathrooms",
95 96 "guests_count", "amenities_count", "num_images", "num_reviews",
96 − "quality_score",
97 + "quality_score", "is_superhost", "is_entire_home",
97 98 ]
98 99 airbnb_labels = {
99 100 "price_numeric": "Nightly price (CAD)",
101 + "is_superhost": "Superhost (share)",
102 + "is_entire_home": "Entire home (share)",
100 103 "rating": "Rating",
101 104 "bedrooms": "Bedrooms",
102 105 "bathrooms": "Bathrooms",
@@ -110,14 +113,16 @@ def make_tables(airbnb: pd.DataFrame, rent: pd.DataFrame, merged: pd.DataFrame):
110 113 save_table(tbl_airbnb, "summary_stats_airbnb")
111 114
112 115 # 2. Summary statistics: Rent
116 + # 2026-10-17: the original requested a non-existent column ``size_sqft``;
117 + # the interior size is stored as ``size_interior_sqft`` (3,699 listings).
113 118 rent_vars = [
114 − "monthly_rent", "bedrooms", "bathrooms", "size_sqft",
119 + "monthly_rent", "bedrooms", "bathrooms", "size_interior_sqft",
115 120 ]
116 121 rent_labels = {
117 122 "monthly_rent": "Monthly rent (CAD)",
118 123 "bedrooms": "Bedrooms",
119 124 "bathrooms": "Bathrooms",
120 − "size_sqft": "Size (sq ft)",
125 + "size_interior_sqft": "Interior size (sq ft)",
121 126 }
122 127 tbl_rent = summary_stats(rent, rent_vars, rent_labels)
123 128 save_table(tbl_rent, "summary_stats_rent")
@@ -144,11 +149,65 @@ def make_tables(airbnb: pd.DataFrame, rent: pd.DataFrame, merged: pd.DataFrame):
144 149 if len(corr_vars) >= 3:
145 150 corr_df = merged[corr_vars].dropna()
146 151 corr_mat = corr_df.corr()
147 − save_table(corr_mat.round(3).reset_index().rename(columns={"index": ""}),
148 − "correlation_matrix")
152 + corr_mat.round(3).to_csv(TABLE_DIR / "correlation_matrix.csv")
153 + # 2026-10-17: emit a publication-ready fragment (numbered columns,
154 + # readable row labels) instead of raw pandas output with unescaped
155 + # underscores, which could not be \input in the paper.
156 + corr_labels = {
157 + "log_rent": "Log monthly rent",
158 + "airbnb_count_500m": "Airbnb count (500 m)",
159 + "airbnb_density_500m": "Airbnb density (500 m)",
160 + "mean_airbnb_price_500m": "Mean Airbnb price (500 m)",
161 + "share_entire_home_500m": "Entire-home share (500 m)",
162 + "bedrooms": "Bedrooms",
163 + "bathrooms": "Bathrooms",
164 + }
165 + k = len(corr_vars)
166 + lines = [r"\begin{tabular}{l" + "r" * k + "}", r"\toprule",
167 + " & " + " & ".join(f"({i + 1})" for i in range(k)) + r" \\",
168 + r"\midrule"]
169 + for i, v in enumerate(corr_vars):
170 + row = [f"({i + 1}) {corr_labels.get(v, v)}"]
171 + for j, w in enumerate(corr_vars):
172 + row.append(f"{corr_mat.loc[v, w]:.2f}" if j <= i else "")
173 + lines.append(" & ".join(row) + r" \\")
174 + lines += [r"\bottomrule", r"\end{tabular}",
175 + r"\parbox{\textwidth}{\footnotesize Pearson correlations on the "
176 + + f"{len(corr_df):,}" + r" rental listings with at least one Airbnb "
177 + r"listing within 500\,m (the composition variables are undefined "
178 + r"otherwise). At a fixed radius the density is a rescaling of the "
179 + r"count, hence the correlation of 1.00.}"]
180 + (TABLE_DIR / "correlation_matrix.tex").write_text("\n".join(lines) + "\n",
181 + encoding="utf-8")
182 + print(" Saved correlation_matrix.csv + correlation_matrix.tex")
149 183 else:
150 184 print(" Skipping correlation matrix — not enough overlapping columns.")
151 185
186 + # 4. Exposure summary by buffer radius (2026-10-17: the paper previously
187 + # described these statistics in prose only)
188 + rows = []
189 + for tag, lab in [("250m", "250 m"), ("500m", "500 m"), ("1000m", "1 km"), ("2000m", "2 km")]:
190 + c = merged[f"airbnb_count_{tag}"].dropna()
191 + rows.append({
192 + "Radius": lab, "N": int(len(c)), "Mean": c.mean(), "SD": c.std(),
193 + "Median": c.median(), "P90": c.quantile(0.90), "Max": c.max(),
194 + "Share zero": (c == 0).mean(),
195 + })
196 + expo = pd.DataFrame(rows)
197 + expo.to_csv(TABLE_DIR / "exposure_summary.csv", index=False)
198 + lines = [r"\begin{tabular}{lrrrrrrr}", r"\toprule",
199 + r"Radius & N & Mean & SD & Median & P90 & Max & Share zero \\", r"\midrule"]
200 + for _, r in expo.iterrows():
201 + lines.append(f"{r['Radius']} & {r['N']:,} & {r['Mean']:.2f} & {r['SD']:.2f} & "
202 + f"{r['Median']:.0f} & {r['P90']:.0f} & {r['Max']:.0f} & {r['Share zero']:.3f} \\\\")
203 + lines += [r"\bottomrule", r"\end{tabular}",
204 + r"\parbox{\textwidth}{\footnotesize Number of Airbnb listings within each "
205 + r"radius of a rental listing (Haversine distance), over all rental listings "
206 + r"with valid coordinates. ``Share zero'' is the fraction of rental listings "
207 + r"with no Airbnb listing within the radius.}"]
208 + (TABLE_DIR / "exposure_summary.tex").write_text("\n".join(lines) + "\n", encoding="utf-8")
209 + print(" Saved exposure_summary.csv + exposure_summary.tex")
210 +
152 211
153 212 # ===================================================================
154 213 # Figures
@@ -173,6 +232,27 @@ def fig_dist_airbnb_price(airbnb: pd.DataFrame):
173 232 print(" dist_airbnb_price.pdf")
174 233
175 234
235 +def fig_dist_airbnb_logprice(airbnb: pd.DataFrame):
236 + """Histogram of log nightly prices (added 2026-10-17): documents the
237 + bimodality of the scraped price field (second mode above $1,000)."""
238 + prices = airbnb["price_numeric"].dropna()
239 + fig, ax = plt.subplots(figsize=(6, 4))
240 + ax.hist(np.log(prices), bins=40, color="#4C72B0", edgecolor="white", linewidth=0.5)
241 + ax.axvline(np.log(1000), color="firebrick", linestyle="--", linewidth=1.2,
242 + label="$1,000 per night")
243 + ticks = [50, 100, 200, 500, 1000, 2000, 5000, 10000]
244 + ax.set_xticks(np.log(ticks))
245 + ax.set_xticklabels([f"${t:,}" for t in ticks], rotation=0, fontsize=8)
246 + ax.set_xlabel("Nightly price (CAD, log scale)")
247 + ax.set_ylabel("Count")
248 + ax.set_title("Distribution of Airbnb Nightly Prices (log scale)")
249 + ax.legend(fontsize=8, frameon=False)
250 + fig.tight_layout()
251 + fig.savefig(FIG_DIR / "dist_airbnb_logprice.pdf")
252 + plt.close(fig)
253 + print(" dist_airbnb_logprice.pdf")
254 +
255 +
176 256 def fig_dist_rent(rent: pd.DataFrame):
177 257 """Histogram of monthly rents."""
178 258 rents = rent["monthly_rent"].dropna()
@@ -356,6 +436,7 @@ def main():
356 436 # ------------------------------------------------------------------
357 437 print("\n--- Figures ---")
358 438 fig_dist_airbnb_price(airbnb)
439 + fig_dist_airbnb_logprice(airbnb)
359 440 fig_dist_rent(rent)
360 441 fig_airbnb_by_city(airbnb)
361 442 fig_rent_by_city(rent)
modified scripts/06_hedonic_models.py +23 −9
@@ -24,7 +24,7 @@ import pandas as pd
24 24 import statsmodels.api as sm
25 25
26 26 from src.config import AIRBNB_CLEAN, MERGED_ANALYSIS, TABLE_DIR, require
27 −from src.latex_tables import significance_star, results_to_latex
27 +from src.latex_tables import significance_star, results_to_latex, label
28 28
29 29 PROCESSED_HINT = "Run scripts/04_merge_data.py first."
30 30
@@ -166,21 +166,35 @@ def model2_airbnb_pricing(rent: pd.DataFrame, airbnb: pd.DataFrame) -> None:
166 166 # 2b: With controls
167 167 res_2b = run_ols(ab, "log_price", ["mean_rent_city"] + ab_controls, "2b")
168 168
169 − # 2c: With controls + city FE
170 − res_2c = run_ols(ab, "log_price",
171 − ["mean_rent_city"] + ab_controls + ab_city_fe, "2c")
169 + # 2c: With controls + city FE.
170 + # 2026-10-17 correction: mean_rent_city is constant within city and hence
171 + # perfectly collinear with the city dummies; the previous version reported
172 + # a pseudo-inverse "coefficient" for it. It is now dropped in (2c).
173 + res_2c = run_ols(ab, "log_price", ab_controls + ab_city_fe, "2c")
174 +
175 + # 2d-2e (added 2026-10-17): the nightly-price distribution is bimodal, with
176 + # 26% of listings above $1,000 "per night" (the scraper's own category
177 + # "Ultra-Luxury (>$1000)"), which most plausibly reflects total-stay rather
178 + # than nightly prices. Re-estimate on listings priced at or below $1,000.
179 + ab_r = ab[ab["price_numeric"] <= 1000].copy()
180 + print(f" Restricted sample (price <= $1,000): {len(ab_r):,} listings")
181 + res_2d = run_ols(ab_r, "log_price", ["mean_rent_city"] + ab_controls, "2d")
182 + res_2e = run_ols(ab_r, "log_price", ab_controls + ab_city_fe, "2e")
172 183
173 184 display_ab = ["const", "mean_rent_city"] + ab_controls
174 − all_res = [res_2a, res_2b, res_2c]
185 + all_res = [res_2a, res_2b, res_2c, res_2d, res_2e]
175 186
176 187 results_to_latex(
177 188 all_res,
178 − ["(2a)", "(2b)", "(2c)"],
189 + ["(2a)", "(2b)", "(2c)", "(2d)", "(2e)"],
179 190 dep_var="log\\_price",
180 191 display_vars=[v for v in display_ab
181 192 if any(v in r.params.index for r in all_res)],
182 193 out_path=TABLE_DIR / "hedonic_airbnb_pricing.tex",
183 − note="Model (2c) includes city fixed effects (not shown).",
194 + note=("Columns (2c) and (2e) include city fixed effects (not shown), which "
195 + "absorb the city mean log rent. Columns (2a)--(2c) use all listings "
196 + "with a matched city; columns (2d)--(2e) restrict the sample to "
197 + "listings with a nightly price of at most \\$1,000 (see Section~3)."),
184 198 )
185 199
186 200
@@ -238,7 +252,7 @@ def model3_city_interaction(rent: pd.DataFrame) -> None:
238 252 lines.append(r"\toprule")
239 253 lines.append(r" & \textbf{(3-fwd)} & \textbf{(3-rev)} \\")
240 254 lines.append(
241 − r"Dep.\ var: & \textit{mean\_log\_rent} & \textit{airbnb\_count\_city} \\"
255 + r"Dep.\ var: & \textit{mean log rent} & \textit{Airbnb listings in city} \\"
242 256 )
243 257 lines.append(r"\midrule")
244 258
@@ -259,7 +273,7 @@ def model3_city_interaction(rent: pd.DataFrame) -> None:
259 273 else:
260 274 cells_coef.append("")
261 275 cells_se.append("")
262 − vn = var.replace("_", r"\_")
276 + vn = label(var)
263 277 lines.append(f"{vn} & {cells_coef[0]} & {cells_coef[1]} " + r"\\")
264 278 lines.append(f" & {cells_se[0]} & {cells_se[1]} " + r"\\[4pt]")
265 279
modified scripts/07_spatial_models.py +153 −12
@@ -30,7 +30,10 @@ import statsmodels.api as sm # noqa: E402
30 30 from scipy.spatial import cKDTree # noqa: E402
31 31
32 32 from src.config import MERGED_ANALYSIS, TABLE_DIR, FIG_DIR, require # noqa: E402
33 −from src.latex_tables import significance_star as _star # noqa: E402
33 +from src.latex_tables import significance_star as _star, label # noqa: E402
34 +import json # noqa: E402
35 +from scipy.sparse import identity as sp_identity # noqa: E402
36 +from scipy.sparse.linalg import splu # noqa: E402
34 37
35 38 PROCESSED_HINT = "Run scripts/04_merge_data.py first."
36 39
@@ -45,6 +48,91 @@ except ImportError:
45 48 print(" libpysal/spreg not available — using fallback spatial approach")
46 49
47 50
51 +def project_km(lat: np.ndarray, lon: np.ndarray) -> np.ndarray:
52 + """
53 + Equirectangular projection to kilometres around the sample centroid.
54 +
55 + 2026-10-17 correction: the k-nearest-neighbour search was previously run
56 + on raw (latitude, longitude) degrees. At 45-47 degrees North one degree of
57 + longitude spans only ~0.69 of a degree of latitude, so the neighbourhoods
58 + were anisotropic (stretched east-west). Distances are now in kilometres.
59 + """
60 + lat0 = np.radians(np.nanmean(lat))
61 + x = (lon - np.nanmean(lon)) * 111.32 * np.cos(lat0)
62 + y = (lat - np.nanmean(lat)) * 111.32
63 + return np.column_stack([x, y])
64 +
65 +
66 +def lesage_pace_impacts(w_sparse, rho: float, beta: dict, vm: np.ndarray,
67 + idx: dict, n_draws: int = 2000, seed: int = 42) -> dict:
68 + """
69 + Average direct, indirect and total impacts of the SAR model
70 + (LeSage and Pace, 2009, ch. 2) for a row-standardised W.
71 +
72 + total = beta / (1 - rho) (exact for row-standardised W)
73 + direct = beta * (1/n) tr[(I - rho W)^{-1}]
74 + indirect = total - direct
75 +
76 + The trace is evaluated exactly at the point estimate with a sparse LU
77 + factorisation, and as a power series tr[(I - rho W)^{-1}] = sum_k rho^k tr(W^k)
78 + inside a Monte-Carlo loop over draws of (beta, rho) from their asymptotic
79 + normal distribution to obtain simulated standard errors. tr(W^k) for k >= 2
80 + is estimated with Hutchinson's stochastic trace estimator (50 Rademacher
81 + vectors); tr(W^0) = n and tr(W) = 0 are exact.
82 + """
83 + n = w_sparse.shape[0]
84 + W = w_sparse.tocsc()
85 + # exact mean diagonal at the point estimate
86 + lu = splu((sp_identity(n, format="csc") - rho * W).tocsc())
87 + diag_sum = 0.0
88 + chunk = 500
89 + for start in range(0, n, chunk):
90 + cols = np.arange(start, min(start + chunk, n))
91 + rhs = np.zeros((n, len(cols)))
92 + rhs[cols, np.arange(len(cols))] = 1.0
93 + sol = lu.solve(rhs)
94 + diag_sum += sol[cols, np.arange(len(cols))].sum()
95 + mean_diag_exact = diag_sum / n
96 +
97 + # Hutchinson traces for the power series
98 + rng = np.random.default_rng(seed)
99 + K = 60
100 + traces = np.zeros(K + 1)
101 + traces[0] = n
102 + m = 50
103 + V = rng.choice([-1.0, 1.0], size=(n, m))
104 + Wk = V.copy()
105 + for k in range(1, K + 1):
106 + Wk = W @ Wk
107 + traces[k] = np.einsum("ij,ij->", V, Wk) / m
108 + traces[1] = 0.0 # zero diagonal by construction
109 +
110 + def mean_diag(r):
111 + return np.sum((r ** np.arange(K + 1)) * traces) / n
112 +
113 + # Monte-Carlo over (beta_j, rho)
114 + names = list(beta.keys())
115 + j_rho = idx["rho"]
116 + sel = [idx[v] for v in names] + [j_rho]
117 + mu = np.array([beta[v] for v in names] + [rho])
118 + cov = vm[np.ix_(sel, sel)]
119 + draws = rng.multivariate_normal(mu, cov, size=n_draws)
120 + out = {"rho": rho, "mean_diag_exact": mean_diag_exact,
121 + "mean_diag_series": mean_diag(rho)}
122 + for i, v in enumerate(names):
123 + b = beta[v]
124 + direct = b * mean_diag_exact
125 + total = b / (1 - rho)
126 + d_sim = np.array([dr[i] * mean_diag(dr[-1]) for dr in draws])
127 + t_sim = draws[:, i] / (1 - draws[:, -1])
128 + out[v] = {
129 + "direct": direct, "indirect": total - direct, "total": total,
130 + "direct_se": d_sim.std(ddof=1), "indirect_se": (t_sim - d_sim).std(ddof=1),
131 + "total_se": t_sim.std(ddof=1),
132 + }
133 + return out
134 +
135 +
48 136 def run_ols_robust(df, y_col, x_cols, label):
49 137 """OLS with HC1 robust SE."""
50 138 sub = df[[y_col] + x_cols].dropna()
@@ -85,8 +173,11 @@ def spatial_models_table(rent_sp, coords, res_ols, all_x_baseline,
85 173 sem = None
86 174 try:
87 175 print(" Estimating Spatial Lag Model (SAR) ...")
176 + # 2026-10-17: heteroskedasticity-robust (White) standard errors,
177 + # consistent with the HC1 inference used elsewhere in the paper.
88 178 sar = spreg.GM_Lag(
89 − Y_arr, X_arr, w=w, name_y="log_rent", name_x=var_names
179 + Y_arr, X_arr, w=w, name_y="log_rent", name_x=var_names,
180 + robust="white",
90 181 )
91 182 print(f" [SAR] N={sar.n} pseudo-R2={sar.pr2:.4f} rho={sar.betas[-1][0]:.4f}")
92 183 except Exception as e:
@@ -127,7 +218,7 @@ def spatial_models_table(rent_sp, coords, res_ols, all_x_baseline,
127 218 s1 = f"({ols_s[var]:.4f})" if var in ols_s else ""
128 219 c2 = f"{fb_p[var]:.4f}{_star(fb_pv[var])}" if var in fb_p else ""
129 220 s2 = f"({fb_s[var]:.4f})" if var in fb_s else ""
130 − vn = var.replace("_", r"\_")
221 + vn = label(var)
131 222 lines.append(f"{vn} & {c1} & {c2}" + r" \\")
132 223 lines.append(f" & {s1} & {s2}" + r" \\[4pt]")
133 224 lines.append(r"\midrule")
@@ -143,7 +234,7 @@ def spatial_models_table(rent_sp, coords, res_ols, all_x_baseline,
143 234 lines.append(r"\begin{tabular}{lccc}")
144 235 lines.append(r"\toprule")
145 236 lines.append(r" & \textbf{OLS} & \textbf{SAR (GM\_Lag)} & \textbf{SEM (GM\_Error)} \\")
146 − lines.append(r"Dep.\ var: & \multicolumn{3}{c}{\textit{log\_rent}} \\")
237 + lines.append(r"Dep.\ var: & \multicolumn{3}{c}{\textit{log rent}} \\")
147 238 lines.append(r"\midrule")
148 239 ols_params = dict(zip(["const"] + all_x_baseline, res_ols.params))
149 240 ols_se = dict(zip(["const"] + all_x_baseline, res_ols.bse))
@@ -178,16 +269,63 @@ def spatial_models_table(rent_sp, coords, res_ols, all_x_baseline,
178 269 else:
179 270 cells_c.append("")
180 271 cells_s.append("")
181 − vn = var.replace("_", r"\_")
272 + vn = label(var)
182 273 lines.append(f"{vn} & " + " & ".join(cells_c) + r" \\")
183 274 lines.append(f" & " + " & ".join(cells_s) + r" \\[4pt]")
184 275 lines.append(r"$\lambda$ (spatial error) & & & " + f"{sem.betas[-1][0]:.4f}" + r" \\")
276 +
277 + # ── LeSage–Pace impacts for the SAR model (added 2026-10-17) ─────────
278 + print(" Computing LeSage-Pace impacts ...")
279 + idx = {v: i for i, v in enumerate(sar_var_names)}
280 + idx["rho"] = idx["W_log_rent"]
281 + imp_vars = ["airbnb_count_500m", "bedrooms", "bathrooms"]
282 + imp = lesage_pace_impacts(
283 + w.sparse, sar_params["W_log_rent"],
284 + {v: sar_params[v] for v in imp_vars}, np.asarray(sar.vm), idx,
285 + )
286 + print(f" rho={imp['rho']:.4f} mean diag exact={imp['mean_diag_exact']:.5f} "
287 + f"series={imp['mean_diag_series']:.5f}")
288 + ilines = [r"\begin{tabular}{lccc}", r"\toprule",
289 + r" & \textbf{Direct} & \textbf{Indirect} & \textbf{Total} \\", r"\midrule"]
290 + for v in imp_vars:
291 + r = imp[v]
292 + cells = []
293 + for key in ("direct", "indirect", "total"):
294 + est, se = r[key], r[f"{key}_se"]
295 + pz = 2 * (1 - scipy.stats.norm.cdf(abs(est / se))) if se > 0 else 1.0
296 + cells.append(f"{est:.4f}{_star(pz)}")
297 + ilines.append(f"{label(v)} & " + " & ".join(cells) + r" \\")
298 + ilines.append(" & " + " & ".join(f"({r[k + '_se']:.4f})" for k in ("direct", "indirect", "total")) + r" \\[4pt]")
299 + ilines += [r"\midrule",
300 + r"$\hat\rho$ & \multicolumn{3}{c}{" + f"{imp['rho']:.4f}" + r"} \\",
301 + r"$n^{-1}\,\mathrm{tr}[(I-\hat\rho W)^{-1}]$ & \multicolumn{3}{c}{" + f"{imp['mean_diag_exact']:.4f}" + r"} \\",
302 + r"Observations & \multicolumn{3}{c}{" + f"{sar.n:,}" + r"} \\",
303 + r"\bottomrule", r"\end{tabular}",
304 + r"\parbox{\textwidth}{\footnotesize Average direct, indirect and total "
305 + r"impacts of the SAR model in Table~\ref{tab:spatial_results} "
306 + r"\citep{lesage2009introduction}: total $=\hat\beta/(1-\hat\rho)$, direct "
307 + r"$=\hat\beta\, n^{-1}\mathrm{tr}[(I-\hat\rho W)^{-1}]$, indirect $=$ total $-$ "
308 + r"direct. Standard errors in parentheses from 2,000 draws of $(\hat\beta,\hat\rho)$ "
309 + r"from their estimated asymptotic normal distribution. "
310 + r"$^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}"]
311 + (TABLE_DIR / "spatial_impacts.tex").write_text("\n".join(ilines) + "\n", encoding="utf-8")
312 + print(f" -> saved {TABLE_DIR / 'spatial_impacts.tex'}")
313 + # machine-readable record of the spatial estimates
314 + rec = {"rho": sar_params["W_log_rent"], "rho_se": sar_se["W_log_rent"],
315 + "lambda": float(sem.betas[-1][0]),
316 + "sar": {v: {"beta": sar_params[v], "se": sar_se[v]} for v in display_vars if v in sar_params},
317 + "sem": {v: {"beta": sem_params[v], "se": sem_se[v]} for v in display_vars if v in sem_params},
318 + "ols": {v: {"beta": ols_params[v], "se": ols_se[v]} for v in display_vars if v in ols_params},
319 + "impacts": {v: imp[v] for v in imp_vars},
320 + "mean_diag_exact": imp["mean_diag_exact"], "n": int(sar.n),
321 + "sar_pr2": float(sar.pr2), "sem_pr2": float(sem.pr2), "ols_r2": float(res_ols.rsquared)}
322 + (TABLE_DIR / "spatial_models.json").write_text(json.dumps(rec, indent=2), encoding="utf-8")
185 323 lines.append(r"\midrule")
186 324 lines.append(f"Observations & {int(res_ols.nobs)} & {sar.n} & {sem.n} " + r"\\")
187 325 lines.append(f"R$^2$ / pseudo-R$^2$ & {res_ols.rsquared:.4f} & {sar.pr2:.4f} & {sem.pr2:.4f} " + r"\\")
188 326 lines.append(r"\bottomrule")
189 327 lines.append(r"\end{tabular}")
190 − lines.append(r"\parbox{\textwidth}{\footnotesize Standard errors in parentheses. SAR estimated via GM\_Lag; SEM via GM\_Error. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$. City FE included but not shown.}")
328 + lines.append(r"\parbox{\textwidth}{\footnotesize Standard errors in parentheses: HC1 (OLS), White-robust (SAR, spatial two-stage least squares, \texttt{GM\_Lag}), and the classical GM standard errors of \texttt{GM\_Error} (SEM; no standard error is reported for $\lambda$). $W$ is a row-standardised $k=5$ nearest-neighbour matrix on projected coordinates. All columns include building-type dummies and fixed effects for the 15 largest cities (remaining cities grouped), so the OLS column differs slightly from column (1c) of Table~\ref{tab:hedonic_rent}. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}")
191 329 return lines
192 330
193 331 # ── Fallback: manual spatial-lag OLS ─────────────────────────────────────
@@ -233,17 +371,17 @@ def spatial_models_table(rent_sp, coords, res_ols, all_x_baseline,
233 371 else:
234 372 cells_c.append("")
235 373 cells_s.append("")
236 − vn = var.replace("_", r"\_")
374 + vn = label(var)
237 375 lines.append(f"{vn} & " + " & ".join(cells_c) + r" \\")
238 376 lines.append(f" & " + " & ".join(cells_s) + r" \\[4pt]")
239 377
240 378 lines.append(r"\midrule")
241 − for label, accessor in [
379 + for lbl, accessor in [
242 380 ("Observations", lambda r: f"{int(r.nobs)}"),
243 381 ("R$^2$", lambda r: f"{r.rsquared:.4f}"),
244 382 ("Adj.\\ R$^2$", lambda r: f"{r.rsquared_adj:.4f}"),
245 383 ]:
246 − row = [label]
384 + row = [lbl]
247 385 for res in [res_ols, res_slag_rent, res_slag_both]:
248 386 row.append(accessor(res))
249 387 lines.append(" & ".join(row) + r" \\")
@@ -295,7 +433,7 @@ def buffer_robustness(rent_m, controls, city_fe_cols) -> None:
295 433 header = " & ".join([""] + [f"\\textbf{{{b}}}" for b in buf_labels]) + r" \\"
296 434 lines.append(header)
297 435 lines.append(
298 − " & ".join(["Dep.\\ var:"] + [r"\textit{log\_rent}"] * len(buf_labels))
436 + " & ".join(["Dep.\\ var:"] + [r"\textit{log rent}"] * len(buf_labels))
299 437 + r" \\"
300 438 )
301 439 lines.append(r"\midrule")
@@ -336,7 +474,9 @@ def buffer_robustness(rent_m, controls, city_fe_cols) -> None:
336 474 lines.append(r"\end{tabular}")
337 475 lines.append(
338 476 r"\parbox{\textwidth}{\footnotesize Robust (HC1) standard errors in "
339 − r"parentheses. Controls: bedrooms, bathrooms, building-type dummies. "
477 + r"parentheses. Controls: bedrooms, bathrooms, building-type dummies; "
478 + r"fixed effects for the 15 largest cities (remaining cities grouped), as in "
479 + r"Table~\ref{tab:spatial_results}. "
340 480 r"$^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}"
341 481 )
342 482
@@ -439,7 +579,8 @@ def main() -> None:
439 579 rent_sp = rent_m.dropna(subset=spatial_cols).reset_index(drop=True)
440 580 print(f" Complete cases for spatial analysis: {len(rent_sp):,}")
441 581
442 − coords = rent_sp[[lat_col, lon_col]].values
582 + coords = project_km(rent_sp[lat_col].values.astype(float),
583 + rent_sp[lon_col].values.astype(float))
443 584
444 585 # OLS baseline on the spatial subsample
445 586 res_ols = run_ols_robust(rent_sp, "log_rent", all_x_baseline,
modified scripts/08_quantile_models.py +4 −4
@@ -29,7 +29,7 @@ import statsmodels.api as sm # noqa: E402
29 29 from statsmodels.regression.quantile_regression import QuantReg # noqa: E402
30 30
31 31 from src.config import MERGED_ANALYSIS, TABLE_DIR, FIG_DIR, require # noqa: E402
32 −from src.latex_tables import significance_star as _star # noqa: E402
32 +from src.latex_tables import significance_star as _star, label # noqa: E402
33 33
34 34 PROCESSED_HINT = "Run scripts/04_merge_data.py first."
35 35
@@ -95,7 +95,7 @@ def build_table(qr_results: dict, res_ols, bt_cols) -> None:
95 95 " & ".join([""] + [f"\\textbf{{{h}}}" for h in col_headers]) + r" \\"
96 96 )
97 97 lines.append(
98 − " & ".join(["Dep.\\ var:"] + [r"\textit{log\_rent}"] * n_models) + r" \\"
98 + " & ".join(["Dep.\\ var:"] + [r"\textit{log rent}"] * n_models) + r" \\"
99 99 )
100 100 lines.append(r"\midrule")
101 101
@@ -112,7 +112,7 @@ def build_table(qr_results: dict, res_ols, bt_cols) -> None:
112 112 else:
113 113 cells_c.append("")
114 114 cells_s.append("")
115 − vn = var.replace("_", r"\_")
115 + vn = label(var)
116 116 lines.append(f"{vn} & " + " & ".join(cells_c) + r" \\")
117 117 lines.append(f" & " + " & ".join(cells_s) + r" \\[4pt]")
118 118
@@ -196,7 +196,7 @@ def build_plot(qr_model: QuantReg, res_ols) -> None:
196 196 ax.axhline(0, color="grey", linestyle=":", linewidth=0.7)
197 197 ax.set_xlabel(r"Quantile ($\tau$)")
198 198 ax.set_ylabel(r"$\beta_\tau$ (airbnb\_count\_500m)")
199 − ax.set_title("Effect of Airbnb Count (500m) on Log Rent Across Quantiles")
199 + ax.set_title("Airbnb Count (500 m) Coefficient Across Quantiles of Log Rent")
200 200 ax.legend(fontsize=8, loc="best")
201 201 fig.tight_layout()
202 202
modified scripts/09_ml_robustness.py +83 −2
@@ -32,7 +32,8 @@ import pandas as pd # noqa: E402
32 32 from sklearn.ensemble import GradientBoostingRegressor, RandomForestRegressor # noqa: E402
33 33 from sklearn.linear_model import ElasticNetCV, LassoCV, LinearRegression # noqa: E402
34 34 from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score # noqa: E402
35 −from sklearn.model_selection import train_test_split # noqa: E402
35 +from sklearn.model_selection import train_test_split, KFold, GroupKFold # noqa: E402
36 +from sklearn.base import clone # noqa: E402
36 37 from sklearn.preprocessing import StandardScaler # noqa: E402
37 38
38 39 from src.config import ( # noqa: E402
@@ -110,6 +111,80 @@ def train_models(X_train, X_test, y_train, y_test, X_train_sc, X_test_sc):
110 111 return pd.DataFrame(results), fitted
111 112
112 113
114 +def make_models():
115 + """Fresh (unfitted) model instances."""
116 + return {
117 + "OLS": LinearRegression(),
118 + "LASSO": LassoCV(cv=5, random_state=RANDOM_STATE, max_iter=10_000),
119 + "Elastic Net": ElasticNetCV(cv=5, random_state=RANDOM_STATE, max_iter=10_000),
120 + "Random Forest": RandomForestRegressor(
121 + n_estimators=500, max_depth=15, random_state=RANDOM_STATE, n_jobs=-1
122 + ),
123 + "Gradient Boosting": GradientBoostingRegressor(
124 + n_estimators=500, max_depth=5, learning_rate=0.05,
125 + random_state=RANDOM_STATE
126 + ),
127 + }
128 +
129 +
130 +def cross_validate_blocks(X, y, groups) -> pd.DataFrame:
131 + """
132 + Added 2026-10-17. Five-fold cross-validation under two fold designs:
133 + random K-fold and spatially blocked folds (GroupKFold on the forward
134 + sortation area, i.e. the first three characters of the postal code), so
135 + that no test listing shares a neighbourhood with a training listing.
136 + Random splits let flexible learners exploit near-duplicate neighbours and
137 + overstate out-of-sample accuracy for new neighbourhoods.
138 + """
139 + designs = {
140 + "Random 5-fold": KFold(n_splits=5, shuffle=True, random_state=RANDOM_STATE).split(X),
141 + "Spatial 5-fold (FSA blocks)": GroupKFold(n_splits=5).split(X, y, groups),
142 + }
143 + rows = []
144 + for design, splits in designs.items():
145 + splits = list(splits)
146 + for name, proto in make_models().items():
147 + r2s, rmses, maes = [], [], []
148 + for tr, te in splits:
149 + Xtr, Xte = X[tr], X[te]
150 + if name in USE_SCALED:
151 + sc = StandardScaler().fit(Xtr)
152 + Xtr, Xte = sc.transform(Xtr), sc.transform(Xte)
153 + m = clone(proto).fit(Xtr, y[tr])
154 + pred = m.predict(Xte)
155 + r2s.append(r2_score(y[te], pred))
156 + rmses.append(np.sqrt(mean_squared_error(y[te], pred)))
157 + maes.append(mean_absolute_error(y[te], pred))
158 + rows.append({"Design": design, "Model": name,
159 + "R2_cv": np.mean(r2s), "R2_cv_sd": np.std(r2s, ddof=1),
160 + "RMSE_cv": np.mean(rmses), "MAE_cv": np.mean(maes)})
161 + print(f" [{design}] {name:18s} R2={np.mean(r2s):.4f} (sd {np.std(r2s, ddof=1):.4f})"
162 + f" RMSE={np.mean(rmses):.4f}")
163 + return pd.DataFrame(rows)
164 +
165 +
166 +def save_cv_table(cv_df: pd.DataFrame, n_groups: int) -> None:
167 + cv_df.to_csv(TABLE_DIR / "ml_spatial_cv.csv", index=False)
168 + lines = [r"\begin{tabular}{lcccc}", r"\toprule",
169 + r"Model & $R^2$ (mean) & $R^2$ (s.d.) & RMSE & MAE \\", r"\midrule"]
170 + for design, grp in cv_df.groupby("Design", sort=False):
171 + lines.append(r"\multicolumn{5}{l}{\textit{" + design + r"}} \\")
172 + for _, r in grp.iterrows():
173 + lines.append(f"{r['Model']} & {r['R2_cv']:.4f} & {r['R2_cv_sd']:.4f} & "
174 + f"{r['RMSE_cv']:.4f} & {r['MAE_cv']:.4f} \\\\")
175 + lines.append(r"\addlinespace")
176 + lines += [r"\bottomrule", r"\end{tabular}",
177 + r"\parbox{\textwidth}{\footnotesize Five-fold cross-validation of the "
178 + r"models in Table~\ref{tab:ml_performance} on the same features and "
179 + r"sample. Random folds shuffle listings; spatial folds assign whole "
180 + r"forward sortation areas (" + f"{n_groups}" + r" FSA groups) to folds, so no "
181 + r"test listing shares a neighbourhood with a training listing. "
182 + r"Metrics are averaged over the five test folds; $R^2$ (s.d.) is the "
183 + r"standard deviation across folds.}"]
184 + (TABLE_DIR / "ml_spatial_cv.tex").write_text("\n".join(lines) + "\n", encoding="utf-8")
185 + print(f"Saved {TABLE_DIR / 'ml_spatial_cv.tex'}")
186 +
187 +
113 188 def save_comparison_table(res_df: pd.DataFrame) -> None:
114 189 """Write ml_comparison.csv and ml_comparison.tex."""
115 190 res_df.to_csv(TABLE_DIR / "ml_comparison.csv", index=False)
@@ -237,12 +312,13 @@ def main() -> None:
237 312 print("Loading data ...")
238 313 df = pd.read_parquet(require(MERGED_ANALYSIS, PROCESSED_HINT))
239 314
240 − cols = FEATURES + [TARGET]
315 + cols = FEATURES + [TARGET, "postal_code"]
241 316 df_ml = df[cols].dropna()
242 317 print(f"Sample size after dropping NaN: {len(df_ml):,}")
243 318
244 319 X = df_ml[FEATURES].values
245 320 y = df_ml[TARGET].values
321 + groups = df_ml["postal_code"].str[:3].values
246 322
247 323 # 2. Train / test split
248 324 X_train, X_test, y_train, y_test = train_test_split(
@@ -268,6 +344,11 @@ def main() -> None:
268 344 # 7. SHAP values or sklearn feature importances
269 345 plot_importances(fitted, X_test)
270 346
347 + # 8. Random vs spatially blocked cross-validation (added 2026-10-17)
348 + print("\nCross-validation (random vs FSA-blocked folds) ...")
349 + cv_df = cross_validate_blocks(X, y, groups)
350 + save_cv_table(cv_df, n_groups=int(pd.Series(groups).nunique()))
351 +
271 352 print("\n=== 09_ml_robustness.py complete ===")
272 353
273 354
modified scripts/10_robustness_tables_figures.py +4 −2
@@ -167,12 +167,14 @@ def table_subsamples(df: pd.DataFrame) -> list[dict]:
167 167 sub_results.append(res_non)
168 168
169 169 # (c) Apartments only
170 − apt_mask = df["building_type"].str.contains("Apartment", case=False, na=False)
170 + # 2026-10-17: exact matches. The previous case-insensitive substring match
171 + # on "House" also captured "Row / Townhouse" (48 listings).
172 + apt_mask = df["building_type"].eq("Apartment")
171 173 res_apt = run_ols_city_fe(df[apt_mask], "Apartments only")
172 174 sub_results.append(res_apt)
173 175
174 176 # (d) Houses only
175 − house_mask = df["building_type"].str.contains("House", case=False, na=False)
177 + house_mask = df["building_type"].eq("House")
176 178 res_house = run_ols_city_fe(df[house_mask], "Houses only")
177 179 sub_results.append(res_house)
178 180
modified scripts/11_extended_robustness.py +5 −1
@@ -77,6 +77,8 @@ def fit(d: pd.DataFrame, x_main: list[str], bt_cols: list[str],
77 77 if cluster:
78 78 res = sm.OLS(y, X).fit(cov_type="cluster",
79 79 cov_kwds={"groups": sub["city"]})
80 + res.n_clusters = int(sub["city"].nunique())
81 + print(f" [{label}] city clusters = {res.n_clusters}")
80 82 else:
81 83 res = sm.OLS(y, X).fit(cov_type="HC1")
82 84
@@ -95,7 +97,7 @@ def build_table(results: list, col_headers: list[str], se_row: list[str],
95 97 lines.append(r"\toprule")
96 98 lines.append(" & ".join([""] + [f"\\textbf{{{h}}}" for h in col_headers]) + r" \\")
97 99 lines.append(
98 − " & ".join(["Dep.\\ var:"] + [r"\textit{log\_rent}"] * n) + r" \\"
100 + " & ".join(["Dep.\\ var:"] + [r"\textit{log rent}"] * n) + r" \\"
99 101 )
100 102 lines.append(r"\midrule")
101 103
@@ -115,6 +117,8 @@ def build_table(results: list, col_headers: list[str], se_row: list[str],
115 117
116 118 lines.append(r"\midrule")
117 119 lines.append("Standard errors & " + " & ".join(se_row) + r" \\")
120 + lines.append("Clusters & " + " & ".join(
121 + f"{r.n_clusters}" if hasattr(r, "n_clusters") else "" for r in results) + r" \\")
118 122 lines.append("Building type \\& city FE & " + " & ".join(["Yes"] * n) + r" \\")
119 123 lines.append("Observations & "
120 124 + " & ".join(f"{int(r.nobs):,}" for r in results) + r" \\")
added scripts/12_neighbourhood_fe_inference.py +321 −0
@@ -0,0 +1,321 @@
1 +# Author: Simon-Pierre Boucher — contact@spboucher.ai
2 +"""
3 +12_neighbourhood_fe_inference.py
4 +--------------------------------
5 +Added 2026-10-17 (editorial-board revision).
6 +
7 +Two questions left open by the original design:
8 +
9 +1. Are the results robust to neighbourhood fixed effects finer than the city?
10 + The rental listings carry a postal code; its first three characters define
11 + the forward sortation area (FSA, Canada Post), a neighbourhood-scale unit
12 + (333 FSAs in the sample, 180 with at least ten listings). Within-FSA
13 + variation in the Airbnb count is a much stricter comparison than
14 + within-city variation and absorbs most time-invariant neighbourhood
15 + amenities that could drive both Airbnb location and rents.
16 +
17 +2. Which standard errors? The exposure variable is a spatial moving average,
18 + so neighbouring rental listings have mechanically correlated regressors
19 + and plausibly correlated errors. We compare HC1, city-clustered,
20 + FSA-clustered and Conley (1999) spatial HAC standard errors with a
21 + Bartlett kernel at several distance cutoffs.
22 +
23 +Specifications (table neighbourhood_fe.tex):
24 + (F1) city FE (reference, identical to Model 1c)
25 + (F2) FSA FE
26 + (F3) FSA FE, 250 m count (the most local exposure measure)
27 + (F4) FSA FE, extensive + intensive margin (any Airbnb within 500 m, count)
28 + (F5) FSA FE, log(1 + count)
29 + (F6) FSA FE, count + interior size (subsample reporting size)
30 +
31 +Inference table (inference_comparison.tex): coefficient on the 500 m count
32 +under city FE and FSA FE with HC1, cluster-city, cluster-FSA and Conley
33 +standard errors (1, 2, 5, 10 km cutoffs).
34 +
35 +Outputs:
36 + results/tables/neighbourhood_fe.tex
37 + results/tables/inference_comparison.tex
38 + results/tables/neighbourhood_fe.json
39 +"""
40 +
41 +import json
42 +import sys
43 +from pathlib import Path
44 +
45 +sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
46 +
47 +import numpy as np # noqa: E402
48 +import pandas as pd # noqa: E402
49 +import statsmodels.api as sm # noqa: E402
50 +from scipy import stats # noqa: E402
51 +
52 +from src.config import MERGED_ANALYSIS, TABLE_DIR, CHUNK_SIZE, require # noqa: E402
53 +from src.geo import haversine_matrix # noqa: E402
54 +from src.latex_tables import significance_star as _star, label # noqa: E402
55 +
56 +PROCESSED_HINT = "Run scripts/04_merge_data.py first."
57 +CONLEY_CUTOFFS_KM = [1.0, 2.0, 5.0, 10.0]
58 +
59 +
60 +# ─────────────────────────────────────────────────────────────────────────────
61 +# Data preparation
62 +# ─────────────────────────────────────────────────────────────────────────────
63 +
64 +def prepare(df: pd.DataFrame) -> tuple[pd.DataFrame, list[str]]:
65 + d = df.copy()
66 + d["fsa"] = d["postal_code"].astype(str).str[:3].str.upper()
67 + d["log1p_airbnb_500m"] = np.log1p(d["airbnb_count_500m"])
68 + d["any_airbnb_500m"] = (d["airbnb_count_500m"] > 0).astype(float)
69 + d["size_100sqft"] = d["size_interior_sqft"] / 100.0
70 + bt = pd.get_dummies(d["building_type"], prefix="bt", drop_first=True, dtype=float)
71 + d = pd.concat([d, bt], axis=1)
72 + return d, list(bt.columns)
73 +
74 +
75 +def complete_cases(d: pd.DataFrame, x_main: list[str], bt_cols: list[str],
76 + fe: str, extra: list[str] | None = None) -> pd.DataFrame:
77 + controls = ["bedrooms", "bathrooms"] + (extra or [])
78 + needed = ["log_rent", "lat", "lon", "city", "fsa"] + x_main + controls + bt_cols
79 + sub = d[needed].dropna().reset_index(drop=True)
80 + # drop singleton groups (they contribute nothing to within-group variation)
81 + counts = sub[fe].map(sub[fe].value_counts())
82 + sub = sub[counts > 1].reset_index(drop=True)
83 + return sub
84 +
85 +
86 +# ─────────────────────────────────────────────────────────────────────────────
87 +# Estimation with absorbed fixed effects (FWL) + alternative covariances
88 +# ─────────────────────────────────────────────────────────────────────────────
89 +
90 +def within_transform(sub: pd.DataFrame, cols: list[str], fe: str) -> np.ndarray:
91 + g = sub.groupby(fe)
92 + return (sub[cols] - g[cols].transform("mean")).values.astype(float)
93 +
94 +
95 +def fit_fe(sub: pd.DataFrame, x_cols: list[str], fe: str) -> dict:
96 + """
97 + OLS of log_rent on x_cols with fixed effects for `fe` absorbed by the
98 + within transformation. Returns coefficients, residuals, bread, HC1 SEs,
99 + cluster SEs (city, FSA) and the R-squared of the full dummy model.
100 + """
101 + Xw = within_transform(sub, x_cols, fe)
102 + yw = within_transform(sub, ["log_rent"], fe).ravel()
103 + n, k = Xw.shape
104 + n_groups = sub[fe].nunique()
105 + bread = np.linalg.inv(Xw.T @ Xw)
106 + beta = bread @ Xw.T @ yw
107 + e = yw - Xw @ beta
108 + # full-model R2: fitted = group means + Xw beta
109 + fitted = sub["log_rent"].values - e
110 + ss_tot = ((sub["log_rent"] - sub["log_rent"].mean()) ** 2).sum()
111 + r2 = 1 - (e ** 2).sum() / ss_tot
112 + within_r2 = 1 - (e ** 2).sum() / (yw ** 2).sum()
113 + dof_adj = n / (n - k - n_groups) # HC1-type correction with absorbed dummies
114 + S = Xw * e[:, None]
115 + hc1 = np.sqrt(np.diag(bread @ (S.T @ S) @ bread) * dof_adj)
116 + out = {"beta": dict(zip(x_cols, beta)), "se_hc1": dict(zip(x_cols, hc1)),
117 + "n": n, "k": k, "n_groups": n_groups, "r2": r2, "within_r2": within_r2,
118 + "_Xw": Xw, "_e": e, "_bread": bread, "_S": S}
119 + return out
120 +
121 +
122 +def cluster_se(fit: dict, groups: pd.Series) -> np.ndarray:
123 + S, bread = fit["_S"], fit["_bread"]
124 + G = groups.nunique()
125 + n, k = S.shape
126 + meat = np.zeros((k, k))
127 + for _, idx in groups.groupby(groups).indices.items():
128 + sg = S[idx].sum(axis=0)
129 + meat += np.outer(sg, sg)
130 + adj = (G / (G - 1)) * ((n - 1) / (n - k))
131 + return np.sqrt(np.diag(bread @ meat @ bread) * adj)
132 +
133 +
134 +def conley_se(fit: dict, lat: np.ndarray, lon: np.ndarray, cutoff_km: float) -> np.ndarray:
135 + """
136 + Conley (1999) spatial HAC covariance with a Bartlett kernel
137 + K(d) = max(0, 1 - d / cutoff) on great-circle distances; pairs with d = 0
138 + (units in the same building) receive full weight.
139 + """
140 + S, bread = fit["_S"], fit["_bread"]
141 + n, k = S.shape
142 + meat = np.zeros((k, k))
143 + for start in range(0, n, CHUNK_SIZE):
144 + end = min(start + CHUNK_SIZE, n)
145 + d = haversine_matrix(lat[start:end], lon[start:end], lat, lon)
146 + K = np.clip(1.0 - d / cutoff_km, 0.0, None)
147 + meat += S[start:end].T @ (K @ S)
148 + return np.sqrt(np.diag(bread @ meat @ bread))
149 +
150 +
151 +# ─────────────────────────────────────────────────────────────────────────────
152 +# Tables
153 +# ─────────────────────────────────────────────────────────────────────────────
154 +
155 +def star(b, se):
156 + p = 2 * (1 - stats.norm.cdf(abs(b / se)))
157 + return _star(p)
158 +
159 +
160 +def table_specs(results: list[dict], headers: list[str], fe_rows: list[str],
161 + display: list[str]) -> None:
162 + n = len(results)
163 + lines = [r"\begin{tabular}{l" + "c" * n + "}", r"\toprule",
164 + " & ".join([""] + [f"\\textbf{{{h}}}" for h in headers]) + r" \\",
165 + "Dep.\\ var: & \\multicolumn{" + str(n) + r"}{c}{\textit{log rent}} \\",
166 + r"\midrule"]
167 + for v in display:
168 + c, s_ = [], []
169 + for r in results:
170 + if v in r["beta"]:
171 + b, se = r["beta"][v], r["se_hc1"][v]
172 + c.append(f"{b:.4f}{star(b, se)}")
173 + s_.append(f"({se:.4f})")
174 + else:
175 + c.append(""); s_.append("")
176 + lines.append(f"{label(v)} & " + " & ".join(c) + r" \\")
177 + lines.append(" & " + " & ".join(s_) + r" \\[4pt]")
178 + lines += [r"\midrule",
179 + "Fixed effects & " + " & ".join(fe_rows) + r" \\",
180 + "FE groups & " + " & ".join(f"{r['n_groups']:,}" for r in results) + r" \\",
181 + "Observations & " + " & ".join(f"{r['n']:,}" for r in results) + r" \\",
182 + "R$^2$ & " + " & ".join(f"{r['r2']:.4f}" for r in results) + r" \\",
183 + "Within R$^2$ & " + " & ".join(f"{r['within_r2']:.4f}" for r in results) + r" \\",
184 + r"\bottomrule", r"\end{tabular}",
185 + r"\parbox{\textwidth}{\footnotesize Heteroskedasticity-robust (HC1) standard "
186 + r"errors in parentheses. All columns control for bedrooms, bathrooms and "
187 + r"building type; fixed effects are absorbed (within transformation) and "
188 + r"singleton groups are dropped. FSA = forward sortation area (first three "
189 + r"characters of the postal code). Column (F3) uses the 250\,m count; column "
190 + r"(F6) adds interior size on the subsample reporting it. $^{***}p<0.01$; $^{**}p<0.05$; $^{*}p<0.10$.}"]
191 + (TABLE_DIR / "neighbourhood_fe.tex").write_text("\n".join(lines) + "\n", encoding="utf-8")
192 + print(f" -> saved {TABLE_DIR / 'neighbourhood_fe.tex'}")
193 +
194 +
195 +def table_inference(rows: list[dict]) -> None:
196 + """rows: dicts with keys spec, beta, se_hc1, se_city, se_fsa, se_conley{cut}.
197 + Layout (2026-10-17): one column block per specification, one row per
198 + covariance estimator, reporting the standard error and the t-statistic."""
199 + cuts = CONLEY_CUTOFFS_KM
200 + n = len(rows)
201 + lines = [r"\begin{tabular}{l" + "cc" * n + "}", r"\toprule",
202 + " & " + " & ".join(f"\\multicolumn{{2}}{{c}}{{\\textbf{{{r['spec']}}}}}" for r in rows) + r" \\",
203 + " & " + " & ".join(r"\multicolumn{2}{c}{$\hat\beta = " + f"{r['beta']:.4f}" + "$}" for r in rows) + r" \\",
204 + r"\cmidrule(lr){2-3}" + (r"\cmidrule(lr){4-5}" if n > 1 else ""),
205 + "Standard errors & " + " & ".join(["SE & $t$"] * n) + r" \\", r"\midrule"]
206 +
207 + def row(label, key_fn):
208 + cells = []
209 + for r in rows:
210 + se = key_fn(r)
211 + cells += [f"({se:.4f})", f"{r['beta'] / se:.1f}"]
212 + lines.append(f"{label} & " + " & ".join(cells) + r" \\")
213 +
214 + row("Heteroskedasticity-robust (HC1)", lambda r: r["se_hc1"])
215 + row("Clustered by city", lambda r: r["se_city"])
216 + row("Clustered by FSA", lambda r: r["se_fsa"])
217 + for c in cuts:
218 + row(f"Conley spatial HAC, {c:g}\\,km cutoff", lambda r, c=c: r["se_conley"][c])
219 + lines += [r"\midrule",
220 + "City clusters & " + " & ".join(f"\\multicolumn{{2}}{{c}}{{{r['n_city']}}}" for r in rows) + r" \\",
221 + "FSA clusters & " + " & ".join(f"\\multicolumn{{2}}{{c}}{{{r['n_fsa']}}}" for r in rows) + r" \\",
222 + r"\bottomrule", r"\end{tabular}",
223 + r"\parbox{\textwidth}{\footnotesize Coefficient on the Airbnb count within "
224 + r"500\,m from the specification in the column (controls: bedrooms, bathrooms, "
225 + r"building type; fixed effects absorbed, singleton groups dropped). Each row "
226 + r"reports the standard error (in parentheses) and the implied $t$-statistic "
227 + r"under a different covariance estimator: heteroskedasticity-robust (HC1); "
228 + r"clustered by city and by FSA \citep{cameron2015practitioner}; and Conley "
229 + r"spatial HAC with a Bartlett kernel declining linearly to zero at the stated "
230 + r"great-circle cutoff \citep{conley1999gmm, kelejian2007hac}. Listings in the "
231 + r"same building (identical coordinates) receive full weight in the Conley "
232 + r"estimator.}"]
233 + (TABLE_DIR / "inference_comparison.tex").write_text("\n".join(lines) + "\n", encoding="utf-8")
234 + print(f" -> saved {TABLE_DIR / 'inference_comparison.tex'}")
235 +
236 +
237 +# ─────────────────────────────────────────────────────────────────────────────
238 +# Main
239 +# ─────────────────────────────────────────────────────────────────────────────
240 +
241 +def main() -> None:
242 + print("=" * 72)
243 + print("12 NEIGHBOURHOOD FIXED EFFECTS AND SPATIAL INFERENCE")
244 + print("=" * 72)
245 + df = pd.read_parquet(require(MERGED_ANALYSIS, PROCESSED_HINT))
246 + d, bt_cols = prepare(df)
247 + print(f"\nSample: {len(d):,} rows | FSAs: {d['fsa'].nunique()} | cities: {d['city'].nunique()}")
248 +
249 + rec: dict = {}
250 +
251 + # ── Specifications F1–F5 ─────────────────────────────────────────────────
252 + print("\n--- Specifications ---")
253 + sub_city = complete_cases(d, ["airbnb_count_500m"], bt_cols, "city")
254 + f1 = fit_fe(sub_city, ["airbnb_count_500m", "bedrooms", "bathrooms"] + bt_cols, "city")
255 + sub_fsa = complete_cases(d, ["airbnb_count_500m"], bt_cols, "fsa")
256 + f2 = fit_fe(sub_fsa, ["airbnb_count_500m", "bedrooms", "bathrooms"] + bt_cols, "fsa")
257 + # any_airbnb / log1p are derived from the count: compute on the FSA sample
258 + sub_fsa["any_airbnb_500m"] = (sub_fsa["airbnb_count_500m"] > 0).astype(float)
259 + sub_fsa["log1p_airbnb_500m"] = np.log1p(sub_fsa["airbnb_count_500m"])
260 + sub_250 = complete_cases(d, ["airbnb_count_250m"], bt_cols, "fsa")
261 + f3 = fit_fe(sub_250, ["airbnb_count_250m", "bedrooms", "bathrooms"] + bt_cols, "fsa")
262 + f4 = fit_fe(sub_fsa, ["any_airbnb_500m", "airbnb_count_500m", "bedrooms", "bathrooms"] + bt_cols, "fsa")
263 + f5 = fit_fe(sub_fsa, ["log1p_airbnb_500m", "bedrooms", "bathrooms"] + bt_cols, "fsa")
264 + sub_size = complete_cases(d, ["airbnb_count_500m"], bt_cols, "fsa", extra=["size_100sqft"])
265 + f6 = fit_fe(sub_size, ["airbnb_count_500m", "bedrooms", "bathrooms", "size_100sqft"] + bt_cols, "fsa")
266 +
267 + for name, f in [("F1 city FE", f1), ("F2 FSA FE", f2), ("F3 FSA FE 250m", f3),
268 + ("F4 FSA FE any+count", f4), ("F5 FSA FE log1p", f5), ("F6 FSA FE + size", f6)]:
269 + key = list(f["beta"].keys())[0]
270 + print(f" [{name}] N={f['n']:,} groups={f['n_groups']} R2={f['r2']:.4f} "
271 + f"within R2={f['within_r2']:.4f} beta({key})={f['beta'][key]:.6f} "
272 + f"SE={f['se_hc1'][key]:.6f}")
273 + rec[name] = {"n": f["n"], "groups": f["n_groups"], "r2": f["r2"],
274 + "within_r2": f["within_r2"],
275 + "beta": {k: float(v) for k, v in f["beta"].items()},
276 + "se_hc1": {k: float(v) for k, v in f["se_hc1"].items()}}
277 +
278 + # bivariate reference (no controls, no FE) for the coefficient-movement discussion
279 + biv = sm.OLS(d["log_rent"], sm.add_constant(d["airbnb_count_500m"].astype(float))).fit(cov_type="HC1")
280 + rec["bivariate"] = {"beta": float(biv.params["airbnb_count_500m"]),
281 + "se": float(biv.bse["airbnb_count_500m"]), "r2": float(biv.rsquared),
282 + "n": int(biv.nobs)}
283 + print(f" [bivariate] beta={rec['bivariate']['beta']:.6f} R2={rec['bivariate']['r2']:.4f}")
284 +
285 + table_specs([f1, f2, f3, f4, f5, f6], ["(F1)", "(F2)", "(F3)", "(F4)", "(F5)", "(F6)"],
286 + ["City", "FSA", "FSA", "FSA", "FSA", "FSA"],
287 + ["any_airbnb_500m", "airbnb_count_500m", "airbnb_count_250m",
288 + "log1p_airbnb_500m", "bedrooms", "bathrooms", "size_100sqft"])
289 +
290 + # ── Inference comparison ─────────────────────────────────────────────────
291 + print("\n--- Inference comparison ---")
292 + rows = []
293 + for spec, f, sub in [("City FE (Model 1c)", f1, sub_city), ("FSA FE (F2)", f2, sub_fsa)]:
294 + lat = sub["lat"].values.astype(float)
295 + lon = sub["lon"].values.astype(float)
296 + merged = sub[["city", "fsa"]].reset_index(drop=True)
297 + se_city = cluster_se(f, merged["city"])
298 + se_fsa = cluster_se(f, merged["fsa"])
299 + se_con = {c: conley_se(f, lat, lon, c) for c in CONLEY_CUTOFFS_KM}
300 + j = 0 # airbnb_count_500m is the first regressor
301 + row = {"spec": spec, "beta": float(f["beta"]["airbnb_count_500m"]),
302 + "se_hc1": float(f["se_hc1"]["airbnb_count_500m"]),
303 + "se_city": float(se_city[j]), "se_fsa": float(se_fsa[j]),
304 + "se_conley": {c: float(se_con[c][j]) for c in CONLEY_CUTOFFS_KM},
305 + "n_city": int(merged["city"].nunique()), "n_fsa": int(merged["fsa"].nunique())}
306 + rows.append(row)
307 + print(f" [{spec}] beta={row['beta']:.6f} HC1={row['se_hc1']:.6f} city={row['se_city']:.6f} "
308 + f"({row['n_city']} cl.) fsa={row['se_fsa']:.6f} ({row['n_fsa']} cl.) " +
309 + " ".join(f"Conley{c:g}km={row['se_conley'][c]:.6f}" for c in CONLEY_CUTOFFS_KM))
310 + rec["inference"] = rows
311 + table_inference(rows)
312 +
313 + (TABLE_DIR / "neighbourhood_fe.json").write_text(
314 + json.dumps(rec, indent=2, default=float), encoding="utf-8")
315 + print("\n" + "=" * 72)
316 + print("12 DONE")
317 + print("=" * 72)
318 +
319 +
320 +if __name__ == "__main__":
321 + main()
modified src/latex_tables.py +52 −6
@@ -12,6 +12,52 @@ wraps each ``\\input`` in its own ``table`` environment with caption and label.
12 12
13 13 from pathlib import Path
14 14
15 +# Human-readable labels for regressors (shared by every table builder).
16 +# Added 2026-10-17 (editorial-board revision): tables previously printed raw
17 +# variable names such as ``airbnb\_count\_500m``.
18 +LABELS: dict[str, str] = {
19 + "const": "Constant",
20 + "airbnb_count_250m": "Airbnb count (250 m)",
21 + "airbnb_count_500m": "Airbnb count (500 m)",
22 + "airbnb_count_1000m": "Airbnb count (1 km)",
23 + "airbnb_count_2000m": "Airbnb count (2 km)",
24 + "airbnb_density_500m": "Airbnb density (500 m, per km$^2$)",
25 + "share_entire_home_500m": "Entire-home share (500 m)",
26 + "mean_airbnb_price_500m": "Mean Airbnb price (500 m)",
27 + "log1p_airbnb_500m": "log(1 + Airbnb count, 500 m)",
28 + "airbnb_ring_500m_1km": "Airbnb count (500 m--1 km ring)",
29 + "any_airbnb_500m": "Any Airbnb within 500 m (0/1)",
30 + "bedrooms": "Bedrooms",
31 + "bathrooms": "Bathrooms",
32 + "size_100sqft": "Interior size (100 sq ft)",
33 + "bt_House": "House",
34 + "bt_Row / Townhouse": "Row/townhouse",
35 + "mean_rent_city": "City mean log rent",
36 + "guests_count": "Guest capacity",
37 + "amenities_count": "Amenities count",
38 + "is_superhost": "Superhost (0/1)",
39 + "is_entire_home": "Entire home (0/1)",
40 + "W_log_rent": "$W \\ln(\\text{rent})$",
41 + "airbnb_count_city": "Airbnb listings in city",
42 + "mean_bedrooms": "Mean bedrooms",
43 + "mean_bathrooms": "Mean bathrooms",
44 + "mean_log_rent": "Mean log rent",
45 + "spatial_lag_rent": "Spatial lag of log rent",
46 + "spatial_lag_airbnb": "Spatial lag of Airbnb count",
47 +}
48 +
49 +DEPVAR_LABELS: dict[str, str] = {
50 + "log\\_rent": "log rent",
51 + "log\\_price": "log nightly price",
52 + "log_rent": "log rent",
53 + "log_price": "log nightly price",
54 +}
55 +
56 +
57 +def label(var: str) -> str:
58 + """Readable label for a regressor (falls back to an escaped raw name)."""
59 + return LABELS.get(var, var.replace("_", r"\_"))
60 +
15 61
16 62 def significance_star(pval: float) -> str:
17 63 """Return conventional significance stars for a p-value."""
@@ -66,8 +112,8 @@ def results_to_latex(
66 112 header = " & ".join([""] + [f"\\textbf{{{mn}}}" for mn in model_names]) + r" \\"
67 113 lines.append(header)
68 114 lines.append(
69 − " & ".join(["Dep.\\ var:"] + [f"\\textit{{{dep_var}}}" for _ in model_names])
70 − + r" \\"
115 + "Dep.\\ var: & \\multicolumn{" + str(n_models) + "}{c}{\\textit{"
116 + + DEPVAR_LABELS.get(dep_var, dep_var) + "}}" + r" \\"
71 117 )
72 118 lines.append(r"\midrule")
73 119
@@ -87,19 +133,19 @@ def results_to_latex(
87 133 coef_cells.append("")
88 134 se_cells.append("")
89 135 # Pretty variable name
90 − vname = var.replace("_", r"\_")
136 + vname = label(var)
91 137 lines.append(" & ".join([vname] + coef_cells) + r" \\")
92 138 lines.append(" & ".join([""] + se_cells) + r" \\[4pt]")
93 139
94 140 lines.append(r"\midrule")
95 141
96 142 # Fit statistics
97 − for label, accessor in [
98 − ("Observations", lambda r: f"{int(r.nobs)}"),
143 + for lbl, accessor in [
144 + ("Observations", lambda r: f"{int(r.nobs):,}"),
99 145 ("R$^2$", lambda r: f"{r.rsquared:.4f}"),
100 146 ("Adj.\\ R$^2$", lambda r: f"{r.rsquared_adj:.4f}"),
101 147 ]:
102 − cells = [label]
148 + cells = [lbl]
103 149 for res in results_list:
104 150 try:
105 151 cells.append(accessor(res))
106 152
Menu

Theme