Download model-3/scripts/ens_probe.py from Jyo-K/PoPTard5: direct link, hf CLI and curl.
- Browser
- Download file 3.88 kB
-
https://huggingface.co/Jyo-K/PoPTard5/resolve/main/model-3/scripts/ens_probe.py
- Command line
-
hf download hf://Jyo-K/PoPTard5/model-3/scripts/ens_probe.py
-
curl -L -o ens_probe.py https://huggingface.co/Jyo-K/PoPTard5/resolve/main/model-3/scripts/ens_probe.py
3.88 kB
| """Sizing an ensemble with Chinmay's bge-m3 run (leaderboard 0.966) against ours (0.976423). | |
| F0.5 break-even, derived exactly: for one entity F0.5 = 1.25*TP/(0.25*T + k). Adding a | |
| candidate changes the denominator D = 0.25T + k by +1. Adding a TP gains | |
| 1.25(D-TP)/(D(D+1)); adding an FP loses 1.25*TP/(D(D+1)). So an extra pair is worth taking | |
| iff its TP:FP ratio beats TP/(D-TP), which at P=R=1 (T=k, D=1.25T) is exactly 4:1 - i.e. | |
| the added pairs need precision > 80%. | |
| This measures the SIZE of each disagreement region on the real test set, per country, so | |
| the break-even requirement can be applied. It cannot measure their precision (no test | |
| labels) - that is what a submission buys. | |
| """ | |
| import sys | |
| import numpy as np, pandas as pd | |
| sys.path.insert(0, "src") | |
| import config as C | |
| OURS = "output/matching_results.tsv" | |
| HIS = "/scratch/user4/dai/bge-out/runs/full_20260926T001535Z_f7bdb9/output/matching_results.tsv" | |
| def load(p): | |
| d = pd.read_csv(p, sep="\t", dtype=str, keep_default_na=False) | |
| print(f" {p.split('/')[-1]:<22} cols={list(d.columns)} rows={len(d):,}") | |
| a, b = d.columns[0], d.columns[1] | |
| out = {} | |
| for q, v in zip(d[a], d[b]): | |
| s = {x for x in str(v).split(",") if x} | |
| if s: | |
| out[q] = s | |
| return out | |
| print("loading both submissions") | |
| A, B = load(OURS), load(HIS) | |
| s1 = pd.read_parquet(C.PATHS["test"]["source1"], columns=["entity_id", "country_norm"]) | |
| ctry = dict(zip(s1["entity_id"], s1["country_norm"].astype(str))) | |
| allq = list(s1["entity_id"]) | |
| print(f"\ntest entities {len(allq):,} ours non-empty {len(A):,} his non-empty {len(B):,}") | |
| rows = [] | |
| for q in allq: | |
| a, b = A.get(q, set()), B.get(q, set()) | |
| rows.append((ctry.get(q, "?"), len(a), len(b), len(a & b), len(a - b), len(b - a))) | |
| df = pd.DataFrame(rows, columns=["ctry", "na", "nb", "both", "only_a", "only_b"]) | |
| print("\n" + "=" * 78) | |
| print("AGREEMENT STRUCTURE (pairs, per country)") | |
| print("=" * 78) | |
| g = df.groupby("ctry")[["na", "nb", "both", "only_a", "only_b"]].sum() | |
| g["entities"] = df.groupby("ctry").size() | |
| g["jaccard"] = g["both"] / (g["both"] + g["only_a"] + g["only_b"]) | |
| g["onlyB_per_entity"] = g["only_b"] / g["entities"] | |
| print(g.to_string()) | |
| tot = g.sum(numeric_only=True) | |
| print(f"\n TOTAL ours {int(tot['na']):,} his {int(tot['nb']):,} agree {int(tot['both']):,}") | |
| print(f" ours-only {int(tot['only_a']):,} HIS-ONLY {int(tot['only_b']):,}") | |
| print(f" overall jaccard {tot['both']/(tot['both']+tot['only_a']+tot['only_b']):.4f}") | |
| print("\n" + "=" * 78) | |
| print("WHAT A UNION WOULD ADD, and the precision it must clear") | |
| print("=" * 78) | |
| for c in g.index: | |
| add = g.at[c, "only_b"] | |
| cur = g.at[c, "na"] | |
| n = g.at[c, "entities"] | |
| print(f" {c:<8} adds {add:>9,} pairs to {cur:>9,} ({add/max(cur,1):>6.2%} more), " | |
| f"{add/n:>5.3f}/entity -> must exceed 80% precision to help") | |
| print("\n" + "=" * 78) | |
| print("HOW MANY OF HIS EXCLUSIVE PAIRS WERE EVEN IN OUR CANDIDATE SET?") | |
| print("=" * 78) | |
| print(" (pairs we never retrieved are the ones an ensemble uniquely unlocks; pairs we") | |
| print(" retrieved and rejected we already priced at p < 0.70 and measured as a losing") | |
| print(" trade at 1.9 TP per FP)") | |
| cp = pd.read_csv("output/candidate_pairs.tsv", sep="\t", dtype=str, | |
| keep_default_na=False, nrows=None) | |
| print(f" our candidate_pairs.tsv: cols={list(cp.columns)} rows={len(cp):,}") | |
| ca, cb = cp.columns[0], cp.columns[1] | |
| cand = {} | |
| for q, v in zip(cp[ca], cp[cb]): | |
| s = {x for x in str(v).split(",") if x} | |
| if s: | |
| cand[q] = s | |
| inc = nev = 0 | |
| for q in allq: | |
| ex = B.get(q, set()) - A.get(q, set()) | |
| if not ex: | |
| continue | |
| cs = cand.get(q, set()) | |
| inc += len(ex & cs) | |
| nev += len(ex - cs) | |
| print(f" his-exclusive pairs INSIDE our candidates : {inc:,} (we scored and rejected)") | |
| print(f" his-exclusive pairs we NEVER retrieved : {nev:,} (genuinely new)") | |