一、图神经网络基础:图论基本概念、图神经网络发展历程、GraphSAGE 原理介绍

我在反欺诈项目中第一次用到图特征时,说实话效果并不理想。后来复盘才发现,问题出在最基础的地方——对图结构本身的理解不够扎实。嗯,今天我们就从最基础的内容开始梳理。

1.1 图论基本概念:万物皆可连

图是什么?说白了就是一堆点和它们之间的连线。每个点叫节点,每条线叫边。就这么简单。

在反欺诈场景里,节点可以是用户、设备、手机号、银行卡。边就是它们之间的关联——比如同一个 IP 登录过两个账号,或者同一个手机号绑定了多张卡。你想想看,这些关系天然就是一张图。

核心概念速查
  • 节点(Vertex):图中的实体,反欺诈中通常代表用户、设备、地址等
  • 边(Edge):实体之间的关联,如交易、登录、绑定等行为
  • 邻接矩阵(Adjacency Matrix):用 0/1 矩阵表示节点之间是否相连
  • 度(Degree):一个节点有多少条边连着它

举个例子。假设我们有 3 个用户:A、B、C。A 和 B 是好友,B 和 C 是好友,A 和 C 不认识。那么邻接矩阵就是:

  A B C
A 0 1 0
B 1 0 1
C 0 1 0

矩阵里第 i 行第 j 列是 1,就说明节点 i 和节点 j 之间有边。我建议初学者先把邻接矩阵吃透,因为后面 GraphSAGE 的所有操作都离不开它。

图的类型其实也就几种,我列个表格帮你快速区分:

类型 说明 反欺诈场景举例
无向图 边没有方向,关系双向 两个设备共用同一 Wi-Fi
有向图 边有方向,A→B 不代表 B→A 用户 A 向用户 B 转账
加权图 边上带权重,表示关联强度 转账金额、频次作为权重
异质图 节点或边有多种类型 用户、设备、地址三种节点混存

我在项目里最常用的是异质图。反欺诈场景的实体类型天生多样,硬塞进同质图反而丢失信息。这点后面讲特征工程时还会提到,先留个印象。

小经验:刚开始接触图的时候,别急着上复杂算法。先用 NetworkX 画一张小图,看看你的数据连起来长什么样。我每接一个新项目都会先干这件事。

1.2 图神经网络发展历程:从谱域到空间域

传统的机器学习方法处理图数据时有个硬伤——它假设样本之间相互独立。但图数据恰恰相反,节点之间是互相关联的。你想想看,一个欺诈团伙里的成员,他们的行为特征肯定互相影响。把每个用户单独建模,等于把团伙拆散了再分析,效果能好才怪。

最早尝试解决这个问题的是图卷积网络(GCN)。GCN 的思路是把卷积操作从图像搬到图上。图像是规则的网格,图是不规则的结构,怎么搬?GCN 用谱域的方法,借助图的拉普拉斯矩阵做特征分解。概念很漂亮,但实际操作中有一个致命问题——它是转导式学习,训练时就必须看到整个图的结构。这意味着如果图里新来了一个节点,整个模型得重新训练。

我记得第一次用 GCN 做反欺诈时,线上不断有新用户注册,每来一批新用户就得全量重训一次模型。那段时间我几乎天天加班,后来实在扛不住了,才开始研究 GraphSAGE。

GraphSAGE 的出现为什么被称为突破?因为它把 GNN 从转导式推向了归纳式。归纳式学习意味着模型在训练时学到的是一套「如何聚合邻居信息」的规则,而不是记住每个节点的具体位置。新节点来了,只要找到它的邻居,套用学好的规则就能生成特征,完全不用重新训练。

我把几个关键模型的发展阶段整理了一下:

年代 模型 核心贡献 我的评价
2016 GCN 谱域卷积,开山之作 理论强,但只能做转导
2017 GraphSAGE 归纳式 + 邻居采样 实战首选,灵活可扩展
2018 GAT 注意力机制加权邻居 效果好但计算量偏大
2019 GIN 理论表达能力更强 适合小图,大图采样压力大

说实话,GAT 和 GIN 各有各的优势。但在工业级反欺诈场景里,GraphSAGE 的采样机制让它在大规模图上依然能跑得动,这也是我选择它作为本章核心的原因。

避坑指南:我曾经踩过一个坑——在图上做消息传递时,忽略了边特征的引入。反欺诈中很多关键信息藏在边上面,比如「转账金额异常」「登录地点跨省」。GraphSAGE 原生只聚合节点特征,如果你也有类似的边特征需求,记得在聚合时把边特征拼接进去,否则损失巨大。

1.3 GraphSAGE 原理:采样 — 聚合 — 更新

GraphSAGE 的全称是 Graph Sample and Aggregation,核心就三件事:采样、聚合、更新。下面我逐一拆解。

1.3.1 邻居采样

大图的邻居数量可能成千上万。全部聚合?计算量扛不住。GraphSAGE 的做法是:每层固定采样 S 个邻居。S 是超参数,通常在 2~50 之间。

  • 如果节点邻居数 > S,随机抽 S 个
  • 如果节点邻居数 < S,就重复采样补齐

这样做的好处很明显:训练时每个 batch 的计算量是可控的。我习惯把第一层采样数设大一点(比如 25),第二层设小一点(比如 10),这样既能捕获局部结构,又不会太吃内存。

1.3.2 聚合函数

采样完邻居之后,要把这些邻居的特征合并成一个向量。GraphSAGE 提供了三种聚合函数:

聚合方式 做法 适用场景
Mean 聚合 对邻居特征逐元素取平均 默认选项,简单稳定
LSTM 聚合 把邻居随机排序后输入 LSTM 邻居顺序隐含结构信息时
Pooling 聚合 邻居特征过 MLP 后取 max 或 mean 需提取最显著邻居特征时

Mean 聚合是最稳妥的选择,我 80% 的项目都用它。LSTM 聚合理论上更强,但需要邻居有顺序——图结构本身是无序的,所以得随机排序,这增加了不确定性。Pooling 聚合适合做「某个邻居特别关键」的场景,比如团伙中只跟头目有联系的成员。

1.3.3 节点更新

聚合完邻居特征之后,下一步是把聚合结果和节点自身的特征拼接,再经过一个全连接层加激活函数,得到更新后的节点特征。公式长这样:

h_v^{(k)} = σ( W_k · CONCAT( h_v^{(k-1)}, AGG( { h_u^{(k-1)}, u ∈ N(v) } ) ) )

其中:

  • h_v^{(k)} 是节点 v 在第 k 层的特征
  • N(v) 是节点 v 的采样邻居集合
  • AGG 是聚合函数(Mean / LSTM / Pooling)
  • CONCAT 把自身特征和邻居聚合特征拼起来
  • σ 是激活函数,一般用 ReLU

注意这里的 CONCAT。很多初学者会忽略这个拼接操作,以为直接把邻居特征聚合一下就行。但实际上,保留自身特征非常关键——它让模型在更新时能区分「我原本是谁」和「我的邻居是谁」。我在调参时试过去掉拼接,准确率直接掉了 7 个点,印象极其深刻。

下面是 GraphSAGE 完整流程的示意图,我把它画成了五步流水线,方便你对照理解:

GraphSAGE 核心流程:采样 → 聚合 → 更新 ← 上一章 📖 返回目录 下一章 →