REPORTED_2020 = pd.DataFrame({ # printed in the 2020 notebook (threshold 0.5, its own unseeded shuffle)
"model": ["LogisticReg", "LogisticRegSMOTE", "RandomForest", "XGBoost"],
"accuracy": [0.89, 0.80, 0.90, 0.88], "precision": [0.58, 0.34, 0.54, 0.49],
"recall": [0.20, 0.76, 0.84, 0.91], "f1": [0.30, 0.47, 0.65, 0.64],
}).set_index("model")
def old_models(Xtr, ytr, seed=SEED):
"""The four 2020 models, fitted on (one-hot, scaled) Xtr."""
Xtr_res, ytr_res = SMOTE(random_state=2468).fit_resample(Xtr, ytr)
neg, pos = np.bincount(ytr)
xgb_2020 = xgb.XGBClassifier(objective="binary:logistic", tree_method="hist", scale_pos_weight=neg / pos,
n_estimators=1000, random_state=seed, n_jobs=-1)
if RERUN_OLD_SEARCH:
lr_grid = {"max_iter": [200, 400, 600, 800], "C": [.01, 0.5, 1]}
lr1 = RandomizedSearchCV(LogisticRegression(penalty="l2"), lr_grid, cv=5, n_iter=12, n_jobs=-1, random_state=1205).fit(Xtr, ytr).best_estimator_
lr2 = RandomizedSearchCV(LogisticRegression(penalty="l2"), lr_grid, cv=5, n_iter=12, n_jobs=-1, random_state=1304).fit(Xtr_res, ytr_res).best_estimator_
rf = RandomizedSearchCV(RandomForestClassifier(criterion="entropy", random_state=seed),
{"max_features": ["sqrt", "log2"], "max_depth": [10, 12, 14, 16]},
cv=5, n_iter=8, n_jobs=-1, random_state=5074).fit(Xtr_res, ytr_res).best_estimator_
xgb_grid = {"learning_rate": [0.001, 0.01, 0.1], "max_depth": [6, 7, 8], "gamma": [1, 2, 3],
"reg_alpha": [0, 1, 2], "reg_lambda": [1, 2, 3], "subsample": [.5, .75, 1]}
xg = RandomizedSearchCV(xgb_2020, xgb_grid, scoring="roc_auc", cv=3, n_iter=30, n_jobs=-1,
random_state=2054).fit(Xtr, ytr).best_estimator_
else:
lr1 = LogisticRegression(C=1, max_iter=200).fit(Xtr, ytr)
lr2 = LogisticRegression(C=0.01, max_iter=200).fit(Xtr_res, ytr_res)
rf = RandomForestClassifier(criterion="entropy", max_features="sqrt", max_depth=16,
random_state=seed, n_jobs=-1).fit(Xtr_res, ytr_res)
xg = xgb_2020.set_params(learning_rate=0.01, max_depth=7, gamma=3, reg_alpha=2, reg_lambda=3, subsample=1).fit(Xtr, ytr)
return {"LogisticReg": lr1, "LogisticRegSMOTE": lr2, "RandomForest": rf, "XGBoost": xg}
BANK_PRED = {} # (variant, model) -> test probabilities, for curves and qualitative examples
rows = []
y_tr, y_te = y_bank.iloc[idx_train].values, y_bank.iloc[idx_test].values
for variant, drop in [("2020 features", []), ("no duration", ["duration"])]:
Xs = X_bank_scaled.drop(columns=drop)
Xr = X_bank_raw.drop(columns=drop)
def run_old():
sync(); t = time.perf_counter()
fitted = old_models(Xs.iloc[idx_train], y_tr)
secs = time.perf_counter() - t
return {name: {"p": m.predict_proba(Xs.iloc[idx_test])[:, 1].tolist(), "seconds": secs} for name, m in fitted.items()}
for name, r in cached(f"B__{variant}__2020models__search{int(RERUN_OLD_SEARCH)}", run_old).items():
BANK_PRED[(variant, name + " (2020)")] = (np.array(r["p"]), r["seconds"])
for model_name, fp in MODELS.items():
def run_new():
p, secs = timed_proba(fp, Xr.iloc[idx_train], y_tr, Xr.iloc[idx_test], SEED)
return {"p": p.tolist(), "seconds": secs}
r = cached(f"B__{variant}__{model_name}", run_new)
BANK_PRED[(variant, model_name)] = (np.array(r["p"]), r["seconds"])
print(f"{variant:14s} {model_name:20s} done")
for (variant, model_name), (p, secs) in BANK_PRED.items():
rows.append({"variant": variant, "model": model_name, **scores(y_te, p), "seconds": secs})
res_b = pd.DataFrame(rows)
res_b.to_csv(BASE_DIR / "results_bank.csv", index=False)