图机器学习——2.1 节点嵌入:基于随机游走

article/2025/8/23 16:17:00

嵌入(embedding)方法是目前文本分析,知识图谱相关中非常常见的一种算法。其为表示学习的一类方法,可以自动地从数据中学习“有用”的特征,并可以直接用于后续的具体任务。后面学习的相关嵌入学习均为表示学习中的内容。

节点嵌入

关于图的一些信息如何能够转化为计算机可以识别的语言呢?通常的方法也是进行嵌入(embedding)。在此之前,我们已经学习了双曲嵌入:

  • 双曲嵌入深度学习
  • 双曲嵌入论文与代码实现——1. 数据集介绍
  • 双曲嵌入论文与代码实现——2. 方法与代码

其将图结构嵌入到双曲空间中而后根据双曲距离进行embedding的训练。这种做法其实是一种比较新的方法,而在此之前的那些传统的节点嵌入方法都没有进行学习。因此,基于双曲空间的节点嵌入方法,本系列博客不再进行具体介绍。


总体而言,节点的嵌入通常采取编码-解码结构进行训练。编码示意图如下:

总体的编解码核心思路如下:

  • 编码器ENC定义了一个从图中的节点 u , v u, v u,v到一个空间中的嵌入 z u , z v \mathbf{z}_{u}, \mathbf{z}_{v} zu,zv的映射;

ENC ( v ) = z v \text{ENC}(v) = \mathbf{z}_{v} ENC(v)=zv

  • 定义一个节点相似度函数(即原始网络中的相似度度量, similarity);
  • 解码器DEC定义一个从嵌入到相似度评分的映射;
  • 通过编码器优化参数,使得下式左右两边尽可能接近:
    similarity ⁡ ( u , v ) ≈ z v T z u \operatorname{similarity}(u, v) \approx \mathbf{z}_{v}^{\mathrm{T}} \mathbf{z}_{u} similarity(u,v)zvTzu

左式表示原始网络中节点 u , v u, v u,v的相似度;右式表示解码后的相似度评分。


基于随机游走的方法

1. DeepWalk

DeepWalk方法受到 word2vec 的启发,首先选择某一特定点为起始点,做随机游走得到点的序列,然后将这个得到的序列视为句子,用 word2vec 来学习,得到该点的表示向量。DeepWalk通过随机游走去可以获图中点的局部上下文信息,因此学到的表示向量反映的是该点在图中的局部结构,两个点在图中共有的邻近点(或者高阶邻近点)越多,则对应的两个向量之间的距离就越短。

图上的随机游走:给定一个图和一个起点,我们随机选择它的一个邻居,并移动到这个邻居;接着我们随机选择这一点的一个邻居,然后继续移动到它,重复这个操作。以这种方式访问的(随机)节点序列是图上的一个随机游走。

我们的目标是学习到一个映射 f : u → R d : f: u \rightarrow \mathbb{R}^{d}: f:uRd: f ( u ) = z u f(u)=\mathbf{z}_{u} f(u)=zu

Log-likelihood 定义如下:
max ⁡ f ∑ u ∈ V log ⁡ P ( N R ( u ) ∣ z u ) \max _{f} \sum_{u \in V} \log \mathrm{P}\left(N_{\mathrm{R}}(u) \mid \mathbf{z}_{u}\right) fmaxuVlogP(NR(u)zu)

  • N R ( u ) N_{R}(u) NR(u) 是从节点 u u u 出发,通过游走策略 R R R 所能到达的节点。给定节点 u u u,我们想要学习的特征表示是节点对随机游走邻居 N R ( u ) N_{R}(u) NR(u)的预测。直觉上,我们的优化目的是要使得从 u u u出发,尽可能使预测到邻居的概率更大,然后遍历所有的节点对总体进行优化。

下面为具体的算法过程:

  • 从图的每个节点 𝑢 𝑢 u开始,使用一些随机游走策略 R R R进行短的固定长度随机游走;
  • 对于每个节点 u u u 计算 N R ( u ) N_{R}(u) NR(u),即从 u u u开始游走路过的节点集合;
  • 给定节点 u u u,预测其邻居结点 N R ( u ) N_{\mathrm{R}}(u) NR(u),通过最大化似然函数(下式)最优化嵌入:

max ⁡ f ∑ u ∈ V log ⁡ P ( N R ( u ) ∣ z u ) \max _{f} \sum_{u \in V} \log P\left(N_{\mathrm{R}}(u) \mid \mathbf{z}_{u}\right) fmaxuVlogP(NR(u)zu)

