图表示学习:从节点嵌入到图神经网络

如果你已经熟悉 GCN、GraphSAGE 这类图神经网络(GNN),可能好奇一个问题:在 GNN 流行之前,业界是如何把图里的节点变成模型能直接消费的向量的?这套方法被称为图表示学习(Graph Representation Learning),它既是 GNN 的前身,也是理解消息传递机制的重要背景。本文面向已了解 GNN 基础的工程师,系统梳理从随机游走嵌入到图神经网络的演进脉络,并给出一段可以直接跑通的 node2vec 代码。

图表示学习的目标

图表示学习的核心目标是:把图中的节点、子图,乃至整张图,编码成一个低维稠密的实向量(embedding),同时尽可能保留图里的结构信息与语义信息。

为什么这件事有价值?因为下游任务(节点分类、链路预测、图分类、推荐、异常检测等)往往依赖「特征」。在传统做法里,特征要人工设计,例如节点的度、聚类系数、各种中心性指标。图表示学习希望用数据驱动的方式自动学出特征,让向量之间的距离(如余弦相似度)能反映节点在图中的关系远近。

具体拆解,表示学习通常关心三类对象:

  • 节点级(Node-level):每个节点对应一个向量,是最常见、也最成熟的一类,DeepWalk、node2vec、LINE 都属于这一类。
  • 边级(Edge-level / Link-level):用两个节点向量预测它们之间是否存在边,或边上的权重、类型。
  • 图级(Graph-level):把整张图池化成一个向量,用于图分类或分子属性预测,这类任务更多由后来的 GNN 承担。

衡量一个嵌入好坏,并不看它重建邻接矩阵有多准,而是看它在下游任务上的「迁移」表现:学到的向量在少量标签下能否取得好分数。这也是这类方法常被称为「无监督 / 自监督特征学习」的原因。

经典浅层嵌入方法

所谓「浅层嵌入」,是指每个节点直接由一个查表(lookup)参数矩阵中的一行表示,模型参数规模与节点数成正比,且不引入层与层之间的非线性变换。下面三篇是奠基性的工作。

DeepWalk

DeepWalk(Perozzi 等,2014,arXiv:1403.6652,已核验)的核心思想非常朴素:把图当作一种「语料」。

做法是先在无向图上做大量截断随机游走(truncated random walk),得到许多节点序列;再把每个序列当成自然语言处理里的一句话,把节点当成词,用 Skip-gram 模型去学习,使得在游走序列中经常相邻出现的节点拥有相近的向量。它借用了 word2vec 的整套工程技巧(层次 Softmax、负采样),因此训练高效、可在线学习、易于并行。DeepWalk 的洞见在于:图中节点的共现统计和词在句子中的共现统计,服从相似的分布规律,所以语言模型可以无缝迁移到图上。

node2vec

node2vec(Grover 与 Leskovec,2016,arXiv:1607.00653,已核验)是对 DeepWalk 的关键改进。DeepWalk 的随机游走是「无偏」的,而 node2vec 设计了一种有偏随机游走(biased random walk):通过两个参数 p 和 q 控制游走是偏向「回头」(BFS 风格,强调局部结构)还是偏向「向外探索」(DFS 风格,强调全局角色)。

  • p 较小:游走更可能在刚访问过的节点附近打转,偏向同质性(homophily)。
  • q 较小:游走更愿意走向更远的节点,偏向结构等价性(structural equivalence)。

通过调节 p、q,node2vec 能够在一组嵌入里同时兼顾「社区内相似」与「结构角色相似」两种不同的邻域定义,在节点分类和链路预测上显著优于 DeepWalk 与之前的方法。它因此被视为连接「浅层嵌入」与「更灵活邻域建模」的桥梁。

LINE

LINE(Large-scale Information Network Embedding,Tang 等,2015,待核实)另辟蹊径,不依赖随机游走,而是直接优化一阶相似度(直接相连节点应相近)和二阶相似度(共享很多邻居的节点应相近)两个目标,并用边采样的方式解决稀疏边上的梯度问题。它在超大规模网络上也能高效训练,是工业界早期常用的基线方法之一。

浅层嵌入与图神经网络的关系

理解浅层嵌入后,再回头看 GCN、GraphSAGE,会觉得顺理成章。两者的本质差异在于「编码函数」的形式。

浅层嵌入方法(DeepWalk / node2vec / LINE)的编码是一个查表操作:

embedding(node) = 查表矩阵的第 i 行

每个节点的向量是独立存储的参数,彼此之间不共享计算。它的优点是训练简单、对任意图都适用;缺点是:

  • 参数随节点数线性增长,难以扩展到亿级节点;
  • 无法为训练时未出现的新节点(如新增用户)生成嵌入,必须重新训练或做推断式扩展;
  • 嵌入只利用了图结构,难以自然融合节点自带的特征属性(如用户的年龄、商品的类目)。

