NLP-beginner's picture
CS3319 Project 2 final deliverable (public F1 = 0.96626)
f28d994
Raw
History Blame Contribute Delete
2.94 kB
"""Appendix A4 — OOF discrimination: PR curves across stages + score histogram."""
from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve, average_precision_score
from style import apply, save, PALETTE as C, COL2 # noqa: E402
KEY = "figA4_oof_pr"
TITLE = "Appendix Figure A4. OOF discrimination across stages"
MODELS = [
("LightGCN ensemble", "dyn202_l2d512_bpr_bigbatch_more/scores/val_vanilla_ensemble_mean.npy", C[7]),
("+ graph stack", "post95_ablation/ensemble_lgcn_oof.npy", C[1]),
("+ DeepWalk/Node2Vec", "node2vec_deepwalk/node2vec_stack_oof.npy", C[2]),
("+ high-order (final)", "high_order_graph_stack/rich_rw7_highorder_directed_oof.npy", C[3]),
]
def make(root, out):
apply()
VR = root / "validation_runs" / "dynamic_seed202"
ypath = VR / "val_labels_seed202.npy"
if not ypath.exists():
return dict(key=KEY, title=TITLE, status="skipped", files=[], sources=[],
note="val_labels_seed202.npy missing — run gen_val_labels",
caption="needs validation labels")
y = np.load(ypath).astype(int)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(COL2, 3.1), gridspec_kw={"width_ratios": [1.6, 1]})
loaded = []
for name, rel, color in MODELS:
p = VR / rel
if not p.exists():
continue
s = np.load(p).astype(np.float64)
loaded.append((name, s, color))
pr, rc, _ = precision_recall_curve(y, s)
ap = average_precision_score(y, s)
ax1.plot(rc, pr, color=color, lw=1.7, label=f"{name} (AP={ap:.4f})")
ax2.hist(s, bins=60, histtype="step", color=color, lw=1.2, density=True)
ax1.set_xlabel("recall"); ax1.set_ylabel("precision"); ax1.set_ylim(0.9, 1.005)
ax1.set_title("(a) Precision–recall across stages", fontsize=8.5)
ax1.legend(fontsize=6.6, loc="lower left")
ax2.set_xlabel("OOF score"); ax2.set_ylabel("density")
ax2.set_title("(b) Score distribution (final)", fontsize=8.5)
fig.suptitle("Out-of-fold discrimination improves with each stacking stage", fontsize=9.5, y=1.02)
status = "ok" if len(loaded) == len(MODELS) else "partial"
save(fig, KEY, out)
return dict(key=KEY, title=TITLE, status=status, files=[f"{KEY}.pdf", f"{KEY}.png", f"{KEY}.svg"],
sources=[str(ypath)] + [str(VR / m[1]) for m in MODELS if (VR / m[1]).exists()],
caption=(
"Out-of-fold discrimination across stacking stages (validation, seed=202; labels "
"alignment-verified). (a) Precision–recall curves move outward at each stage; the final "
"high-order model reaches AP≈0.995. (b) Score distributions separate positives from "
"negatives with a clean margin."))
if __name__ == "__main__":
from style import ensure_dirs
r = make(Path("."), ensure_dirs(Path(".")))
print(r["key"], r["status"])