上述的式子其实等价于下面的损失函数:

L = ∑ u ∈ V ∑ v ∈ N R ( u ) − log ⁡ ( P ( v ∣ z u ) ) \mathcal{L}=\sum_{u \in V} \sum_{v \in N_{R}(u)}-\log \left(P\left(v \mid \mathbf{z}_{u}\right)\right) L=uVvNR(u)log(P(vzu))

  • 我们用softmax函数来参数化 P ( v ∣ z u ) P\left(v \mid \mathbf{z}_{u}\right) P(vzu)

P ( v ∣ z u ) = exp ⁡ ( z u T z v ) ∑ n ∈ V exp ⁡ ( z u T z n ) P\left(v \mid \mathbf{z}_{u}\right)=\frac{\exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{v}\right)}{\sum_{n \in V} \exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{n}\right)} P(vzu)=nVexp(zuTzn)exp(zuTzv)

因此实际的损失函数为:
L = ∑ u ∈ V ∑ v ∈ N R ( u ) − log ⁡ ( exp ⁡ ( z u T z v ) ∑ n ∈ V exp ⁡ ( z u T z n ) ) \mathcal{L}=\sum_{u \in V} \sum_{v \in N_{R}(u)} -\log \left(\frac{\exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{v}\right)}{\sum_{n \in V} \exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{n}\right)}\right) L=uVvNR(u)log(nVexp(zuTzn)exp(zuTzv))

但注意到上式的分母 ∑ n ∈ V exp ⁡ ( z u T z n ) \sum_{n \in V} \exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{n}\right) nVexp(zuTzn)需要遍历网络的所有节点,计算量非常大。为了减少算法复杂度,可以使用负采样策略(Negative sampling,REF: https://arxiv.org/pdf/1402.3722.pdf)。

log ⁡ ( exp ⁡ ( z u T z v ) ∑ n ∈ V exp ⁡ ( z u T z n ) ) ≈ log ⁡ ( σ ( z u T z v ) ) − ∑ i = 1 k log ⁡ ( σ ( z u T z n i ) ) , n i ∼ P V \begin{aligned} &\log \left(\frac{\exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{v}\right)}{\sum_{n \in V} \exp \left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{n}\right)}\right)\\ &\approx \log \left(\sigma\left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{v}\right)\right)-\sum_{i=1}^{k} \log \left(\sigma\left(\mathbf{z}_{u}^{\mathrm{T}} \mathbf{z}_{n_{i}}\right)\right), n_{i} \sim P_{V} \end{aligned} log(nVexp(zuTzn)exp(zuTzv))log(σ(zuTzv))i=1klog(σ(zuTzni)),niPV

其中, P v P_v Pv为节点随机分布, σ ( t ) = 1 1 + e − t \sigma(t)=\frac{1}{1+e^{-t}} σ(t)=1+et1

这样只要随机选取 k k k个“负样本”,即可快速近似到原式,在实际的操作中,通常选自5-20之间的数。

最终优化时用随机梯度下降的方法进行优化即可。

至此,整个基于随机游走的嵌入方法已经基本阐述完了。但有一个关键问题是:我们应该使用什么策略来进行随机游走?

通常最简单的做法是直接固定游走长度,每个邻接节点都是等概率进行游走。但这样的游走其实并不高效,基于这个原因,node2vec方法被提出。

2. node2vec

与DeepWalk相似,node2vec通过最大化随机游走得到的序列中的节点出现的概率来保持节点之间的高阶邻近性。与DeepWalk的最大区别在于,node2vec采用有偏随机游走,在广度优先(bfs)和深度优先(dfs)图搜索之间进行权衡,从而产生比DeepWalk更高质量和更多信息量的嵌入。

对于节点 u u u,node2vec发展了一个有偏的二阶随机游走策略 R R R 来生成网络的领域 N R ( u ) N_{R}(u) NR(u)。核心思想为:使用一个灵活、有偏差的随机游走,其可以在网络的局部和全局视角之间进行权衡。

