4、GraphSAGE:采样与聚合、归纳式学习、大规模图上的应用

说实话,GCN 虽然好用,但它有个硬伤——它是直推式的。什么意思呢?就是训练的时候,你得把整张图都端上来,所有节点都得在场。一旦来了新节点,不好意思,得重新训练。这在工业界太不现实了。

我当年在金融风控项目里就踩过这个坑。每天都有新用户注册,新交易产生,图结构一直在变。用 GCN 的话,每天凌晨都得全量重训,算力扛不住,时效性也差。后来换成了 GraphSAGE,问题就解决了。

GraphSAGE 的核心思想其实很简单:我不学节点的 embedding,我学怎么聚合邻居信息。这样新节点来了,我只要拿它的邻居特征,走一遍聚合函数,就能算出它的 embedding。这就是归纳式学习。

4.1 采样:邻居不是越多越好

GCN 做消息传递时,用的是全邻居。GraphSAGE 不一样,它采样。为什么?

  • 全邻居的计算复杂度是 O(|V|×|E|),图大了根本扛不住
  • 每个节点的度差异很大,有的节点几万个邻居,有的就两三个
  • 采样能控制计算量,让训练更稳定

GraphSAGE 的采样策略是固定大小的邻居采样。比如设定采样数 K=3,那就从邻居里随机抽 3 个。如果邻居不够 3 个,就重复采样补齐。

核心公式:第 l 层的邻居采样数 Sl,通常 S1 > S2 > S3,越往外层采得越少。

我个人习惯设 S1=25, S2=10。为什么这么设?因为第一层离目标节点近,信息最相关,多采点;第二层是间接邻居,信息量递减,少采点。这样既保留了局部结构,又控制了计算量。

避坑指南:我曾经把采样数设得太大,结果每个 batch 的邻居数爆炸,显存直接 OOM。后来改成逐层递减采样,问题就解决了。你想想看,如果每层都采 25 个,两层就是 25×25=625 个节点,三层就是 15625 个。这谁顶得住?

4.2 聚合:三种方式各有千秋

采样完邻居,下一步就是聚合。GraphSAGE 提供了三种聚合函数:

聚合方式 特点 适用场景
Mean 聚合 对邻居特征取平均,简单高效 节点度比较均匀的场景
LSTM 聚合 对邻居序列建模,表达能力更强 邻居有顺序关系的场景
Pooling 聚合 对每个邻居做 MLP,再取 max/mean 需要提取最显著特征的场景

我在金融风控里用得最多的是 Mean 聚合。为什么?因为简单、稳定、不容易过拟合。LSTM 虽然理论上更强,但邻居的顺序在金融图里其实没什么意义——难道说张三的邻居按 ID 排序就有信息量?不存在的。

聚合的数学表达是这样的:

h_v^(k) = σ( W · MEAN( { h_v^(k-1) } ∪ { h_u^(k-1), ∀u ∈ N(v) } ) )

说白了,就是把目标节点自己的特征,和采样到的邻居特征,一起取平均,再过一个线性层加激活函数。嗯,就这么简单。

4.3 归纳式学习:这才是 GraphSAGE 的精髓

GCN 学的是每个节点的 embedding,GraphSAGE 学的是聚合函数。这个区别太关键了。

举个例子。假设你训练好了 GraphSAGE 模型,用来做反欺诈。第二天来了个新用户,他的交易记录、设备信息、IP 地址都有。在 GCN 里,你得把新用户加到图上,重新跑一遍前向传播,甚至可能得重新训练。但在 GraphSAGE 里,你只需要:

  1. 找到新用户的 K 个邻居
  2. 把邻居特征喂给聚合函数
  3. 输出新用户的 embedding

整个过程不需要重新训练,这就是归纳式学习的威力。

关键区别:直推式学习(GCN)—— 训练时所有节点可见,新节点需要重训。归纳式学习(GraphSAGE)—— 训练时只学聚合函数,新节点直接推理。

我记得有一次线上部署,模型已经跑了三个月,突然要接入一个新的数据源。用 GraphSAGE 的话,我只需要把新数据源的特征映射到已有的特征空间,然后走一遍聚合流程就行。整个上线过程不到一小时。要是用 GCN,光重训就得花半天。

4.4 大规模图上的应用:Mini-Batch 训练

GraphSAGE 能上大规模图,核心原因就是它支持 Mini-Batch 训练。GCN 是全图训练,一次要把整张图加载到显存里。GraphSAGE 每次只处理一个 Batch 的节点和它们的采样邻居。

训练流程是这样的:

  1. 从图中随机采样一个 Batch 的目标节点
  2. 对每个目标节点,采样 K 层邻居
  3. 构建子图,只包含这些节点和边
  4. 在这个子图上做前向传播和反向传播

这样做的好处很明显:

  • 显存占用可控,只跟 Batch Size 和采样数有关
  • 可以并行训练,每个 Batch 独立计算
  • 支持流式数据,新数据来了直接处理

注意:Batch Size 不是越大越好。我试过把 Batch Size 从 256 提到 1024,训练速度没快多少,显存倒是翻了三倍。后来发现 512 是个不错的平衡点。具体多少合适,得看你的图密度和显存大小。

4.5 金融风控实战:反欺诈场景

最后分享一个我在反欺诈项目里的实际配置。这个场景是检测团伙欺诈,图里有用户节点、设备节点、IP 节点,边表示关联关系。

模型配置:

# GraphSAGE 参数配置
num_layers = 2          # 两层聚合
sample_sizes = [25, 10] # 第一层采25个,第二层采10个
hidden_dim = 128        # 隐藏层维度
aggregator = 'mean'     # 均值聚合
batch_size = 512        # 每批处理512个节点
learning_rate = 0.001   # 学习率
dropout = 0.3           # 防止过拟合

效果怎么样?相比之前的 GCN 方案:

  • 训练时间从 6 小时降到 40 分钟
  • 新用户上线延迟从 1 天降到 实时
  • AUC 从 0.89 提升到 0.92

说实话,提升最大的不是 AUC,而是工程上的可落地性。以前每次模型更新都要协调多个团队,现在一个人就能搞定。这才是 GraphSAGE 在工业界真正受欢迎的原因。

我的建议:如果你刚开始用 GraphSAGE,先从 Mean 聚合 + 两层采样开始。这个配置最稳,也最容易调参。等跑通了,再尝试 Pooling 或者 LSTM。别一上来就整花活,容易翻车。

GraphSAGE 核心流程 输入:目标节点 第1层:采样25个邻居 第2层:采样10个邻居 Mean 聚合邻居特征 Mean 聚合邻居特征 输出:节点 Embedding 可用于下游任务 · 节点分类 · 链接预测 · 异常检测 关键特性 归纳式学习:学聚合函数,不学节点 embedding Mini-Batch 训练:每次只处理采样子图 支持新节点:无需重训,直接推理

好了,GraphSAGE 的核心内容就这些。采样控制计算量,聚合提取邻居信息,归纳式学习让模型能处理新节点,Mini-Batch 让大规模训练成为可能。这四个点串起来,就是 GraphSAGE 能在工业界大规模落地的原因。

专注资料整理