Download tools/nnlab/model_create2.py from Karar-git/hack4dev-building-age-winners: direct link, hf CLI and curl.
- Browser
- Download file 4.38 kB
-
https://huggingface.co/Karar-git/hack4dev-building-age-winners/resolve/main/tools/nnlab/model_create2.py
- Command line
-
hf download hf://Karar-git/hack4dev-building-age-winners/tools/nnlab/model_create2.py
-
curl -L -o model_create2.py https://huggingface.co/Karar-git/hack4dev-building-age-winners/resolve/main/tools/nnlab/model_create2.py
4.38 kB
| """ | |
| modelCreate for the round-2 pick (FINAL-2): two models and one fixed rule. | |
| 1. zero-shot anchor teammate's XGBoost + DANN, trained on Madrid labels and | |
| UNLABELLED Amsterdam features (cached probabilities, | |
| data/processed/zeroshot_xgb_dann_ams.npz) | |
| 2. lgbm_feda LightGBM on Madrid + the labelled shots (weight 30, classes | |
| balanced, each city robust-z scaled with its own median/IQR) | |
| with Daume's feature augmentation: the top 120 features get | |
| a Madrid-only copy and an Amsterdam-only copy | |
| 3. ensemble log p = w0 * log p_zero_shot + (1 - w0) * log p_feda, w0 = 10 / (n + 10) | |
| 4. decision neighbour smoothing (r = 6 px, alpha 0.5, shots excluded), then | |
| tau-0.5 logit adjustment + macro-F1 plug-in rule | |
| (spatial=False skips the smoothing: no coordinates needed) | |
| from model_create2 import model_create | |
| m = model_create(shot_idx, shot_labels) # rows of the Amsterdam feature table, labels 1..4 | |
| labels = m.predict() # labels 1..4 for m.keep (every non-shot row) | |
| Needs at fit time: the Madrid table, ALL unlabelled Amsterdam features (per-city | |
| scaling, the DANN inside the anchor), pixel coordinates for the smoothing. The | |
| decision is batch-level: it labels the whole city at once. | |
| CLI (scores one protocol draw; the only place non-shot labels are read): | |
| python tools/nnlab/model_create2.py --n 25 --rep 0 [--no-spatial] | |
| """ | |
| from __future__ import annotations | |
| import argparse, sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent)) | |
| import lab | |
| import numpy as np | |
| import pandas as pd | |
| W = lab.W | |
| K = 10.0 | |
| _S = {} | |
| def _state(): | |
| if not _S: | |
| import lgbm_var as V | |
| d = lab.load(official60=False) | |
| feats = W.feature_names() | |
| Xm = pd.read_parquet(W.DATA / "madrid_features.parquet", columns=feats)[feats].to_numpy(float) | |
| Xa = pd.read_parquet(W.DATA / "amsterdam_features.parquet", columns=feats)[feats].to_numpy(float) | |
| z = np.load(lab.PROC / "zeroshot_xgb_dann_ams.npz") | |
| assert (z["pa"] == d["pa"]).all() | |
| _S.update(V=V, d=d, Zm=W.robustz(Xm, W.robustz_fit(Xm)), Za=W.robustz(Xa, W.robustz_fit(Xa)), | |
| ctx={"top": V.top_gain_idx()}, | |
| P_zs=((z["P_xgb"] + z["P_dann_seeds"].mean(0)) / 2).astype(np.float32).astype(np.float64), | |
| params={**W.LGBM_PARAMS, **W.RETRAIN_OVERRIDES, "n_jobs": lab.THREADS}) | |
| return _S | |
| class Model: | |
| def __init__(self, proba, keep, spatial, members): | |
| self.proba, self.keep, self.spatial, self.members = proba, keep, spatial, members | |
| def predict(self): | |
| S = _state() | |
| P = self.proba[self.keep] | |
| if self.spatial: | |
| P = lab.smooth(P, S["d"]["pa"], keep=self.keep) | |
| return W.decide(P, S["d"]["prior"]) | |
| def model_create(shot_idx, shot_labels, n=None, spatial=True): | |
| S = _state() | |
| shot = np.asarray(shot_idx) | |
| ys = np.asarray(shot_labels) | |
| n = len(shot) / 4 if n is None else n | |
| P_feda = S["V"].fit_predict("lgbm_feda", S["Zm"], S["d"]["ym"], S["Za"], shot, ys, S["ctx"], S["params"]) | |
| P_feda = P_feda.astype(np.float32).astype(np.float64) # as stored by the lab | |
| w0 = K / (n + K) | |
| L = w0 * np.log(np.clip(S["P_zs"], 1e-6, 1)) + (1 - w0) * np.log(np.clip(P_feda, 1e-6, 1)) | |
| keep = np.setdiff1d(np.arange(len(S["Za"])), shot) | |
| return Model(lab.softmax(L), keep, spatial, {"zs_xgb_dann": S["P_zs"], "lgbm_feda": P_feda}) | |
| if __name__ == "__main__": | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument("--n", type=int, default=25) | |
| ap.add_argument("--rep", type=int, default=0) | |
| ap.add_argument("--no-spatial", action="store_true") | |
| a = ap.parse_args() | |
| S = _state() | |
| d = S["d"] | |
| shot = lab.shots_for(d, a.n, a.rep) | |
| m = model_create(shot, lab.shot_labels(d, shot), n=a.n, spatial=not a.no_spatial) | |
| f1 = W.macro_f1(d["_ya"][m.keep], m.predict()) # scoring only | |
| print(f"FINAL-2 n={a.n} rep={a.rep} spatial={m.spatial}: macro F1 {f1:.6f}") | |
| ref = lab.pred_path("ens_e12", a.n, a.rep) | |
| if ref.exists(): | |
| print(f"max |proba - stored ens_e12| = {np.abs(m.proba - np.load(ref)).max():.2e}") | |