而 GNN 采用的是基于消息传递(message passing)的编码:每层的节点向量由其邻居上一层的向量聚合得到,参数在节点间共享。以 GraphSAGE 为例,它学习的是「聚合函数」而非「每个节点的向量」,因此:

  • 参数规模与图大小无关,可以泛化到未见过的节点(inductive);
  • 天然支持把节点属性特征作为输入,与结构一起编码;
  • 多层堆叠能捕捉多跳邻域,表达能力远强于浅层嵌入。

可以这样概括它们的关系:浅层嵌入是「为每个节点学一个静态向量」,GNN 是「学一个把节点及其邻域映射成向量的函数」。两者目标一致(都是图表示学习),但 GNN 把编码从「查表」升级成了「可泛化的函数」,这也是为什么在多数现代任务上 GNN 逐步取代了浅层嵌入方法。不过在超大图、冷启动、或只需快速基线的场景里,node2vec 这类方法依然实用。

代码实战:用 node2vec 训练并可视化节点嵌入

下面用 node2vec 库在一张小型社交图(空手道俱乐部图)上训练节点嵌入,再用 t-SNE 降到二维画出散点图,直观感受「结构相近的节点在向量空间里也相近」。运行前先安装依赖:

pip install node2vec networkx scikit-learn matplotlib
import networkx as nx
from node2vec import Node2Vec
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE

G = nx.karate_club_graph()  # 载入经典空手道俱乐部社交图,含 34 个节点
n2v = Node2Vec(G, dimensions=16, walk_length=30, num_walks=200, workers=1)  # 配置有偏随机游走
model = n2v.fit(window=10, min_count=1, batch_words=4)  # 用 Skip-gram 训练节点嵌入
embeddings = [model.wv[str(n)] for n in G.nodes()]  # 取出每个节点的 16 维向量
coords = TSNE(n_components=2, random_state=42).fit_transform(embeddings)  # 降维到 2 维以便可视化
plt.scatter(coords[:, 0], coords[:, 1])  # 绘制节点嵌入散点图
plt.title("Node2Vec embeddings (Karate Club)")
plt.show()

代码要点说明:

  • dimensions=16 决定嵌入维度,越大表达力越强但越容易过拟合。
  • walk_lengthnum_walks 控制随机游走的数量与长度,是训练成本的主要来源。
  • 想调节 p、q 来切换 BFS / DFS 偏向时,可在构造 Node2Vec 时传入 pq 参数。
  • 得到的 model.wv 是词向量接口,可以用 model.wv.most_similar(str(node)) 查看与某节点最相似的节点,用来验证嵌入是否学到了社区结构。

如果你更习惯「纯 sklearn 风格」的接口,也可以把图当作邻接关系,用 sklearn 的降维工具(如 SpectralEmbedding)直接得到节点坐标;但与 node2vec 相比,它缺少有偏游走带来的灵活邻域控制。

小结

图表示学习的目标,是把节点、子图或整图编码为保留结构与语义的低维向量。DeepWalk 用无偏随机游走加 Skip-gram 开风气之先,node2vec 用有偏游走(p、q 参数)让邻域定义更灵活,LINE 则通过一阶与二阶相似度直接优化大规模网络嵌入。它们都属于「浅层嵌入」:每个节点的向量是独立查表得到的,优点是简单、对超大图友好,缺点是无法泛化到新节点、也难以融合节点属性。图神经网络把编码从「查表」升级为「消息传递函数」,共享参数、支持归纳式学习与特征融合,成为更主流的方案。对工程师而言,理解这套演进,能帮你在新任务上正确选择基线方法与进阶模型。

参考与延伸阅读

  • Perozzi B., Al-Rfou R., Skiena S. DeepWalk: Online Learning of Social Representations. arXiv:1403.6652(已核验)
  • Grover A., Leskovec J. node2vec: Scalable Feature Learning for Networks. arXiv:1607.00653(已核验)
  • PyTorch Geometric 官方文档:https://pytorch-geometric.readthedocs.io/ (已核验,GNN 训练首选库)
  • Tang J. 等. LINE: Large-scale Information Network Embedding. arXiv:1503.03578(待核实)
  • Hamilton W., Ying R., Leskovec J. Inductive Representation Learning on Large Graphs (GraphSAGE). NeurIPS 2017(延伸阅读)
  • Kipf T., Welling M. Semi-Supervised Classification with Graph Convolutional Networks (GCN). ICLR 2017(延伸阅读)
本文累计阅读