cs3319-project2 / docs_first_principles /09_experiment_timeline.md
NLP-beginner's picture
CS3319 Project 2 final deliverable (public F1 = 0.96626)
f28d994
|
Raw
History Blame Contribute Delete
14.7 kB

09 实验演进时间线 (Experiment Timeline)

本文档面向"懂一点 ML 但不完全懂图推荐系统"的读者,从第一性原理梳理 CS3319 Project 2 这条 author↔paper 阅读推荐链路从 baseline 到最终 0.96626 的完整演进。每一阶段都讲清楚"为什么这么做""验证上拿到什么数字""学到了什么教训",所有数值均带可核验来源(以 validation_runs/ 下 CSV 与 README/reports 为准),无法核验的项明确标注 not explicitly confirmed


1. 任务回顾与本时间线的坐标系

任务是异构学术网络上的二部图链路预测:对 ~2.05M 测试对输出 0/1,公开榜只评 50% 测试对,指标是 F1。我们在全程使用了同一把验证尺子 —— make_notebook_style_split(seed=202, train_frac=0.9)(code/train_val_lgcn_ensemble.py:132-165):留出 10% 已知正边(68,242 对)作正例,再等量随机采样非边作负例,得到 136,484 对、1:1 的人工平衡验证集(val_labels_seed202.npy)。

为什么强调这一点?因为只有验证集固定,后续每一个阶段的"验证 F1"才可比。而正因为验证集是人为 1:1 平衡的、与测试集真实分布不同,我们最终放弃验证最优概率阈值,改用 rank cutoff top 50% 决策 —— 这是贯穿全时间线的一条主线,详见 §5。

下文表格里的两类分数:

  • Validation F1:同 seed=202 切分下的 5-fold StratifiedKFold OOF F1(leak-free,由 best_f1() 取 PR 曲线 argmax)。
  • Public F1:该阶段对应提交 CSV 在 Kaggle 公开榜的实际分数(口径不同,数值不必单调等于验证 F1)。

2. 实验演进总表(可直接转论文结果表)

下表是本文档的核心产物,数字全部有原始 CSV 或 README/reports 来源,无来源处标 not explicitly confirmed

Stage Method Main idea Validation F1 Public F1 Key lesson
0 官方 notebook 基线 (run_baseline.py, legacy) HeteroMeanConv + hinge/ranking,cosine 打分 + 阈值搜索 ≈0.8850 not explicitly confirmed 简单 mean 聚合 + 简单负采样太弱;复杂非线性 GNN 在该任务上不如轻量 CF
1 LightGCN 异构 CF 集成 纯加权邻居聚合(无 W 无非线性)+ BPR + 硬负采样,多 seed/维集成 0.93857648 0.93044 (6-model sub_ens6_t0.36.csv) 去掉 MLP/非线性反而更稳更强;CF 范式天然贴合推荐任务
2 + 显式图 / meta-path stacking 把 LightGCN 分数与手工图特征(A-A-P / A-P-P / A-P-A-P、度、common 邻居)拼成 ~76 维,LightGBM 5-fold OOF 0.9559916871555707 not explicitly confirmed (post95 ≈0.95760) 单阶段最大增益 +0.0174;meta-path 补上了 LightGCN 看不见的多跳结构盲区,真正突破 0.95
3 Post95 变体特征 stacker 在 stack 基础上把 20 个 LightGCN 变体分数做 zscore+rank01 聚合(+top-k 内容相似度/负证据) 0.9571095502729724 ≈0.95760 同源分数的多变体聚合能稳定小幅提升;但单组特征(如 neg/topk)单独贡献微弱甚至微负
4 + Content mean-cos 作者历史论文 embedding 均值 · 候选论文向量,作第 4 个分数源 0.9576285428276249 语义内容信号是 CF 之外的互补视角
5 + BPR-MF 矩阵分解 BPR(dim=256)作独立 CF 分数源,纳入 84 维 X_base 0.959308321934092 ≈0.95996 矩阵分解与 LightGCN 互补,二者联合比任一单 CF 更强
6 + rich content (18 维, feature.pkl) 直接从 512-d USE 论文嵌入抽 18 维作者/候选内容画像 0.95990 (figures / notes) 深层内容画像进一步缩小 CF 盲区
7 + DeepWalk / Node2Vec 在二部/合著/引用图上随机游走 + Word2Vec,产接近度嵌入,作新分数源 0.9621153367764501 (+node2vec) ≈0.96252 随机游走捕获全局接近度,是 LightGCN 局部 CF 看不到的尺度
8 + 7 RW blocks 一致性聚合 系统 7 块游走配置(DeepWalk/Node2Vec, d128/d256, l40/l80),每块 11 维 + 11 维一致性聚合 0.9649210283178503 not explicitly confirmed (r0.500 公开约 0.96229, 低于上一阶段) 关键教训:验证 F1 随 RW 数量上升,但公开分反而略降 —— validation 对"堆更多同源模型"系统性偏乐观,过拟合 seed=202
9 + 高阶引用传播 (undirected → directed, 259 维) $H_k = R\cdot C^k$(作者历史论文经 k 步引用扩散)+ $G_k = S\cdot R\cdot C^k$(合著者历史论文扩散),fwd/bwd/undir 三向 0.966873736337297 0.96626 最终方法。显式建模"作者读过的论文被引用链路指向的候选论文",是有向、可解释的结构先验,把验证 0.9649 → 0.9669、公开 0.96252 → 0.96626

