"""Appendix A2 — Random-walk ensemble size vs validation F1.""" from pathlib import Path import pandas as pd import matplotlib.pyplot as plt from style import apply, save, PALETTE as C, COL1 # noqa: E402 KEY = "figA2_rw_ablation" TITLE = "Appendix Figure A2. Random-walk ensemble size vs F1" def make(root, out): apply() RW = root / "validation_runs" / "dynamic_seed202" / "randomwalk_systematic" try: single = pd.read_csv(RW / "small_ablation_table.csv").validation_F1.max() e5 = pd.read_csv(RW / "ensemble_5_ablation.csv").validation_F1.iloc[0] e7 = pd.read_csv(RW / "ensemble_7_ablation.csv").validation_F1.iloc[0] status = "ok"; sources = ["small_ablation_table.csv", "ensemble_5_ablation.csv", "ensemble_7_ablation.csv"] except FileNotFoundError as e: return dict(key=KEY, title=TITLE, status="skipped", files=[], sources=[], note=str(e), caption="RW ablation CSVs missing") sizes, f1s = [1, 5, 7], [single, e5, e7] fig, ax = plt.subplots(figsize=(COL1 * 1.35, 3.0)) ax.plot(sizes, f1s, "-o", color=C[2], lw=1.8, ms=8) for s, f in zip(sizes, f1s): ax.text(s, f + 0.00015, f"{f:.5f}", ha="center", fontsize=7.5, fontweight="bold") ax.set_xlabel("# RW embedding configs"); ax.set_ylabel("validation F1") ax.set_xticks(sizes) ax.set_ylim(min(f1s) - 0.0005, max(f1s) + 0.0005) ax.set_title("RW ensemble size vs F1 (used 7 in final)", fontsize=9) save(fig, KEY, out) return dict(key=KEY, title=TITLE, status=status, files=[f"{KEY}.pdf", f"{KEY}.png", f"{KEY}.svg"], sources=[str(RW / s) for s in sources], caption=( "Random-walk ensemble size vs validation F1 (same base features). Moving from the best " "single DeepWalk/Node2Vec config to a 5-block and then 7-block ensemble of diverse configs " "yields a steady +0.00182; 7 blocks are used in the final model.")) if __name__ == "__main__": from style import ensure_dirs r = make(Path("."), ensure_dirs(Path("."))) print(r["key"], r["status"])