You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(forecaster): add v1 training pipeline, reference data, and ops workflows
Introduce the forecaster v1 build/evaluation scripts, feature store modules, housing finance helpers, and supporting docs/data so forecasting and admin operations are reproducible end-to-end.
Made-with: Cursor
Copy file name to clipboardExpand all lines: README.md
+215-6Lines changed: 215 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,8 +26,8 @@ From the repository root, the scripts create `.venv`, install the package, optio
26
26
27
27
| OS | Command |
28
28
|----|--------|
29
-
|**Windows**| Double-click or run: `run-all.cmd`|
30
-
|**macOS / Linux**|`chmod +x run-all.sh` once, then `./run-all.sh`|
29
+
|**Windows**| Double-click or run: `run-all-machinelearning.cmd`|
30
+
|**macOS / Linux**|`chmod +x run-all-machinelearning.sh` once, then `./run-all-machinelearning.sh`|
31
31
32
32
- For faster repeat runs, set `RUN_ALL_SKIP_INSTALL=1` to skip dependency bootstrap when your `.venv` is already ready.
33
33
- In the Streamlit UI, the **Project & method** tab states the **problem, data, storage, models, and how users interact** (dashboard / deployment). For a full **planning-area map** (not the two-polygon test fixture), run `python scripts/fetch_reference_geo.py` and set the map path to `data/reference/planning_areas.geojson`.
Then: `make test` · `hdb-download -o data/raw/hdb_resale_2017_onwards.csv` (or `--max-rows 20000` for a faster sample) · `make analysis` or `python scripts/run_analysis.py` · `streamlit run streamlit_app.py`.
45
+
Then: `make test` · `hdb-download -o data/raw/hdb_resale_2017_onwards.csv` (or `--max-rows 20000` for a faster sample) · `hdb-bto-download -o data/reference` · `make analysis` or `python scripts/run_analysis.py --refresh-bto` · `streamlit run streamlit_app.py`.
46
46
47
-
**Geo (Graph tab, planning-area edges):**`pip install -e ".[geo]"` and run `make fetch-geo` or `scripts/fetch_reference_geo.py` to pull the official [MP2025 planning-area boundary (No Sea)](https://data.gov.sg/datasets/d_2cc750190544007400b2cfd5d7f53209/view) GeoJSON (old static `geo.data.gov.sg` MP14 links are no longer served). **Rent / gross yield:** set `HDB_MEDIAN_RENT_RESOURCE_ID` and `hdb-rent-download -o data/raw/median_rent_hdb.csv`, or use [`tests/fixtures/median_rent_sample.csv`](tests/fixtures/median_rent_sample.csv). Override staleness in the app with `SINGAPORE_EDA_RENT_TTL_HOURS`. Tranche merge and other CLI details: `hdb-download --help`, `hdb-resale-merge --help`.
47
+
## HDB Forecaster V1 (Postgres + Streamlit)
48
+
49
+
This repository now includes a dedicated V1 regression forecaster path with:
50
+
-**Leakage-safe temporal split** (train/validation/test ordered by transaction month),
51
+
-**LightGBM + XGBoost candidate training** with automatic winner selection by validation holdout performance,
52
+
-**SHAP local explainability** for top prediction drivers,
53
+
-**Prediction interval** from split-conformal absolute-residual calibration (default nominal coverage 0.80),
54
+
-**Optional Postgres curated table write** for a production-style feature store.
55
+
-**Empirical lease time-decay feature** fitted from historical data (captures
56
+
age/lease effects without forcing literal zero-value end state).
57
+
-**MLflow experiment tracking** (params, metrics, artifacts) via config.
58
+
-**Deepchecks data integrity validation** hook via config.
59
+
-**Feedback loop capture** from Streamlit predictions to local feedback store.
60
+
-**Optional location/accessibility features** when available in enriched data
**Geo (Graph tab, planning-area edges):**`pip install -e ".[geo]"` and run `make fetch-geo` or `scripts/fetch_reference_geo.py` to pull the official [MP2025 planning-area boundary (No Sea)](https://data.gov.sg/datasets/d_2cc750190544007400b2cfd5d7f53209/view) GeoJSON (old static `geo.data.gov.sg` MP14 links are no longer served). **Rent / gross yield:** set `HDB_MEDIAN_RENT_RESOURCE_ID` and `hdb-rent-download -o data/raw/median_rent_hdb.csv`, or use [`tests/fixtures/median_rent_sample.csv`](tests/fixtures/median_rent_sample.csv). **BTO historical + future supply references:** run `hdb-bto-download -o data/reference` (writes launch price range, completion status, property information, plus `hdb_bto_reference.csv`). Override staleness in the app with `SINGAPORE_EDA_RENT_TTL_HOURS`. Tranche merge and other CLI details: `hdb-download --help`, `hdb-resale-merge --help`.
237
+
238
+
Forecaster training/inference now consumes BTO-derived town/year context features when these files are present:
239
+
-`bto_launch_count_town_3y`
240
+
-`bto_avg_price_range_mid_town_3y`
241
+
-`bto_under_construction_units_town`
242
+
-`bto_completed_units_town`
48
243
49
244
## Data
50
245
51
246
**Primary resale table:**[Resale flat prices (registration) from Jan-2017 onwards](https://data.gov.sg/datasets/d_8b84c4ee58e3cfc0ece0d773c8ca6abc/view) (HDB, [Open Data Licence](https://data.gov.sg/open-data-licence)).
52
247
53
-
**Reference tables (in-repo):**[`data/reference/`](data/reference/) — town → planning area / OCR, mature vs young labels, MRT access proxy, optional EIP block stub, future MRT example rows.
248
+
**Reference tables (in-repo):**[`data/reference/`](data/reference/) — town → planning area / OCR, mature vs young labels, MRT access proxy, optional EIP block stub, and official MRT reference exports fetched from government APIs.
Optional OneMap secrets for official travel-time refresh jobs:
303
+
304
+
```toml
305
+
ONEMAP_API_EMAIL = "your_onemap_email"
306
+
ONEMAP_API_PASSWORD = "your_onemap_password"
307
+
```
308
+
309
+
Local-only development alternative:
310
+
- put the same values into repo-root `.env` (already gitignored),
311
+
- run `make fetch-mrt-travel-times`.
312
+
104
313
## Production: data.gov.sg limits, cache, health API, ops UI
105
314
106
315
Official **per-10-second** limits (see [`API rate limits`](https://guide.data.gov.sg/developer-guide/api-overview/api-rate-limits)) depend on whether you use an API key and its **tier**:
@@ -169,7 +378,7 @@ This section is intentionally direct: the project is useful for **learning and e
169
378
### Weaknesses and cons (what to be careful about)
170
379
171
380
-**Exploratory, not a full research pipeline:** Methods are **standard EDA and simple models** (e.g. OLS-style stats, k-means, ETS). They are **not** a complete econometric or ML validation programme; assumptions are not fully audited in this repo.
172
-
-**Reference data and proxies:** In-repo tables (town→planning area, MRT access, maturity labels) and optional files (e.g. EIP **stub**, future MRT **examples**) are **simplifications** or **placeholders**where noted in code or docs. They can be **wrong**, **incomplete**, or **out of date**relative to ground truth.
381
+
-**Reference data and proxies:** In-repo tables (town→planning area, MRT access, maturity labels) and optional files (e.g. EIP **stub**) are simplificationswhere noted. Even when sourced from official datasets/APIs, joins and transformations can still be wrong, incomplete, or stale relative to current ground truth.
173
382
-**Optional or stubbed features:** Some modules are explicitly limited (e.g. **sun exposure** is largely placeholder unless enabled and configured; see package layout). Treat their outputs as **illustrative**.
174
383
-**Sample and default limits:** Default downloads cap row counts; partial samples **do not** represent the full market. Stale or cached data may not reflect the latest government release.
175
384
-**Upstream and maintenance risk:** API formats, tranche boundaries, and CKAN behaviour **change**; the pipeline may need maintenance after upstream changes.
0 commit comments