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>
67 changed files +2,621 −939
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 | −[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 6 | +[-b31b1b?logo=latex&logoColor=white)](paper/main.pdf) | |
| 7 | 7 | [](requirements.txt) |
| 8 | 8 | [](data/raw/README.md) |
| 9 | −[](src/) | |
| 9 | +[](src/) | |
| 10 | 10 | [](scripts/) |
| 11 | 11 | [](https://uqo.ca) |
| 12 | 12 | [](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 | |