一、图神经网络概述
我们为什么要聊图神经网络?先讲个小故事。几年前我接手一个风控项目,特征都是用户的年龄、收入、消费金额这类“平铺”数据。用xgboost跑得很顺,但同事说:“你能把用户之间的转账关系加进去吗?”我把关系做成简单的统计量——比如“转账给多少人”,效果提升有限。后来我试着把所有用户和转账关系看作一张图,用图神经网络去学每个节点的向量,结果AUC直接跳了3个点。
嗯,这就是图神经网络的威力。它不只看“你是什么样的人”,还看“你跟谁有关系”。说白了,GNN就是让模型学会在图上做信息传递。
1.1 为什么需要图神经网络?
传统的神经网络处理的数据,假设样本之间是独立的。图像像素有固定网格,文本有序列结构。但现实世界很多数据天然是图结构——社交网络、分子结构、知识图谱、金融交易网络。你想想看,如果把用户之间的转账关系、好友关系硬塞到全连接层里,要么维度爆炸,要么丢失拓扑信息。
- 非欧几里得数据:图没有规则的空间结构,不能直接卷积。
- 节点关联性:每个节点的特征受邻居影响,传统模型无法捕捉这种依赖。
- 图规模大:动辄百万、亿级节点,需要高效的采样和聚合策略。
核心观点:GNN的诞生就是为了在图上做“邻居信息聚合”。你可以把它想象成每个节点不断跟自己的邻居“聊天”,交换特征,最后形成一个富含上下文信息的节点表示。
我自己最早接触图数据时,犯过一个错。我把邻居的所有特征直接拼接到原节点特征上,维度动辄几百甚至上千。后来我发现,这样既容易过拟合,又没法泛化到新节点。GraphSAGE提出的“采样+聚合”策略,恰恰解决了这个问题——我后面会详细讲。
1.2 图神经网络的核心思想
GNN的套路其实很清晰:每个节点都从它的邻居那里“收消息”,然后更新自己的特征。这个过程重复几轮,每个节点就获得了越来越远的“视野”。
举个简单的例子:假设每个用户有一个初始特征x(比如年龄、性别)。第一轮,用户A从邻居B、C那里收到他们的特征,通过某个函数(比如平均)混合成新的特征。第二轮,A又能从B的邻居D、E那里间接获得信息。如此反复,A的向量就包含了整个社区的信息。
用公式表达(别怕,我尽量口语化):
h_v^(k+1) = σ( W · Aggregate( { h_u^(k), ∀u ∈ N(v) } ) )
其中:
h_v^(k) 表示节点v在第k层的特征
N(v) 是v的邻居集合
Aggregate 是聚合函数(比如mean、max)
W 是可学习的权重矩阵
σ 是激活函数
我个人习惯把聚合器看成“压缩邻居信息到固定大小的工具”。GraphSAGE最典型的三种聚合器:Mean、LSTM、Pooling,各有各的适用场景。
小提示:聚合函数的选择直接决定模型能不能学到拓扑结构。Mean倾向于等权,可能丢失重要邻居的信息。如果你处理的是异构图(不同节点类型不同),我建议试试GAT的注意力机制,或者GraphSAGE的Pooling。
下面这个图展示了核心的聚合过程。看一遍,你就理解GNN是怎么“聊天”的了。
图里深蓝色的是目标节点v,绿色的是邻居u1、u2、u3。箭头表示消息从邻居流向v。经过聚合函数(橙色框),v更新为红色节点v'。
注意:图中只展示了单层聚合。实际多层GNN中,每一层的输入都是上一层的输出。层数越多,感受野越大。但层数太多容易过平滑——所有节点的向量变得几乎一样。我遇到过堆到4层后模型效果反而下降的情况,所以层数一般2~3层就够了。
1.3 常见GNN变体
GNN家族有很多成员,我帮你整理一个表格,方便对比:
| 模型 | 聚合方式 | 适用场景 | 特点 |
|---|---|---|---|
| GCN | 归一化后的邻居特征平均 | 节点分类、链路预测 | 简单高效,对度差异敏感 |
| GAT | 注意力加权平均 | 异构、动态图 | 可以学习不同邻居权重 |
| GraphSAGE | 采样+Mean/LSTM/Pool | 大规模图、归纳学习 | 支持新节点快速推理 |
| GIN | MLP+求和 | 图级分类 | 理论上最强的图表达能力 |
看到没?GraphSAGE排第三行。它最大的优势是能处理完全没见过的节点——因为它不是针对某个固定图结构学习的,而是学了一个“如何从邻居那里聚合信息”的函数。这个特性在工业界特别有用,比如每天新增的用户、新商品,你不需要重训模型就可以拿到它们的向量。
我个人的经验:当你面临上亿节点、而且图结构频繁变化时,优先选GraphSAGE。GCN需要全图拉普拉斯矩阵,内存扛不住。GAT注意力计算复杂度太高。GraphSAGE的采样策略让你可以用mini-batch训练,吃内存少,效果还不差。
1.4 应用场景与挑战
图神经网络已经在很多领域落地了。我挑几个最有代表性的:
- 推荐系统:把用户和商品看作节点,交互行为作为边。PinSage(借鉴GraphSAGE思想)用在Pinterest上,提效显著。
- 金融风控:交易网络中的异常检测、团伙欺诈识别。我曾经用GraphSAGE做特征衍生,把节点向量作为新特征加入LR模型,召回率提高了15%。
- 分子性质预测:原子是节点,化学键是边。GNN能预测分子是否有毒性或是否易溶解。
- 知识图谱推理:补全实体之间的关系。
当然,GNN也不是万能的。下面几个坑我在实际项目里踩过:
避坑指南:
- 千万不要把小图直接套用复杂GNN。如果只有几百个节点,简单的图统计特征往往比GNN还好。
- 异构边(不同类型的关系)要小心处理。我试过把所有边权都设成1,结果模型完全学不到关系类型的信息。可以用关系感知的GNN(如R-GCN)或者特征上做区分。
- 图很大时,邻居采样策略要调。采样太多内存炸,采样太少信息不够。GraphSAGE默认采样25个邻居,但你可以根据每个节点的度动态调整。
好了,这章就到这里。你心里应该对“为什么需要GNN”和“GNN大概怎么工作”有了个轮廓。下一章我们开始动手——我会带你从零搭建一个GraphSAGE的基线模型,并解决一个真实的分类问题。
警告:不要跳过基础直接看章节后面的代码。你如果没理解“聚合”这件事,调参的时候会一脸懵的。我当年就是跳着看,结果写了个“假GNN”——每个节点只用了自己的特征,根本没聚合邻居,跑出来还以为是模型结构好。