SPB Git

spb/wp36_uqo

Public
3.0 KB · 58 lines python
1"""Unit tests for ucml.prediction helpers on synthetic arrays (no data access)."""2import numpy as np34from ucml import prediction as P567def test_make_targets_rules():8    day = 86400.09    entry = np.zeros(5)10    first_cut = np.array([10 * day, 40 * day, np.nan, 5 * day, np.nan])11    duration = np.array([50.0, 50.0, 20.0, 12.0, 45.0])12    exit_conf = np.array([True, False, True, True, False])13    y = P.make_targets(entry, first_cut, duration, exit_conf, horizon=30)14    assert y["y_markdown30"].tolist() == [1, 0, 0, 1, 0]        # cut at 40 d is beyond the horizon15    assert y["y_exit30"].tolist() == [0, 0, 1, 1, 0]            # exit at 12 d with cut at 5 d: both events16    cr = y["y_markdown30cr"]17    assert np.isnan(cr[2]) and cr[3] == 1 and cr[0] == 1 and cr[1] == 0   # exit-before-cut removed only when no cut181920def test_calibration_table_and_ece():21    y = np.array([0, 0, 1, 1, 1, 0, 1, 1])22    p = np.array([0.05, 0.15, 0.15, 0.95, 0.85, 0.85, 0.95, 0.95])23    t = P.calibration_table(y, p, n_bins=10)24    assert len(t) == 10 and t["n"].sum() == 825    b1 = t.iloc[1]; assert b1["n"] == 2 and abs(b1["frac_pos"] - 0.5) < 1e-12 and abs(b1["mean_pred"] - 0.15) < 1e-1226    e = P.expected_calibration_error(y, p, n_bins=10)27    # bins: [0.05]->|0-0.05|, [0.15,0.15]->|0.5-0.15|, [0.85,0.85]->|0.5-0.85|, [0.95x3]->|1-0.95|28    assert abs(e - (1 * 0.05 + 2 * 0.35 + 2 * 0.35 + 3 * 0.05) / 8) < 1e-1229    perfect = P.expected_calibration_error(np.array([0, 1, 0, 1]), np.array([0.5, 0.5, 0.5, 0.5]))30    assert abs(perfect) < 1e-12313233def test_bootstrap_metrics_keys_and_ci_order():34    rng = np.random.default_rng(0)35    p = rng.uniform(size=400); y = (rng.uniform(size=400) < p).astype(float)36    m = P.bootstrap_metrics(y, p, n_boot=50, seed=1)37    for k in ("log_loss", "brier", "auc"):38        lo, hi = m[f"{k}_ci"]; assert lo <= m[k] <= hi or abs(m[k] - lo) < 0.05 or abs(hi - m[k]) < 0.0539    assert m["n_test"] == 400 and 0 < m["base_rate"] < 1 and m["auc"] > 0.640    g = np.repeat(["A", "B"], 200)41    mg = P.bootstrap_metrics(y, p, groups=g, n_boot=20, seed=1)42    assert abs(mg["log_loss"] - np.mean([P._metrics(y[g == k], p[g == k])["log_loss"] for k in ("A", "B")])) < 1e-12434445def test_target_encode_no_self_leak_and_prior_for_unseen():46    g_tr = np.array(["d1"] * 10 + ["d2"] * 10)47    y_tr = np.array([1.0] * 10 + [0.0] * 10)48    enc_tr, enc_te = P.target_encode(g_tr, y_tr, np.array(["d1", "d2", "d9"]), m=2.0, k=5, seed=0)49    prior = 0.550    assert abs(enc_te[2] - prior) < 1e-12                       # unseen dealer -> training prior51    assert abs(enc_te[0] - (10 + 2 * prior) / 12) < 1e-12 and abs(enc_te[1] - (0 + 2 * prior) / 12) < 1e-1252    # training rows: own label excluded, so d1 encodings are strictly below the full-training value53    assert np.all(enc_tr[:10] < enc_te[0]) and np.all(enc_tr[10:] > enc_te[1])54    # NaN labels (competing-risk target) are ignored, not propagated55    y_nan = y_tr.copy(); y_nan[0] = np.nan56    a, b = P.target_encode(g_tr, y_nan, np.array(["d1"]), m=2.0)57    assert np.isfinite(a).all() and np.isfinite(b).all()58
Files · f9bf466deda3bcf4729bb4dc6e4078483843c761
Menu

Theme