SPB Git

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%
5.4 KB

# QWHPI Data Audit Report

Author: Simon-Pierre Boucher — contact@spboucher.ai

# 1. Schema and shape

  • Rows: 745,119

  • Columns: 17

  • Date range: 2021-01-04 -> 2026-07-27

  • Distinct Monday-labeled weeks with >=1 transaction: 291

  • Distinct cities (raw text field): 1,100

  • Distinct ids: 745,119 (duplicated ids: 0)

    -> table saved: outputs/tables/audit_schema.csv (17 rows)

# 2. Missingness

-> table saved: outputs/tables/audit_missingness.csv (17 rows)

  • buildingType: 283,206 missing (38.01%)
  • ownerType: 224,999 missing (30.2%)
  • yearBuilt: 137,315 missing (18.43%)
  • floorArea: 115,153 missing (15.45%)
  • previousValue: 78,581 missing (10.55%)
  • zipCode: 75,369 missing (10.12%)
  • totalArValue: 63,160 missing (8.48%)
  • street: 6,688 missing (0.9%)

Sentinel / degenerate values (not encoded as null): -> table saved: outputs/tables/audit_sentinel_values.csv (11 rows)

  • amount <= 0: 0
  • amount in (1, 2): 0
  • amount < 5000: 0
  • floorArea <= 0: 0
  • floorArea > 2000 m2: 375
  • yearBuilt < 1600: 0
  • yearBuilt > 2026: 0
  • yearBuilt == 0: 0
  • previousValue <= 0: 1,640
  • totalArValue <= 0: 17
  • lat/lng outside Quebec bbox (44.9-62.7N, -79.8--57W): 0

# 3. Categorical distributions

# propertyType

-> table saved: outputs/tables/audit_dist_propertyType.csv (4 rows)

  • unifamilial: 443,078 (59.46%)
  • indéterminé: 107,656 (14.45%)
  • condo: 100,218 (13.45%)
  • plex: 94,167 (12.64%)

# buildingType

-> table saved: outputs/tables/audit_dist_buildingType.csv (6 rows)

  • None: 283,206 (38.01%)
  • single-story: 205,924 (27.64%)
  • full-story: 188,584 (25.31%)
  • mansard: 52,808 (7.09%)
  • split-level: 8,743 (1.17%)
  • single-wide: 5,854 (0.79%)

# ownerType

-> table saved: outputs/tables/audit_dist_ownerType.csv (4 rows)

  • physical_person: 496,404 (66.62%)
  • None: 224,999 (30.2%)
  • legal_person: 22,351 (3.0%)
  • mixed: 1,365 (0.18%)

# 4. Amount descriptives by propertyType (amount > 0)

-> table saved: outputs/tables/audit_amount_by_type.csv (4 rows)

  • unifamilial: n=443,078 | p01=$60,000 | median=$378,000 | p99=$1,635,000 | max=$345,000,000
  • indéterminé: n=107,656 | p01=$52,185 | median=$319,252 | p99=$1,400,000 | max=$75,000,000
  • condo: n=100,218 | p01=$103,500 | median=$360,000 | p99=$1,300,000 | max=$18,750,000
  • plex: n=94,167 | p01=$75,000 | median=$470,577 | p99=$1,710,000 | max=$42,000,000 -> table saved: outputs/tables/audit_characteristics_by_type.csv (4 rows)

# 5. Duplicate scan

  • Exact duplicates ignoring id: 665
  • Same street+city+date (candidate multi-unit or true dupes): 10,925
  • Same street+city+date+amount (strong duplicate candidates): 784
  • Addresses (street+city) with >=2 distinct sale dates: 87,787

# 6. Weekly coverage and liquidity

  • Continuous Monday grid: 291 weeks (2021-01-04 -> 2026-07-27)
  • Zero-transaction weeks on the grid: 0
  • Median tx/week (province): 2,351
  • Min tx/week: 35 | Max: 7,845
  • Last 6 weeks (partial-week check): 2026-06-22=4226, 2026-06-29=3581, 2026-07-06=2934, 2026-07-13=2973, 2026-07-20=2197, 2026-07-27=318 -> table saved: outputs/tables/audit_weekly_volume_province.csv (291 rows) -> table saved: outputs/tables/audit_weekly_liquidity_topcities.csv (100 rows) -> table saved: outputs/tables/audit_liquidity_matrix.csv (25 rows)

Median weekly transactions, top cities (rows) x type (cols): see audit_liquidity_matrix.csv

  • {'city': 'Québec', 'condo': 41.5, 'indéterminé': 6.0, 'plex': 21.0, 'unifamilial': 66.0}

  • {'city': 'Montréal', 'condo': 145.0, 'indéterminé': 39.0, 'plex': 80.0, 'unifamilial': 64.0}

  • {'city': 'Gatineau', 'condo': 7.0, 'indéterminé': 12.0, 'plex': 12.0, 'unifamilial': 54.0}

  • {'city': 'Laval', 'condo': 21.0, 'indéterminé': 8.0, 'plex': 8.0, 'unifamilial': 54.0}

  • {'city': 'Sherbrooke', 'condo': 2.0, 'indéterminé': 6.0, 'plex': 7.0, 'unifamilial': 29.0}

  • {'city': 'Longueuil', 'condo': 15.0, 'indéterminé': 10.0, 'plex': 9.0, 'unifamilial': 28.0}

  • {'city': 'Lévis', 'condo': 4.0, 'indéterminé': 6.0, 'plex': 5.0, 'unifamilial': 26.0}

  • {'city': 'Saguenay', 'condo': 2.0, 'indéterminé': 4.0, 'plex': 8.0, 'unifamilial': 26.0}

  • {'city': 'Trois-Rivières', 'condo': 2.0, 'indéterminé': 5.0, 'plex': 8.0, 'unifamilial': 23.0}

  • {'city': 'Terrebonne', 'condo': 3.0, 'indéterminé': 6.0, 'plex': 3.0, 'unifamilial': 22.0}

  • {'city': 'Saint-Jean-sur-Richelieu', 'condo': 2.0, 'indéterminé': 4.0, 'plex': 3.0, 'unifamilial': 18.0}

  • {'city': 'Drummondville', 'condo': 1.0, 'indéterminé': 3.0, 'plex': 4.0, 'unifamilial': 16.0}

  • Top 50 city strings cover 61.4% of transactions -> table saved: outputs/tables/audit_city_top200.csv (200 rows)

# 7. indéterminé property type — preliminary look

  • Count: 107,656 (14.4%)
  • Median amount: $319,252 (vs unifamilial $378,000)
  • floorArea missing: 95.6% | yearBuilt missing: 95.2% | buildingType missing: 97.9%
  • Top buildingType values within indéterminé: None=105,377, single-story=1,089, mansard=601, full-story=557, single-wide=26, split-level=6
  • ownerType within indéterminé: None=73,911, physical_person=20,620, legal_person=12,657, mixed=468