来源说明:Stage 1 验证分 dynamic_summary.csv 首行 dyn202_l2d512_bpr_bigbatch_more=0.93857648;Stage 2 stack_threshold_summary.csv seed202 行 0.9559916871555707;Stage 3–5 extra_score_ablation.csv(post95_lgbm_baseline=0.9571095502729724 / +content_mean_cos=0.9576285428276249 / +bpr_mf=0.959308321934092);Stage 6 rich content 18 维增益到 0.95990 据 reports/notes,缺独立 CSV 复核;Stage 7 node2vec_deepwalk_ablation.csv(+node2vec=0.9621153367764501);Stage 8 ensemble_7_ablation.csv=0.9649210283178503;Stage 9 high_order_graph_stack/validation_summary.csv(rich_rw7_highorder_directed=0.966873736337297)。公开分链条 0.93044 → 0.95760 → 0.95996 → 0.96252 → 0.96626 见 README.md:42-46


3. 三段大跃迁的第一性原理解读

3.1 跃迁一:从"复杂 GNN"到"轻量 CF"(Stage 0→1,+0.054 验证)

早期我们试过官方 HeteroMeanConv、PyG SAGEConv+残差/layernorm/MLP 解码器、SAGEConv+BPR(见 notes/experiment_history.md §1–3,脚本 run_baseline.py/run_improved.py/run_v2.py,均为 legacy,硬编码 /home/lzc 路径)。直觉上"更强的网络应该更好",但验证分长期停在 0.885–0.93 区间。

切换到 LightGCN(code/train_val_lgcn_ensemble.py:49-104)是关键转折:它删掉了所有权重矩阵和非线性,只做入度归一的邻居加权聚合(LightGCNLayer),用点积解码、BPR 损失 + 硬负采样(sample_hard_negatives 混合 random/popular/coauthor-pool)。验证分直接跳到 0.9386。教训是:推荐任务里,显式特征交互往往由后端的 LightGBM 来学,前端 GNN 越简洁、越不容易过拟合到稀疏图(密度仅 1.29e-3、56% 作者度=1)的噪声上

