spb/qwhpi Public
QHPI — Quebec Housing Price Index: quality-adjusted, hierarchically pooled housing price indexes.
Python 63.9%
TypeScript 25.4%
CSS 5.5%
TeX 3.5%
SQL 0.8%
Makefile 0.5%
Dockerfile 0.5%
1<!--2=============================================================================3QWHPI — Quebec Weekly Housing Price Index4Author : Simon-Pierre Boucher5Contact : contact@spboucher.ai6File : outputs/reports/hierarchical_report.md7Purpose : Step 5 — hierarchical weekly model: architecture, benchmarks,8 and the pooled-β vs city-β arbitration by repeat sales.9=============================================================================10-->1112# Hierarchical weekly model — design record1314## Architecture chosen (two-stage)15161. **Stage 1 — pooled residualization** (pyfixest, n=625,882, R²=0.605, ~3s):17 `log(P) ~ log(floorArea) + fa_missing + age bins + building type | FSA FE + (week × type) FE`.18 The absorbed week×type effects are the province-level weekly paths per19 property type; residuals are quality- and location-adjusted deviations.202. **Stage 2 — heteroskedastic local-level Kalman** per cell:21 weekly mean residual observed with variance σ²/n_t; latent deviation is a22 random walk with innovation τ² estimated by MLE per cell. Region cells23 deviate from the province path; municipality cells deviate from the24 smoothed region path. Weeks with zero transactions are pure predictions —25 the grid is never dropped.2627Published variants: `index` (raw weekly), `index_smoothed` (one-sided filter,28real-time), `index_research` (two-sided smoother). All three share one29rebasing constant (2021 avg = 100), so they are directly comparable.3031## Shrinkage behaviour (outputs/tables/hierarchical_summary.csv)3233- Trois-Rivières condo (median 1 tx/week): raw weekly SD 30.4% → smoothed 4.2%.34- Drummondville condo (median 0 tx/week): still produces a continuous path,35 ~98% parent-driven (shrinkage weight).36- Liquid cells (province types, ~300–1,500 tx/week) are data-dominated.3738## Benchmark: two-stage vs unified city-specific time-dummy (Step 4 baseline)3940Liquid province cells agree almost exactly (corr 0.9996, Québec unifamilial).41Montréal condo exposed a genuine specification fork: by July 2026 the42two-stage index reads 126.9 vs 118.6 for the city-β baseline.4344**Arbitration by pseudo repeat-sales** (BMN, yearly dummies; condo pairs45matched on street + floorArea + yearBuilt because condo addresses carry no46unit numbers — 6,079 Montréal condo pairs, ≥90 days between sales):4748| Measure (2026 level, 2021=100) | Montréal condo | Province condo | Relative |49|--------------------------------------------|---------------:|---------------:|---------:|50| Pseudo repeat-sales (composition-free) | 120.4 | 132.0 | −8.8% |51| Two-stage hierarchical (pooled β) | 126.9 | 138.2 | −8.2% |52| City-specific time-dummy baseline | 118.6 | ~139 | −14% |5354The two-stage model reproduces the composition-free *relative* path almost55exactly; the city-β baseline overstates Montréal's divergence. Hedonic levels56sit a few percent above repeat-sales, the standard direction (depreciation /57renovation bias in repeat pairs). **Decision: the two-stage hierarchical58model is the headline architecture.** The unified per-cell time-dummy remains59as a robustness spec.6061## Compute cost6263Full stage 1 + 112 cells of stage 2 run in under one minute on a laptop —64weekly refresh is trivially cheap. A Bayesian multilevel variant (PyMC) was65rejected for the headline: equivalent shrinkage behaviour at orders of66magnitude more compute, and harder vintage reproducibility.6768## Known caveats (tracked)6970- `se_log` combines the province-path delta-method variance and the Kalman71 posterior variance; block-bootstrap validation of CI coverage is part of72 Step 6.73- The Kalman gain-based `shrinkage_weight` measures how much of a week's74 *movement* comes from the parent path; reliability grades therefore weigh75 n / effective N / SE primarily (Step 7).76- Montréal plex R² is low (0.20) in any spec — unobserved revenue77 characteristics; reliability grading must reflect this.7879Author: Simon-Pierre Boucher — contact@spboucher.ai80