Download train/tabular_tune.py from lee101/mojo-tabular: direct link, hf CLI and curl.
- Browser
- Download file 4.7 kB
-
https://huggingface.co/lee101/mojo-tabular/resolve/main/train/tabular_tune.py
- Command line
-
hf download hf://lee101/mojo-tabular/train/tabular_tune.py
-
curl -L -o tabular_tune.py https://huggingface.co/lee101/mojo-tabular/resolve/main/train/tabular_tune.py
4.7 kB
| import argparse, hashlib, json, time | |
| from pathlib import Path | |
| import joblib, numpy as np | |
| from sklearn.ensemble import HistGradientBoostingClassifier, ExtraTreesClassifier | |
| from sklearn.linear_model import LogisticRegression | |
| from sklearn.metrics import roc_auc_score | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.pipeline import make_pipeline | |
| from tabular_bench import DATA, SEED, load, prep | |
| TRIALS = 16 | |
| GB_TRIALS = 6 | |
| def gbdt(rng): | |
| from xgboost import XGBClassifier | |
| from lightgbm import LGBMClassifier | |
| for _ in range(GB_TRIALS): | |
| lr = float(10 ** rng.uniform(-2, -0.7)); n = int(rng.integers(150, 600)); d = int(rng.integers(3, 9)) | |
| yield 'xgb', dict(learning_rate=lr, n_estimators=n, max_depth=d), XGBClassifier( | |
| learning_rate=lr, n_estimators=n, max_depth=d, subsample=0.8, colsample_bytree=0.8, n_jobs=2, random_state=SEED, verbosity=0) | |
| yield 'lgbm', dict(learning_rate=lr, n_estimators=n, num_leaves=2 ** d), LGBMClassifier( | |
| learning_rate=lr, n_estimators=n, num_leaves=2 ** d, subsample=0.8, subsample_freq=1, colsample_bytree=0.8, n_jobs=2, random_state=SEED, verbose=-1) | |
| def hgb(rng): | |
| return dict(learning_rate=float(10 ** rng.uniform(-2, -0.7)), max_iter=int(rng.integers(100, 600)), | |
| max_leaf_nodes=int(rng.integers(8, 64)), min_samples_leaf=int(rng.integers(5, 60)), | |
| l2_regularization=float(10 ** rng.uniform(-3, 1)), max_features=float(rng.uniform(0.5, 1.0))) | |
| def main(): | |
| ap = argparse.ArgumentParser() | |
| ap.add_argument('--output', type=Path, required=True) | |
| ap.add_argument('--datasets', nargs='*') | |
| ap.add_argument('--gbdt', action='store_true') | |
| ap.add_argument('--artifacts', type=Path, required=True) | |
| a = ap.parse_args() | |
| man = json.loads((DATA / 'manifest.json').read_text()) | |
| out = dict(kind='tuned_ensemble', seed=SEED, metric='roc_auc', trials=TRIALS, | |
| source_sha256=hashlib.sha256(Path(__file__).read_bytes()).hexdigest(), datasets={}) | |
| a.artifacts.mkdir(parents=True, exist_ok=True) | |
| for name, m in man.items(): | |
| if a.datasets and name not in a.datasets: | |
| continue | |
| X, y = load(name, m['target']) | |
| if y is None: | |
| continue | |
| idx = np.arange(len(y)) | |
| tr, rest = train_test_split(idx, test_size=0.4, stratify=y, random_state=SEED) | |
| va, te = train_test_split(rest, test_size=0.5, stratify=y[rest], random_state=SEED) | |
| rng = np.random.default_rng(SEED) | |
| t0 = time.monotonic() | |
| cands = [] | |
| for i in range(TRIALS): | |
| p = hgb(rng) | |
| mdl = make_pipeline(prep(X), HistGradientBoostingClassifier(early_stopping=False, random_state=SEED, **p)).fit(X.iloc[tr], y[tr]) | |
| cands.append(('hgb', p, mdl, mdl.predict_proba(X.iloc[va])[:, 1])) | |
| for c in (0.1, 1.0): | |
| mdl = make_pipeline(prep(X), LogisticRegression(C=c, max_iter=500)).fit(X.iloc[tr], y[tr]) | |
| cands.append(('logreg', dict(C=c), mdl, mdl.predict_proba(X.iloc[va])[:, 1])) | |
| mdl = make_pipeline(prep(X), ExtraTreesClassifier(300, min_samples_leaf=2, n_jobs=2, random_state=SEED)).fit(X.iloc[tr], y[tr]) | |
| cands.append(('et', {}, mdl, mdl.predict_proba(X.iloc[va])[:, 1])) | |
| if a.gbdt: | |
| for kind, p, est in gbdt(np.random.default_rng(SEED + 1)): | |
| mdl = make_pipeline(prep(X), est).fit(X.iloc[tr], y[tr]) | |
| cands.append((kind, p, mdl, mdl.predict_proba(X.iloc[va])[:, 1])) | |
| aucs = [roc_auc_score(y[va], c[3]) for c in cands] | |
| order = np.argsort(aucs)[::-1] | |
| top = [cands[i] for i in order[:3]] | |
| ens_va = np.mean([c[3] for c in top], axis=0) | |
| ens_auc = roc_auc_score(y[va], ens_va) | |
| single = cands[order[0]] | |
| use_ens = ens_auc > aucs[order[0]] | |
| members = top if use_ens else [single] | |
| pred = lambda i: np.mean([c[2].predict_proba(X.iloc[i])[:, 1] for c in members], axis=0) | |
| path = a.artifacts / f'{name}.joblib' | |
| joblib.dump(dict(members=[c[2] for c in members], columns=list(X.columns)), path, compress=3) | |
| out['datasets'][name] = dict( | |
| val_auc=round(max(ens_auc, aucs[order[0]]), 4), test_auc=round(roc_auc_score(y[te], pred(te)), 4), | |
| ensemble=use_ens, best_single_kind=single[0], members=[dict(kind=c[0], params=c[1]) for c in members], | |
| artifact_bytes=path.stat().st_size, artifact_sha256=hashlib.sha256(path.read_bytes()).hexdigest(), | |
| search_s=round(time.monotonic() - t0, 1)) | |
| print(name, out['datasets'][name], flush=True) | |
| a.output.write_text(json.dumps(out, indent=2) + '\n') | |
| if __name__ == '__main__': | |
| main() | |