Melbourne Footfall
MASE 0.87 vs 0.98 baseline
Hourly CBD pedestrian forecasts by precinct: a daily pipeline from open data to dbt to LightGBM to a public dashboard.
01 Problem
Pedestrian sensors are one of the few high-frequency public signals of how Melbourne is used. After lockdowns, recovery was uneven by precinct and by hour; a citywide average hides the streets that came back and the ones that didn’t. The question: for each CBD precinct and hour, what footfall should we expect, and how far is recent volume from it?
02 Approach
City of Melbourne sensor counts, weather, calendar and CLUE land use land as immutable Parquet. dbt on DuckDB owns staging, joins and grain, ending in a precinct × hour mart. Python adds features, fits a 24-hour seasonal-naive baseline first, then LightGBM, scored with MASE on rolling-origin folds, and exports a Tableau-ready table. Everything reruns from a clean checkout with make targets, decisions are recorded as ADRs, and a scheduled GitHub Actions workflow runs the pipeline every morning.
03 Result
On 2026-06-04 to 2026-09-01 — 18,901 precinct-hour rows across 9 CLUE areas and 89 rolling-origin folds — LightGBM scored a pooled MASE of 0.87 against 0.98 for the seasonal-naive baseline (lower is better). The output is published as a Tableau Public dashboard for non-technical readers.
04 What didn’t work
The pre-lockdown comparison that motivated the project isn’t in yet: the live hourly API only starts at 2024-09-06, so there is no verified older series to compare against. Sensors are mapped to precincts by nearest block, which a published sensor-to-area table would replace.