cs3319-project2 / figures_paper /scripts /fig4_architecture.py
NLP-beginner's picture
CS3319 Project 2 final deliverable (public F1 = 0.96626)
f28d994
Raw
History Blame Contribute Delete
4.27 kB
"""Figure 4 — Final pipeline architecture.
Five input streams converge into a LightGBM OOF stacker, a rank-cutoff top-50% decision,
and the submission. The high-order stream carries the two propagation formulae
H_k = R C^k and G_k = S R C^k rendered with mathtext.
"""
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
from style import apply, save, PALETTE as C, COL2 # noqa: E402
KEY = "fig4_architecture"
TITLE = "Figure 4. Final pipeline architecture"
def _box(ax, x, y, w, h, text, color, fs=7.6, fc_alpha=0.16, weight="bold"):
ax.add_patch(FancyBboxPatch((x, y), w, h, boxstyle="round,pad=0.06,rounding_size=0.12",
fc=color, ec=color, alpha=fc_alpha, lw=1.5))
ax.text(x + w / 2, y + h / 2, text, ha="center", va="center", fontsize=fs,
fontweight=weight, color="black")
def _arrow(ax, a, b, color="black", lw=1.3):
ax.add_patch(FancyArrowPatch(a, b, arrowstyle="-|>", mutation_scale=12, color=color, lw=lw))
def make(root, out):
apply()
fig, ax = plt.subplots(figsize=(COL2, 4.3))
ax.set_xlim(0, 13.6); ax.set_ylim(0, 6.2); ax.axis("off")
# source
_box(ax, 0.2, 2.7, 1.9, 0.9, "Official\nData", C[7], fs=8.5)
# five feature streams
streams = [
(4.6, "Author–Paper graph", "LightGCN score / rank", C[0]),
(3.7, "Coauthor + citation graph", "explicit graph / meta-path feats", C[1]),
(2.8, "feature.pkl", "content sim. + rich profile", C[2]),
(1.9, "mixed graph", "DeepWalk / Node2Vec pair feats", C[3]),
(1.0, "$R\\,C^{k}$ and $S\\,R\\,C^{k}$", "high-order propagation feats", C[4]),
]
for y, src, feat, col in streams:
_box(ax, 3.7, y - 0.30, 3.4, 0.62, f"{feat}", col, fs=7.2)
ax.text(3.7 + 3.4 + 0.08, y, src, ha="left", va="center", fontsize=6.6, color="dimgray")
_arrow(ax, (2.1, 3.15), (3.7, y))
# high-order propagation formula panel, linked to its feature stream
ax.add_patch(FancyBboxPatch((8.45, 0.30), 3.15, 1.30,
boxstyle="round,pad=0.06,rounding_size=0.12",
fc=C[4], ec=C[4], alpha=0.10, lw=1.3))
ax.text(8.55, 1.42, "high-order propagation", fontsize=7.2, color=C[4], fontweight="bold")
ax.text(10.0, 1.10, "$H_k = R\\,C^{\\,k}$", fontsize=11, color=C[4], ha="center")
ax.text(10.0, 0.72, "$G_k = S\\,R\\,C^{\\,k}$", fontsize=11, color=C[4], ha="center")
ax.text(10.0, 0.42,
"$R$: author–paper $C$: citation $S$: coauthor",
fontsize=6.2, color="dimgray", ha="center")
_arrow(ax, (7.1, 1.0), (8.45, 0.95), color=C[4], lw=1.2)
# stacker + decision + submission
_arrow(ax, (7.1, 2.8), (9.4, 4.3))
_box(ax, 9.4, 3.85, 2.5, 0.95, "LightGBM\nOOF stacker\n(259-d)", C[5], fs=8)
_arrow(ax, (10.65, 3.85), (10.65, 3.05))
_box(ax, 9.4, 2.15, 2.5, 0.85, "rank cutoff\ntop 50% + known pos.", C[6], fs=7.6)
_arrow(ax, (11.9, 2.55), (12.6, 2.55))
_box(ax, 12.5, 2.10, 1.0, 0.9, "sub.", C[7], fs=8)
ax.set_title("Final two-stage stacking pipeline", fontsize=10)
save(fig, KEY, out)
return dict(key=KEY, title=TITLE, status="ok",
files=[f"{KEY}.pdf", f"{KEY}.png", f"{KEY}.svg"],
sources=["schematic"],
caption=(
"Final pipeline. Five feature streams — LightGCN score/rank, explicit graph and meta-path "
"features, content similarity and rich author–content profiles, DeepWalk/Node2Vec pair "
"features, and high-order propagation features — are concatenated into a 259-d vector and "
"fed to a LightGBM out-of-fold stacker. A rank-cutoff decision (top 50% positive, known "
"positives forced to 1) produces the submission. High-order features are defined by "
"$H_k = R\\,C^{k}$ (author reaches papers $k$ citation hops away) and $G_k = S\\,R\\,C^{k}$ "
"(same, mediated by coauthorship), where $R$ is the author–paper matrix, $C$ the citation "
"matrix and $S$ the coauthorship matrix."))
if __name__ == "__main__":
from style import ensure_dirs
r = make(Path("."), ensure_dirs(Path(".")))
print(r["key"], r["status"])