Omibranch commited on
Commit
d46ab95
·
verified ·
1 Parent(s): 43b04b5

Upload colab_xfamily_analyze.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. colab_xfamily_analyze.py +90 -0
colab_xfamily_analyze.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Cross-family deception transfer — STAGE 2: probe transfer analysis.
2
+
3
+ Train a linear deception probe on the relative-representation space of ONE
4
+ model family, test zero-shot on the OTHERS. If deception lives in a
5
+ basis-invariant relative geometry shared across families, the probe transfers.
6
+ """
7
+ import json, numpy as np
8
+ from sklearn.linear_model import LogisticRegression
9
+ from sklearn.preprocessing import StandardScaler
10
+ from sklearn.metrics import roc_auc_score
11
+ from sklearn.model_selection import cross_val_score, StratifiedKFold
12
+
13
+ d = json.load(open("/content/rift_xfamily_reps.json"))
14
+ models = [m for m in d["models"] if m in d["data"]]
15
+ short = {m: m.split("/")[-1] for m in models}
16
+ print("models:", [short[m] for m in models])
17
+ print(f"anchors: {len(d['anchors'])}, facts: {d['n_facts']}, layer_frac: {d['layer_frac']}\n")
18
+
19
+ # Per-model standardization aligns the cosine-similarity distributions across
20
+ # families (different anisotropy) so the probe compares relative structure.
21
+ Z = {}
22
+ for m in models:
23
+ X = np.array(d["data"][m]["X"], dtype=float); y = np.array(d["data"][m]["y"])
24
+ n_nan = int(np.isnan(X).sum())
25
+ X = np.nan_to_num(X, nan=0.0, posinf=0.0, neginf=0.0)
26
+ sc = StandardScaler().fit(X)
27
+ Xz = np.nan_to_num(sc.transform(X), nan=0.0, posinf=0.0, neginf=0.0)
28
+ Z[m] = (Xz, y)
29
+ print(f" {short[m]}: X{X.shape}, raw NaN={n_nan}, "
30
+ f"constant-anchor features={(X.std(axis=0)==0).sum()}")
31
+ print()
32
+
33
+ def make_probe():
34
+ return LogisticRegression(C=1.0, max_iter=5000, solver="lbfgs")
35
+
36
+ rng = np.random.default_rng(0)
37
+ N_PERM = 5000
38
+
39
+ print("=" * 70)
40
+ print("CROSS-FAMILY DECEPTION PROBE TRANSFER (AUC)")
41
+ print("=" * 70)
42
+ matrix = {}
43
+ cross_aucs = []
44
+ for tr in models:
45
+ Xtr, ytr = Z[tr]
46
+ row = []
47
+ for te in models:
48
+ Xte, yte = Z[te]
49
+ if tr == te:
50
+ auc = cross_val_score(make_probe(), Xtr, ytr,
51
+ cv=StratifiedKFold(5, shuffle=True, random_state=0),
52
+ scoring="roc_auc").mean()
53
+ tag = "CV"
54
+ p = None
55
+ else:
56
+ p_ = make_probe().fit(Xtr, ytr)
57
+ scores = p_.predict_proba(Xte)[:, 1]
58
+ auc = roc_auc_score(yte, scores)
59
+ # permutation test: how often do shuffled test labels beat observed?
60
+ null = np.array([roc_auc_score(rng.permutation(yte), scores)
61
+ for _ in range(N_PERM)])
62
+ p = float((null >= auc).mean())
63
+ tag = f"p={p:.4f}"
64
+ cross_aucs.append(auc)
65
+ matrix[f"{short[tr]}->{short[te]}"] = {"auc": float(auc), "p": p}
66
+ row.append(f"{auc:.3f}({tag})")
67
+ print(f"{short[tr]:28s} -> " + " | ".join(f"{short[te][:10]:>10s}:{r}"
68
+ for te, r in zip(models, row)))
69
+
70
+ print("\n" + "=" * 70)
71
+ ca = np.array(cross_aucs)
72
+ print(f"MEAN cross-family AUC: {ca.mean():.3f} (min {ca.min():.3f}, max {ca.max():.3f})")
73
+ print(f"cross-family pairs above 0.7: {(ca > 0.7).sum()}/{len(ca)}")
74
+ print(f"cross-family pairs above 0.8: {(ca > 0.8).sum()}/{len(ca)}")
75
+ allp = [v["p"] for v in matrix.values() if v["p"] is not None]
76
+ print(f"cross-family pairs significant (p<0.05): {sum(p < 0.05 for p in allp)}/{len(allp)}")
77
+
78
+ verdict = ("UNIVERSAL DECEPTION GEOMETRY: probe transfers across families"
79
+ if ca.mean() > 0.75 and all(p < 0.05 for p in allp)
80
+ else "PARTIAL transfer — some shared structure"
81
+ if ca.mean() > 0.6
82
+ else "NO cross-family transfer — deception geometry is family-specific")
83
+ print(f"\nVERDICT: {verdict}")
84
+
85
+ json.dump({"matrix": matrix, "mean_cross_auc": float(ca.mean()),
86
+ "cross_aucs": ca.tolist(), "verdict": verdict,
87
+ "models": models, "n_anchors": len(d["anchors"]),
88
+ "n_facts": d["n_facts"]},
89
+ open("/content/rift_xfamily_results.json", "w"), indent=2)
90
+ print("\nsaved /content/rift_xfamily_results.json")