Buckets:

glennmatlin's picture
download
raw
6.86 kB
#!/usr/bin/env python3
# pyright: reportAttributeAccessIssue=false
"""Corrected 6-metric robustness recompute (top of tab:selectivity-robust), reading
gamma DIRECTLY from gamma_olmes_tidy.csv. Mirrors pilot_bootstrap_olmes.py ingestion
(expA = bin-targeted, expC = empirical naive top-K) and selectivity_M1 verbatim.
Six selectivity metrics, headline bin-rule = highest-attribution topic (argmax raw z-bin):
M1 mean-collateral sel = |g_t| / mean_{b!=t}|g_b|
M2 worst-case collateral sel = |g_t| / max_{b!=t}|g_b|
M3 excluding-shared sel = |g_t| / mean_{b!=t, b!=shared(t)}|g_b|
M4 signed damage ratio sel = |g_t| / mean_{b!=t} g_b (signed denominator)
M5 cosine-to-ideal cos([g_b]_b, onehot_t) (win if bin > naive)
M6 neg-entropy concentr. -sum p log p, p=|g|/sum|g| (win if bin > naive)
For M1-M4: ratio = sel_bin / sel_naive, win if >1. For M5-M6: win if bin metric > naive.
--baseline old : recompute g = OLD_BASE[b] - unlearned_acc (validation vs published table)
--baseline corrected : use the tidy g (config-matched :mc::olmes baselines) [default]
"""
import sys
from pathlib import Path
import numpy as np
import pandas as pd
HOME = Path.home()
ROOT = HOME / "scratch" / "n16_selectivity"
TIDY = ROOT / "results" / "gamma_olmes_tidy.csv"
ZSCORED_DIR = (
HOME
/ "dev"
/ "data-attribution"
/ "artifacts"
/ "zscored_bin_scores"
/ "aggregated"
)
OUT_DIR = ROOT / "results" / "robustness"
OUT_DIR.mkdir(parents=True, exist_ok=True)
BENCHMARKS = ["socialiqa", "mmlu_social_science", "mmlu_stem", "arc_challenge"]
DISPLAY = {
"socialiqa": "SocialIQA",
"mmlu_social_science": "MMLU-SS",
"mmlu_stem": "MMLU-STEM",
"arc_challenge": "ARC-C",
}
# Pre-correction (OLMo-3 Tech-Report) baselines — for reproducing the published table.
OLD_BASE = {
"socialiqa": 0.8029,
"mmlu_social_science": 0.7508,
"mmlu_stem": 0.5979,
"arc_challenge": 0.892,
}
# "Shared" benchmark excluded by M3 (same MMLU family pairing; socialiqa/arc pair to their
# nearest neighbor). Pinned by validation against the published table.
SHARED = {
"mmlu_stem": "mmlu_social_science",
"mmlu_social_science": "mmlu_stem",
"socialiqa": "mmlu_social_science",
"arc_challenge": "mmlu_stem",
}
def _gamma_col(df, mode):
if mode == "old":
return df.apply(lambda r: OLD_BASE[r.eval_benchmark] - r.unlearned_acc, axis=1)
return df.gamma
def load(mode):
df = pd.read_csv(TIDY)
df = df[df.eval_family == "primary"].copy()
df["g"] = _gamma_col(df, mode)
def cells(cond):
out = {}
for key, g in df[df.condition == cond].groupby("target_or_topic"):
out[str(key)] = dict(zip(g.eval_benchmark, g.g))
return out
expA_raw, expC = cells("expA"), cells("expC")
gamma = {}
for key, cell in expA_raw.items():
if "__" not in key:
continue
topic, target = key.rsplit("__", 1)
gamma.setdefault(target, {})[topic] = cell
return gamma, expC
def top1_topic(target):
z = pd.read_csv(ZSCORED_DIR / f"zscored_{target}.csv")
return z.loc[z.zscore.idxmax(), "topic_label"]
# ---- the six metrics ----
def _offs(target):
return [b for b in BENCHMARKS if b != target]
def m_mean(d, t):
o = [abs(d[b]) for b in _offs(t) if b in d]
m = float(np.mean(o)) if o else 0.0
return abs(d.get(t, 0.0)) / m if m > 0 else float("nan")
def m_worst(d, t):
o = [abs(d[b]) for b in _offs(t) if b in d]
m = max(o) if o else 0.0
return abs(d.get(t, 0.0)) / m if m > 0 else float("nan")
def m_exclshared(d, t):
o = [abs(d[b]) for b in _offs(t) if b in d and b != SHARED.get(t)]
m = float(np.mean(o)) if o else 0.0
return abs(d.get(t, 0.0)) / m if m > 0 else float("nan")
def m_signed(d, t):
o = [d[b] for b in _offs(t) if b in d]
m = float(np.mean(o)) if o else 0.0
return abs(d.get(t, 0.0)) / abs(m) if m != 0 else float("nan")
def _vec(d, t):
return np.array([d.get(b, 0.0) for b in BENCHMARKS], float), BENCHMARKS.index(t)
def m_cosine(d, t):
v, ti = _vec(d, t)
n = np.linalg.norm(v)
if n == 0:
return float("nan")
ideal = np.zeros_like(v)
ideal[ti] = 1.0
return float(np.dot(v, ideal) / n) # = |v_t|/||v|| (sign via v_t)
def m_negentropy(d, t):
a = np.abs([d.get(b, 0.0) for b in BENCHMARKS])
s = a.sum()
if s == 0:
return float("nan")
p = a / s
nz = p[p > 0]
return float(
np.sum(nz * np.log(nz))
) # negative entropy (higher = more concentrated)
RATIO_METRICS = [
("mean", m_mean),
("worst", m_worst),
("excl_shared", m_exclshared),
("signed", m_signed),
]
WIN_METRICS = [("cosine", m_cosine), ("neg_entropy", m_negentropy)]
def main():
mode = "corrected"
if "--baseline" in sys.argv:
mode = sys.argv[sys.argv.index("--baseline") + 1]
gamma, expC = load(mode)
print(f"=== 6-metric robustness (highest-attribution topic), baseline={mode} ===\n")
rows = []
for name, fn in RATIO_METRICS:
cells, wins = [], 0
for t in BENCHMARKS:
k = top1_topic(t)
dbin = gamma.get(t, {}).get(k, {})
dnaive = expC.get(t, {})
if not dbin or not dnaive:
cells.append("---")
continue
sb, sn = fn(dbin, t), fn(dnaive, t)
r = sb / sn if (sn and not np.isnan(sn) and sn != 0) else float("nan")
win = (not np.isnan(r)) and r > 1.0
wins += int(win)
cells.append(f"{r:.2f}x{'*' if win else ' '}")
rows.append((name, cells, wins))
print(
f" {name:14s} "
+ " ".join(f"{DISPLAY[b]}={c}" for b, c in zip(BENCHMARKS, cells))
+ f" wins={wins}/4"
)
for name, fn in WIN_METRICS:
cells, wins = [], 0
for t in BENCHMARKS:
k = top1_topic(t)
dbin, dnaive = gamma.get(t, {}).get(k, {}), expC.get(t, {})
if not dbin or not dnaive:
cells.append("---")
continue
vb, vn = fn(dbin, t), fn(dnaive, t)
win = (not np.isnan(vb)) and (not np.isnan(vn)) and vb > vn
wins += int(win)
cells.append("win" if win else "loss")
rows.append((name, cells, wins))
print(
f" {name:14s} "
+ " ".join(f"{DISPLAY[b]}={c}" for b, c in zip(BENCHMARKS, cells))
+ f" wins={wins}/4"
)
out = pd.DataFrame(
[
{"metric": n, **{DISPLAY[b]: c for b, c in zip(BENCHMARKS, cs)}, "wins": w}
for n, cs, w in rows
]
)
dest = OUT_DIR / f"robustness_6metric_{mode}.csv"
out.to_csv(dest, index=False)
print(f"\nwrote {dest}")
if __name__ == "__main__":
main()

Xet Storage Details

Size:
6.86 kB
·
Xet hash:
e20653a40fd989cde6a1a3d5408948d36e6d64fb989a34ed16ba3929433cd209

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.