口径提醒(见事实表 #10):6-model 公开 0.93044(5×256d/4层 + 1×384d,早期 sub_ens6_t0.36.csv)与动态 best 验证 0.9386(2 seed × 512d/2层 dot,dyn202_l2d512_bpr_bigbatch_more)是两个不同阶段产物,不要混用。

3.2 跃迁二:从"单分数"到"meta-path stacking"(Stage 1→2,+0.0174 验证)

LightGCN 单分数卡在 0.939 左右。真正突破 0.95 的是把 LightGCN 分数和手工图/meta-path 特征一起喂给 LightGBM(code/stack_rank_calibration.py)。这些特征包括显式的多跳共同邻居:A-A-P(合著者共同论文)、A-P-P(作者论文→引用论文)、A-P-A-P 等,加上度、rank 校准(add_rank_features 产 score/global_rank/author_pct/author_rank 4 列)。

为什么这是单阶段最大增益?因为 LightGCN 学的是局部、隐式的 CF 表征,它看不见"我的合著者读过哪些论文""我读过的论文引用了哪些候选论文"这种显式、可数、多跳的结构事实。把这些手工特征堆到第二阶段,等于把"模型不确定的"和"图结构明确告诉你的"两条信息源交给一个 calibrator 联合裁决。验证分稳定跨 4 seed 都在 0.9555–0.9560(exploration_summary.md §4.3 表),说明这是真信号而非 seed 噪声。

一处冗余(见事实表 #13):ExplicitGraphFeatures.transformout[i,12]out[i,3] 字面重复(co_read_count),LightGBM 会自动忽略共线列;"18 维有效信息"实为 17 维独立。

3.3 跃迁三:从"局部 CF"到"高阶有向引用传播"(Stage 8→9,+0.0020 验证 / +0.0037 公开)

最后一步是高阶引用传播(code/high_order_graph_stack.pybuild_high_order*,硬编码稀疏矩阵形状 6611×79937)。核心两式:

Hk=RCk,Gk=SRCkH_k = R \cdot C^k, \qquad G_k = S \cdot R \cdot C^k

其中 $R$ 是作者-论文二部矩阵,$C$ 是有向引用邻接(fwd/bwd/undir 三向),$S$ 是合著邻接。直觉解读:$H_k$ 表示"作者历史论文经 $k$ 步引用扩散到候选论文"的强度,$G_k$ 把"合著者的历史论文"也扩散进来。这把"我读过的论文 → 它引用/被引用的论文 → 我的候选论文"这条有向、可解释的语义链路显式建模成特征。

validation_summary.csv 的四行消融清楚展示了这一增量:

stage n_features validation F1 增量
base_highorder 108 0.9642697338013148
rich_rw7 190 0.9649474248055991 +0.000678
rich_rw7_highorder (+undirected, 24 维) 214 0.9665557233547776 +0.001608
rich_rw7_highorder_directed (+directed, 45 维) 259 0.966873736337297 +0.000318

关键观察:undirected(无向)贡献最大(+0.0016),directed(有向)再补 +0.0003,但正是这 +0.0003 把公开分从 ≈0.96252 推到 0.96626。方向性在这里不是锦上添花,而是抓住了"引用是被引→引用还是引用→被引"这种 LightGCN/无向聚合无法区分的真实因果结构。


4. 两条贯穿全程的方法论教训

教训 A:验证集与公开榜存在系统性偏差。 Stage 8 是最典型例子 —— 7 RW blocks 验证 F1 0.964921 比初版 Node2Vec 0.962115 高,但其 r0.500 公开分仅约 0.96229(reports 记载值,未在权威事实表核验;exploration_summary.md §16),低于上一阶段的 0.96252。原因:验证集是人为 1:1 平衡的,堆更多同源 RW 模型会过拟合到这个特定切分。这直接导致我们最终不信任"验证最优概率阈值"。

教训 B:决策用 rank cutoff 而非概率阈值。 validation_summary.csv 给出的验证最优阈值是 0.46173080801963806,但 threshold_submission_summary.csv 显示:把这个阈值迁移到 test,正例比例漂移到 0.5241947537735766(应为 ~0.5 量级却多出 2.4 个百分点,对应 changed_vs_anchor=55638 对翻转)。改用 rank top 50%(submission_summary.csv 的 r0.500000 行)后,正例比例精确锁在 0.5000(changed_vs_anchor=34863)。决策规则再加一道 cached_scores/test_known_mask.npy 强制把 train/test 重叠的 524,083 条已知正边(占测试 25.6%)置 1。这套规则就是最终 0.96626 的来源。


5. 流程图:从原始数据到最终提交

原始边 (data_and_docs/)
   │  682,421 训练正边 / 2,047,262 测试对 / 9,663 合著 / 327,113 引用 / feature.pkl(79,937×512)
   ▼  make_notebook_style_split(seed=202)
验证集 (136,484 对, 1:1)
   │
   ├── Stage 1: train_val_lgcn_ensemble.py → LightGCN 主分数
   │            (0.9386 验证 / 0.93044 公开 6-model)
   ├── Stage 2: stack_rank_calibration.py → explicit18 + rank4 → LightGBM
   │            (0.9560 验证)
   ├── Stage 3-5: generate_post95 + extra_score_sources → variant43 + content_mean4 + bpr4
   │            (0.9576 → 0.9593 验证 / ≈0.95996 公开)
   ├── Stage 6-7: content_rich + node2vec_deepwalk → rich18 + RW 初版
   │            (0.9621 验证 / ≈0.96252 公开)
   ├── Stage 8: randomwalk_systematic → 7×11 RW + 11 聚合
   │            (0.9649 验证, 但公开偏乐观)
   └── Stage 9: high_order_graph_stack.build_high_order* → undir24 + directed45
                (0.9669 验证 / 0.96626 公开, 最终 259 维 LightGBM)
                            │
                            ▼  rank top 50% + test_known_mask 强制 1
                submission_rich_rw7_highorder_directed_r0.500000.csv

6. 关于本时间线的可信度说明

  • 所有"验证 F1"均可在 validation_runs/dynamic_seed202/ 对应 CSV 中逐字核验(已在本审计中实测);唯一例外是 Stage 6 rich content 18 维的 0.95990,仅见 reports/figures caption,缺独立 CSV,据实标注。
  • "公开 F1"来自 README/reports 与提交文件名;除最终 0.96626、6-model 0.93044 外,中间若干公开分(0.95760 / 0.95996 / 0.96252)为 README 记载的约值,not explicitly confirmed 到小数末位。
  • WORKSPACE_STATUS.md(2026-06-17)曾称 validation_runs/dynamic_seed202/ 等关键目录缺失,实测为误(目录均存在且含真实产物),本时间线以当前文件系统与 CSV 为准。

可迁移到论文中的写法

以下表述可直接进入 ACM 中文论文的"实验/结果"章节,数值与口径与本仓库原始 CSV 完全一致。

结果表(建议作为论文主表 Table 1):

我们在固定的 seed=202 验证切分(68,242 正例 + 68,242 随机负例,共 136,484 对)上以 5-fold StratifiedKFold OOF F1 评估每个阶段,并在 Kaggle 公开榜(测试集的 50%)验证泛化性。表 1 汇总了从启发式基线到最终方法的演进。最大单阶段增益来自显式 meta-path 堆叠(0.9386 → 0.9560,+0.0174),最终的高阶有向引用传播 $H_k=R\cdot C^k$、$G_k=S\cdot R\cdot C^k$ 在 259 维 LightGBM 二级 meta-learner 上取得验证 F1 = 0.96687、公开 F1 = 0.96626。

方法叙述段(可直接进 Experiments):

实验演进可归纳为三段跃迁:(1) 从复杂异构 GNN 转向无权重、无非线性的 LightGCN(+0.054 验证),表明在极稀疏(密度 $1.29\times10^{-3}$)的长尾图上,轻量协同过滤优于过参数化编码器;(2) 引入显式多跳 meta-path 特征并与 LightGCN 分数联合送入 LightGBM(+0.0174 验证),补足了 CF 无法捕获的可数结构先验;(3) 提出高阶有向引用传播,将"作者历史论文经引用链扩散至候选"建模为稀疏矩阵幂 $R\cdot C^k$ 与 $S\cdot R\cdot C^k$,在 fwd/bwd/undir 三向特征上把验证 F1 由 0.9649 提升至 0.9669,公开 F1 由 0.96252 提升至 0.96626。

决策规则段(可直接进 Implementation Details):

由于 1:1 平衡验证集与测试集存在分布偏移,验证最优概率阈值 0.4617 迁移至测试后正例率漂移至 0.5242。我们改用 rank cutoff:按预测分对测试对排序取 top 50% 为正,并将 524,083 条训练-测试重叠的已知正边(mask 占比 25.6%)强制置 1,得到稳定且校准的最终提交。

消融表述(对应论文消融小节):

表 2 给出高阶传播的逐层消融:base(108 维)0.96427 → +rich_rw7(190 维)0.96495 → +无向高阶(214 维)0.96656 → +有向高阶(259 维)0.96687;其中无向传播贡献 +0.00161,有向传播贡献 +0.00032,AUC 由 0.99405 升至 0.99492,验证了方向性引用结构对推荐排序的增益。