| """Fig 3 (hero figure): method performance progression — the 'three-step leap'. |
| |
| Validation F1 on the fixed split_seed=202 split; public-leaderboard F1 from the README |
| stage table. Sources for each point are noted inline. |
| """ |
| from pathlib import Path |
| import sys |
|
|
| import numpy as np |
| import matplotlib.pyplot as plt |
|
|
| sys.path.insert(0, str(Path(__file__).resolve().parent)) |
| from plot_style import apply, save, PALETTE_DEEP as C |
|
|
| apply() |
| ROOT = Path(__file__).resolve().parents[2] |
| FIG = ROOT / "reports" / "figures" |
|
|
| |
| stages = [ |
| ("Official\nbaseline", 0.885, None), |
| ("LightGCN\n(single)", 0.9386, 0.9304), |
| ("+ graph/meta-path\nstacking", 0.9560, 0.9576), |
| ("+ content\n+ BPR-MF", 0.9593, 0.9600), |
| ("+ rich content", 0.9599, None), |
| ("+ DeepWalk\n+ Node2Vec", 0.9621, 0.9625), |
| ("+ 7-block RW\nensemble", 0.9649, None), |
| ("+ high-order\npropagation", 0.9669, 0.9663), |
| ] |
| labels = [s[0] for s in stages] |
| val = np.array([s[1] for s in stages]) |
| lb_x = [i for i, s in enumerate(stages) if s[2] is not None] |
| lb_y = [s[2] for s in stages if s[2] is not None] |
|
|
| fig, ax = plt.subplots(figsize=(11.5, 5.4)) |
| x = np.arange(len(stages)) |
| ax.plot(x, val, "-o", color=C[0], label="Validation F1", zorder=3, markersize=7) |
| ax.plot(lb_x, lb_y, "--s", color=C[3], label="Public leaderboard F1", zorder=3, markersize=6) |
|
|
| for i, v in enumerate(val): |
| ax.annotate(f"{v:.3f}", (i, v), textcoords="offset points", xytext=(0, 9), |
| ha="center", fontsize=8.6) |
|
|
| |
| leaps = [(1, 2, "+0.017\nstacking"), (5, 6, "+0.003\nrandom-walk"), (6, 7, "+0.002\nhigh-order")] |
| y0 = 0.978 |
| for a, b, txt in leaps: |
| ax.annotate("", xy=(b, y0), xytext=(a, y0), |
| arrowprops=dict(arrowstyle="-|>", color=C[2], lw=1.6)) |
| ax.text((a + b) / 2, y0 + 0.0015, txt, ha="center", fontsize=8, color=C[2]) |
|
|
| ax.set_xticks(x) |
| ax.set_xticklabels(labels, fontsize=8.6) |
| ax.set_ylabel("F1 score") |
| ax.set_ylim(0.86, 0.99) |
| ax.set_title("Performance progression: three breakthroughs (validation split seed = 202)") |
| ax.legend(loc="lower right") |
| save(fig, "fig3_progression", FIG) |
| print("saved fig3_progression") |
|
|