Inspiration

A rising median rent can reflect a changing selection of apartments. We wanted a forecast whose meaning survives changes in the buildings, apartment sizes and lease types represented in an extract.

What it does

Our Jupyter notebook estimates annualized effective rent growth by comparing consecutive leases for the same physical unit. It separates renewals from turnovers and holds the prior year's building and transition-type weights fixed. It explains the calculation, evaluates chronological forecasts against the same target, and shows simple baselines alongside the central method.

How we built it

We derived the notebook from JADCO's starter schema and required function templates. Python, pandas and NumPy implement availability filters, safe matching, compound annualization, strict lineage barriers, a transparently selected persistence rule and dated public market comparisons. Matplotlib provides aggregate visual explanations. A fresh Jupyter kernel executes the calculations; nbconvert produces an offline report.

Statistics Canada rent CPI and CMHC rental-market evidence provide market context. TAL and Ontario sources support conditional regulatory scenarios. Published dates are checked against each forecast origin. Asking rents remain distinct from signed effective rents.

Challenges we faced

Property and unit codes must remain strings, and site codes are not safe physical-unit identifiers. Promotions affect the difference between contractual and effective rent; we use the supplied effective amount without subtracting the same concession twice. Retrospective CRM extracts lack ingestion and correction timestamps, so chronological filters cannot prove the original historical values. Public market aggregates also differ from the observed transition population.

Accomplishments and learning

The notebook teaches its transformations, exposes per-year errors and comparator outcomes, and records input hashes, source dates and exact dependencies. Independent arithmetic and future-data perturbation checks support the implementation. Their detailed evidence and the measured sponsor results are included only in the separate jury attachment. Historical backtests are limited evidence of future precision; sensitivity scenarios are not confidence intervals.

Reproduction and responsible sharing

The public repository contains generic code, an output-free notebook, independently generated synthetic examples, tests and attributed public facts. A public clone reproduces a synthetic report without sponsor data. Reproducing the sponsor analysis requires authorized access to the original private input directory; those inputs are not included in either deliverable. The jury archive contains the executed notebook, aggregate report, forecast, comparisons and presentation. No sponsor-derived results or charts are published to GitHub.

What's next

Prospectively save data vintages, obtain the facts needed to verify legal applicability, and evaluate genuinely new outcomes. The current revision discloses retrospective design, a finite development comparison and an expanding known-history stability check. Previously inspected years are not presented as an unseen test; every comparator remains visible even when better.

Team, sources and AI disclosure

SOTA Overfitters — Kenneth Chen and Ning Ye. Based on the JADCO starter notebook and challenge instructions, with official sources attributed in the notebook and source catalog. OpenAI Codex assisted source review, implementation, testing and writing. The numerical estimate is computed by the documented Python method. No separately trained model is used.

Built With

  • github;
  • jupyter;
  • matplotlib;
  • nbclient;
  • nbconvert;
  • numpy;
  • openai
  • openpyxl;
  • pandas;
  • python;
Share this project:

Updates

Submission history