Download model-3/scripts/fr_robust.py from Jyo-K/PoPTard5: direct link, hf CLI and curl.
- Browser
- Download file 3.63 kB
-
https://huggingface.co/Jyo-K/PoPTard5/resolve/main/model-3/scripts/fr_robust.py
- Command line
-
hf download hf://Jyo-K/PoPTard5/model-3/scripts/fr_robust.py
-
curl -L -o fr_robust.py https://huggingface.co/Jyo-K/PoPTard5/resolve/main/model-3/scripts/fr_robust.py
3.63 kB
| """Risk analysis for raising France's threshold. | |
| The p**g shift model saturated at g=6 without fully explaining France's deficit, so g is | |
| NOT identified. The decision must therefore be robust across the whole plausible range of | |
| g - including g=1 (no shift at all), which is the downside case. Reports, for each g: | |
| the optimal France threshold, and what threshold 0.90 costs or gains against 0.70. | |
| Also propagates the uncertainty in the val US/India estimate into France's implied score, | |
| since France is inferred by subtraction and the lever arm is 0.85/0.15 = 5.7x. | |
| """ | |
| import sys, glob | |
| import numpy as np, pandas as pd, joblib | |
| sys.path.insert(0, "src") | |
| import config as C, decide as DC | |
| b = joblib.load("work/results_A/model_bundle.joblib") | |
| MM, THR = b["miss_mass"], b["param"] | |
| s1 = pd.read_parquet(C.PATHS["test"]["source1"], columns=["entity_id", "country_norm"]) | |
| ctry = s1["country_norm"].astype(str).values | |
| N = len(s1) | |
| nq = {c: int((ctry == c).sum()) for c in np.unique(ctry)} | |
| wfr = nq["france"] / N | |
| d = pd.concat([pd.read_parquet(f) for f in | |
| sorted(glob.glob("work/results_A/test_chunks/chunk_*.parquet"))], | |
| ignore_index=True) | |
| d = DC.resolve_conflicts(d, "p") | |
| d["ctry"] = ctry[d["q"].values] | |
| fr = d[d.ctry == "france"][["q", "p"]].sort_values("q", kind="stable") | |
| fq, fp = fr["q"].values, fr["p"].values.astype(np.float64) | |
| uq, starts = np.unique(fq, return_index=True) | |
| idx = np.r_[starts, len(fq)] | |
| n_fr, n_nocand = nq["france"], nq["france"] - len(uq) | |
| def f05(g, t): | |
| pg = fp ** g | |
| sel = fp >= t | |
| tot = float(n_nocand) | |
| for i in range(len(uq)): | |
| a, z = idx[i], idx[i + 1] | |
| m = sel[a:z] | |
| k = int(m.sum()) | |
| tp = float(pg[a:z][m].sum()) | |
| T = tp + float(pg[a:z][~m].sum()) + MM | |
| tot += (np.exp(-T) if T > 0 else 1.0) if k == 0 else 1.25 * tp / (0.25 * T + k) | |
| return tot / n_fr | |
| print("=" * 78) | |
| print("ROBUSTNESS: France threshold choice across the whole plausible shift range") | |
| print("=" * 78) | |
| grid = [0.70, 0.75, 0.80, 0.85, 0.88, 0.90, 0.92, 0.95] | |
| print(f"{'g':>5}{'F@0.70':>10}" + "".join(f"{'d@'+format(t,'.2f'):>10}" for t in grid[1:]) | |
| + f"{' best thr':>11}") | |
| for g in [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0]: | |
| base = f05(g, 0.70) | |
| vals = [(t, f05(g, t)) for t in grid] | |
| bt, bv = max(vals, key=lambda x: x[1]) | |
| print(f"{g:>5.1f}{base:>10.5f}" + "".join(f"{v-base:>+10.5f}" for _, v in vals[1:]) | |
| + f"{bt:>11.2f}") | |
| print("\n" + "=" * 78) | |
| print("DOWNSIDE AT g=1 (calibration transfers perfectly - the pessimistic case for") | |
| print("this change) vs UPSIDE at g>=3, expressed on the LEADERBOARD") | |
| print("=" * 78) | |
| for g in [1.0, 2.0, 3.0, 4.0, 6.0]: | |
| base = f05(g, 0.70) | |
| for t in (0.85, 0.90): | |
| print(f" g={g:<4} thr {t:.2f}: France {f05(g,t)-base:+.6f} " | |
| f"-> leaderboard {wfr*(f05(g,t)-base):+.6f}") | |
| print("\n" + "=" * 78) | |
| print("HOW MUCH OF FRANCE'S DEFICIT CAN MISCALIBRATION EXPLAIN AT ALL?") | |
| print("=" * 78) | |
| print(f" at threshold 0.70: g=1 -> {f05(1.0,0.70):.6f} g=6 -> {f05(6.0,0.70):.6f}") | |
| print(" implied from leaderboard: 0.946062") | |
| print(" => even an extreme shift leaves a residual, so part of France's deficit is") | |
| print(" NOT the operating point: it is true pairs never retrieved or never scored.") | |
| print("\n" + "=" * 78) | |
| print("SENSITIVITY of France's implied score to the val US/India estimate") | |
| print("=" * 78) | |
| wus, win = nq["us"] / N, nq["india"] / N | |
| for dv in (-0.003, -0.002, -0.001, 0.0, 0.001, 0.002, 0.003): | |
| usin = wus * (0.9832 + dv) + win * (0.9806 + dv) | |
| print(f" val US/India {0.98177+dv:.5f} -> France {(0.976423-usin)/wfr:.5f}") | |