为此,我们定义节点 u u u的两种邻居 N R ( u ) N_R(u) NR(u)。如上图所示, N B F S ( u ) = { s 1 , s 2 , s 3 } N_{B F S}(u)=\left\{s_{1}, s_{2}, s_{3}\right\} NBFS(u)={s1,s2,s3} 为局部微观视角下的游走; N D F S ( u ) = { s 4 , s 5 , s 6 } N_{D F S}(u)=\left\{s_{4}, s_{5}, s_{6}\right\} NDFS(u)={s4,s5,s6}为全局宏观视角下的游走。

这个非常有意思,这种游走策略其实是考虑了节点之间的层级特点(可以与双曲空间的嵌入相结合),考虑到了二阶性质。具体算法思想如下:

  • 设置两个参数:返回参数 p p p,定义随机游走返回到前一个节点的概率;参数 q q q为探索参数,用于控制较大邻域的发现。
  • 算法需要记忆上一步走过的节点。

假设我们上一步从节点 S 1 S_1 S1走到了绿节点 W W W,此时在绿节点上有四种走法:

  1. 返回到红色节点 S 1 S_1 S1的概率是 1 / p 1/p 1/p;
  2. 返回到与前一个红节点没有连接的节点 S 3 , S 4 S_3, S_4 S3,S4的概率是 1 / q 1/q 1/q;
  3. 到红节点 S 1 S_1 S1相邻节点 S 2 S_2 S2的概率是 1 1 1

注意:这里的概率是未归一化的,归一化之后才是真实的概率。因此,我们可以根据距离上一步节点 S 1 S_1 S1的距离,来定义三种不同的概率:

局部游走的情况用 p p p进行控制,其越小,越可能进行局部的随机游走;全局游走用 q q q控制,其越小越可能进行全局的随机游走。最后在实际的应用中固定随机游走的步长 l l l,而后剩下的优化过程和损失函数的定义都和前文一样了。

后续还有一系列文章是基于有偏随机游走进行的,不再进行详细的介绍。

参考

  • CS224W: Machine Learning with Graphs
  • 图表示学习Graph Embedding综述

http://chatgpt.dhexx.cn/article/nhV5jLDF.shtml

相关文章

Python模拟随机游走

随机游走模型由首先由爱因斯坦在1926年以数学方式描述。由于自然界中的许多实体会以不可预知的方式移动,因此随机游走模型用来描述这种不稳定的移动。在这种移动模型中,移动节点随机选择一个方向和速度来从当前位置移动到新的位置。下面展示一维和多维情…

Python基于随机游走模型的PageRank算法及应用

资源下载地址:https://download.csdn.net/download/sheziqiong/86812933 资源下载地址:https://download.csdn.net/download/sheziqiong/86812933 基于随机游走模型的 PageRank 算法及应用 一、课题背景介绍 1.1 随机游走模型 随机游走也称随机漫步&…

图——随机游走算法

