Data and analytics engineering · Christchurch, New Zealand. Open to data and analytics engineering roles. Email · LinkedIn
Start here → retail-ai-pipeline
A year of a UK online retailer's invoices, turned into sales reporting whose totals trace back to the source file, and "bought together" recommendations. Of 541,909 invoice lines, 3.6% are quarantined with a stated reason rather than silently dropped. The recommendations reach a 56.3% hit-rate against 52.8% for a most-popular baseline. Airflow, dbt, DuckDB, SQLite and Power BI. Design notes · Run it · Power BI pages
- nz-bess-peak-credit — How much of a two-hour battery's MW counts at the North Island winter peak as more are built. SOSA 2026 counts every such battery at a flat 60%; 1,218 linear programs over six winters of public EMI data put the perfect-foresight ceiling at 60% for a fleet of about 500 MW on the 2021–2025 average, and 234 MW in the worst winter, against roughly 335 MW once Huntly's battery is commissioned. Six quality gates run from SHA-256 pins on every download to replaying every LP's dispatch. Python + SciPy (HiGHS), with a Power BI report.
- nz-attraction-pageviews — How much online attention eight New Zealand attractions get each day, collected nightly from Wikipedia. A day that fails or arrives incomplete is retried or held back, never silently lost: an offline replay of 720 rows and then 24 more ends with zero duplicate (venue, day) pairs. Python + DuckDB.
- online-retail-analysis-r — Same retail dataset, analysed in R + SQL. Every dropped row is logged with a reason and totals are checked against a SHA-pinned copy of the source, so the numbers can be traced; its net revenue matches the pipeline's to the penny.
- nz-sheep-decline-by-region — Where New Zealand's sheep went, by region, 2002 to 2025: the flock fell 41%. Stats NZ suppresses small cells, so the analysis reconciles regional totals against national ones and accounts for the gaps. R + Quarto, published report.
- nz-ets-forest-eligibility-screening — Which land in Gisborne might count as post-1989 forest under New Zealand's Emissions Trading Scheme. It screens 5,712 land-cover units against open spatial data, so an assessor starts from a list of candidates rather than the whole district. A triage tool, not an eligibility decision: the README names the criteria that stay with the assessor. Python + GeoPandas, with an ArcGIS Pro toolbox.
- aerial-small-object-detection — A benchmarking exercise: the same reproducibility habits (a pinned checkpoint with its SHA-256, stubbed tests, ONNX parity checks) applied to a computer-vision model. Kept for the methodology, not the domain. mAP50 0.375 on validation and 0.318 on held-out test-dev; ONNX on CUDA 7–26% faster than eager PyTorch across four sessions.
Archived, kept because they still reproduce rather than because they are current: PySpark coursework implementations for Million Song and GHCN-Daily. Each says so at the top, with the reason its Spark pin will not move.