文章目录 推荐基本概念PageRankPersonalRankTextRankSimRank 推荐基本概念 其中用户user[A,B,C],物品item[a,b,c,d],用户和物品有以下的关系 上述便是一个典型的二分图,我们用G(V,E)来表示,其中V为用户user和物品item组成的顶点集即[A,B,C,…

python二维随机游走_Python模拟随机游走图形效果示例

本文实例讲述了Python模拟随机游走图形效果。分享给大家供大家参考,具体如下: 在python中,可以利用数组操作来模拟随机游走。 下面是一个单一的200步随机游走的例子,从0开始,步长为1和-1,且以相等的概率出现。纯Python方式实现,使用了内建的 random 模块: # 随机游走 i…

随机游走 推荐系统论文阅读

emmmm本篇博客主要写了,自己阅读的一些论文,做了一些笔记,主要是记录。 基于深度随机游走的协同过滤推荐算法_刘靖凯 推荐算法:召回和排序 召回步骤常用的算法有协同过滤算法、隐语义算法 常用的协同过滤算法有基于用户的协同过…

理解随机游走

随机游走 基本思想 从一个或一系列顶点开始遍历一张图。在任意一个顶点,遍历者将以概率1-a游走到这个顶点的邻居顶点,以概率a随机跳跃到图中的任何一个顶点,称a为跳转发生概率,每次游走后得出一个概率分布,该概率分布…

随机游走问题

随机游走指的是在一个点以等可能的概率走向下一个点。 问题1: Link:https://www.luogu.com.cn/problem/P3232 题意:这道题其实相当于求每条边经过的期望次数。 思路:每条边经过的期望次数不好算,我们想到点经过的期望次数。于…

随机游走 Random Walk

随机游走(英语:Random Walk,缩写为 RW),是一种数学统计模型,它是一连串的轨迹所组成,其中每一次都是随机的。[1][2]它能用来表示不规则的变动形式,如同一个人酒后乱步,所…

时间序列:时间序列模型---随机游走过程(The Random Walk Process)

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 随机游走过程是一种特殊的ARMA序列。从分子运动到股价波动等现象都被建模为随机游走。 随机游走过程是AR(1)序列,而且,时间序列在时刻的值为: 随机游走过程本质上是到当前时间…

随机游走(Random Walk)算法

随机游走 英文:random walk 定义:随机游走,概念接近于布朗运动,是布朗运动的理想数学状态。 核心概念:任何无规则行走者所带的守恒量都各自对应着一个扩散运输定律。 随机游走算法的基本思想是: 从一个或一系列顶点…

ArrayList分页Lists.partition遇到的坑

一、问题的发现 最近在用分布式任务powerjob的时候,发现了一个关于数组分页之后的序列化问题。事情是这样的,在我执行MapReduce模式的时候,发现了在生成子任务时报了com.esotericsoftware.kryo.kryo5.KryoException: Class cannot be created…

partition list java_Java之Lists.Partition项目中的使用

开心一笑 【媳妇儿问我:“孩子都快出生了,你名字想好了没呀?” 我说:“都想好了,要是生个儿子名字就叫“好帅” 媳妇儿问:“为什么呀?” 我说:“别人看到我就会说,好帅的爸爸。】 提出问题 Java之Lists.Partition在项目中的如何被使用??? 学习地址 解决问题 前言 具…

Lists.partition的使用和里面的坑

作用 partition(List list, int size): 将list集合按指定长度进行切分&#xff0c;返回新的List<List<??>>集合。 案例 引入pom文件 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><vers…

Lists.partition集合分组使用以及注意事项

1.介绍 Lists.partition是com.google.common.collect包下的一个方法。 作用是将目标集合按照传入的size分组。 2.使用场景 一般用于固定大小的集合处理&#xff0c;比如&#xff1a;我有两百个商品类型&#xff0c;要求前一百个一种处理方式&#xff0c;后一百个一种处理方…

Guava Lists.transform踩坑小记

1.问题提出 1.前段时间在项目中用到Lists.transform返回的List&#xff0c;在对该list修改后发现修改并没有反映在结果里&#xff0c;研究源码后发现问题还挺大。 下面通过单步调试的结果来查看Guava Lists.transform使用过程中需要注意的地方。 a.对原有的list列表修改会影响L…

Google guava工具类中Lists、Maps、Sets简单使用

Google guava Guava是对Java API的补充&#xff0c;对Java开发中常用功能进行更优雅的实现&#xff0c;使得编码更加轻松&#xff0c;代码容易理解。Guava使用了多种设计模式&#xff0c;同时经过了很多测试&#xff0c;得到了越来越多开发团队的青睐。Java最新版本的API采纳了…

Java常用工具类 : StringUtils、CollectionUtils、ArrayUtils、Lists、Maps等

文章目录 StringUtils引入依赖判断函数 (isNotBlank系列)大小写函数 (转换)删除函数 (remove)字符替换函数 (replace)拆分合并函数 (split)截取函数 (substring)删除空白函数 (trim)判断是否相等函数 (equals)是否包含函数 (contains) CollectionUtils集合判断函数并集、交集、…

Lists的使用

List&#xff08;接口&#xff09;顺序时List最重要的特性&#xff1a;它可保证元素按照规定的顺序排列。List为Collection添加了大量方法&#xff0c;以便我们在List中部插入和删除元素&#xff08;只推荐对LinkedList这样做&#xff09;。List也会生成一个ListIterator&#…

Lists 方法汇总

一、Lists.partition(List<T> list, int size) 将 list 集合按指定长度进行切分&#xff0c;返回新的List<List<T>>集合。 import com.google.common.collect.Lists; import org.junit.Test; import java.util.List;public class ListDemo {Testpublic voi…

LU分解的实现

LU分解是将矩阵分解为一个下三角矩阵和一个上三角矩阵的乘积。矩阵可以不是NxN的矩阵 一个可逆矩阵可以进行LU分解当且仅当它的所有子式都非零。如果要求其中的L矩阵&#xff08;或U矩阵&#xff09;为单位三角矩阵&#xff0c;那么分解是唯一的。同理可知&#xff0c;矩阵的L…