【Graph Embedding】node2vec:算法原理,实现和应用
前面介绍过基于DFS邻域的DeepWalk和基于BFS邻域的LINE。
DeepWalk:算法原理,实现和应用
LINE:算法原理,实现和应用
node2vec是一种综合考虑DFS邻域和BFS邻域的graph embedding方法。简单来说,可以看作是eepwalk的一种扩展,可以看作是结合了DFS和BFS随机游走的deepwalk。
nodo2vec 算法原理
优化目标
设f(u)f(u)f(u)是将顶点uuu映射为embedding向量的映射函数,对于图中每个顶点uuu,定义NS(u)N_S(u)NS(u)为通过采样策略SSS采样出的顶点uuu的近邻顶点集合。
node2vec优化的目标是给定每个顶点条件下,令其近邻顶点出现的概率最大。
maxf∑u∈VlogPr(NS(U)∣f(u))max_f {\sum_{u\in V}\log{Pr(N_S(U)|f(u))}}maxf∑u∈VlogPr(NS(U)∣f(u))
为了将上述最优化问题可解,文章提出两个假设:
- 条件独立性假设
假设给定源顶点下,其近邻顶点出现的概率与近邻集合中其余顶点无关。
Pr(Ns(u)∣f(u))=∏ni∈Ns(u)Pr(ni∣f(u))Pr(N_s(u)|f(u))=\prod_{n_i\in N_s(u)} Pr(n_i|f(u))Pr(Ns(u)∣f(u))=∏ni∈Ns(u)Pr(ni∣f(u)) - 特征空间对称性假设
这里是说一个顶点作为源顶点和作为近邻顶点的时候共享同一套embedding向量。(对比LINE中的2阶相似度,一个顶点作为源点和近邻点的时候是拥有不同的embedding向量的)
在这个假设下,上述条件概率公式可表示为Pr(ni∣f(u))=expf(ni)⋅f(u)∑v∈Vexpf(v)⋅f(u)Pr(n_i|f(u))=\frac{\exp{f(n_i)\cdot f(u)}}{\sum_{v\in V}{\exp{f(v)\cdot f(u)}}}Pr(ni∣f(u))=∑v∈Vexpf(v)⋅f(u)expf(ni)⋅f(u)
根据以上两个假设条件,最终的目标函数表示为
maxf∑u∈V[−logZu+∑ni∈Ns(u)f(ni)⋅f(u)]max_f{\sum_{u\in V}[-\log{Z_u}+\sum_{n_i\in N_s(u)}{f(n_i)\cdot f(u)}]}maxf∑u∈V[−logZu+∑ni∈Ns(u)f(ni)⋅f(u)]
由于归一化因子Zu=∑ni∈Ns(u)exp(f(ni)⋅f(u))Z_u=\sum_{n_i\in N_s(u)}{\exp(f(n_i)\cdot f(u))}Zu=∑ni∈Ns(u)exp(f(ni)⋅f(u))的计算代价高,所以采用负采样技术优化。
采样策略
node2vec依然采用随机游走的方式获取顶点的近邻序列,不同的是node2vec采用的是一种有偏的随机游走。
给定当前顶点vvv,访问下一个顶点xxx的概率为
P(ci=x∣ci−1=v)={πvxZif (v,x)∈E0otherwiseP(c_i=x|c_{i-1}=v)=\left\{ \begin{aligned} \frac{\pi_ {vx}}{Z} & & \text{if }(v,x)\in E \\ 0 & & \text{otherwise} \\ \end{aligned} \right. P(ci=x∣ci−1=v)=⎩⎨⎧Zπvx0if(v,x)∈Eotherwise
πvx\pi_{vx}πvx是顶点vvv和顶点xxx之间的未归一化转移概率,ZZZ是归一化常数。
node2vec引入两个超参数ppp和qqq来控制随机游走的策略,假设当前随机游走经过边(t,v)(t,v)(t,v)到达顶点vvv
设πvx=αpq(t,x)⋅wvx\pi_{vx}=\alpha_{pq}(t,x)\cdot w_{vx}πvx=αpq(t,x)⋅wvx,wvxw_{vx}wvx是顶点vvv和xxx之间的边权,
αpq(t,x)={1p=if dtx=01=if dtx=11q=if dtx=2\alpha_{pq}(t,x)=\left\{ \begin{aligned} \frac{1}{p} & = & \text{if }d_{tx}=0\\ 1 & = & \text{if }d_{tx}=1\\ \frac{1}{q} & = & \text{if }d_{tx}=2\\ \end{aligned} \right. αpq(t,x)=⎩⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎧p11q1===ifdtx=0ifdtx=1ifdtx=2
dtxd_{tx}dtx为顶点ttt和顶点xxx之间的最短路径距离。
下面讨论超参数ppp和qqq对游走策略的影响
- Return parameter,p
参数ppp控制重复访问刚刚访问过的顶点的概率。
注意到ppp仅作用于dtx=0d_{tx}=0dtx=0的情况,而dtx=0d_{tx}=0dtx=0表示顶点xxx就是访问当前顶点vvv之前刚刚访问过的顶点。
那么若ppp较高,则访问刚刚访问过的顶点的概率会变低,反之变高。 - In-out papameter,q
qqq控制着游走是向外还是向内,若q>1,随机游走倾向于访问和ttt接近的顶点(偏向BFS)。若q<1q<1q<1,倾向于访问远离ttt的顶点(偏向DFS)。
下面的图描述的是当从t访问到v时,决定下一个访问顶点时每个顶点对应的α\alphaα。
学习算法
采样完顶点序列后,剩下的步骤就和deepwalk一样了,用word2vec去学习顶点的embedding向量。
值得注意的是node2vecWalk中不再是随机抽取邻接点,而是按概率抽取,node2vec采用了Alias算法进行顶点采样。
Alias Method:时间复杂度O(1)的离散采样方法
node2vec核心代码
node2vecWalk
通过上面的伪代码可以看到,node2vec和deepwalk非常类似,主要区别在于顶点序列的采样策略不同,所以这里我们主要关注node2vecWalk的实现。
由于采样时需要考虑前面2步访问过的顶点,所以当访问序列中只有1个顶点时,直接使用当前顶点和邻居顶点之间的边权作为采样依据。
当序列多余2个顶点时,使用文章提到的有偏采样。
def node2vec_walk(self, walk_length, start_node):G = self.G alias_nodes = self.alias_nodes alias_edges = self.alias_edgeswalk = [start_node]while len(walk) < walk_length: cur = walk[-1] cur_nbrs = list(G.neighbors(cur)) if len(cur_nbrs) > 0: if len(walk) == 1: walk.append(cur_nbrs[alias_sample(alias_nodes[cur][0], alias_nodes[cur][1])]) else: prev = walk[-2] edge = (prev, cur) next_node = cur_nbrs[alias_sample(alias_edges[edge][0],alias_edges[edge][1])] walk.append(next_node) else: breakreturn walk
构造采样表
preprocess_transition_probs
分别生成alias_nodes
和alias_edges
,alias_nodes
存储着在每个顶点时决定下一次访问其邻接点时需要的alias表(不考虑当前顶点之前访问的顶点)。alias_edges
存储着在前一个访问顶点为ttt,当前顶点为vvv时决定下一次访问哪个邻接点时需要的alias表。
get_alias_edge
方法返回的是在上一次访问顶点ttt,当前访问顶点为vvv时到下一个顶点xxx的未归一化转移概率πvx=αpq(t,x)⋅wvx\pi_{vx}=\alpha_{pq}(t,x)\cdot w_{vx}πvx=αpq(t,x)⋅wvx
def get_alias_edge(self, t, v):G = self.G p = self.p q = self.qunnormalized_probs = [] for x in G.neighbors(v): weight = G[v][x].get('weight', 1.0)# w_vxif x == t:# d_tx == 0unnormalized_probs.append(weight/p) elif G.has_edge(x, t):# d_tx == 1unnormalized_probs.append(weight) else:# d_tx == 2unnormalized_probs.append(weight/q) norm_const = sum(unnormalized_probs) normalized_probs = [float(u_prob)/norm_const for u_prob in unnormalized_probs]return create_alias_table(normalized_probs)def preprocess_transition_probs(self):G = self.Galias_nodes = {} for node in G.nodes(): unnormalized_probs = [G[node][nbr].get('weight', 1.0) for nbr in G.neighbors(node)] norm_const = sum(unnormalized_probs) normalized_probs = [float(u_prob)/norm_const for u_prob in unnormalized_probs] alias_nodes[node] = create_alias_table(normalized_probs)alias_edges = {}for edge in G.edges(): alias_edges[edge] = self.get_alias_edge(edge[0], edge[1])self.alias_nodes = alias_nodes self.alias_edges = alias_edgesreturn
node2vec应用
使用node2vec在wiki数据集上进行节点分类任务和可视化任务。 wiki数据集包含 2,405 个网页和17,981条网页之间的链接关系,以及每个网页的所属类别。 通过简单的超参搜索,这里使用p=0.25,q=4的设置。
本例中的训练,评测和可视化的完整代码在下面的git仓库中,
https://github.com/shenweichen/GraphEmbedding
G = nx.read_edgelist('../data/wiki/Wiki_edgelist.txt',create_using=nx.DiGraph(),nodetype=None,data=[('weight',int)])model = Node2Vec(G,walk_length=10,num_walks=80,p=0.25,q=4,workers=1)
model.train(window_size=5,iter=3)
embeddings = model.get_embeddings()evaluate_embeddings(embeddings)
plot_embeddings(embeddings)
分类任务
micro-F1: 0.6757
macro-F1: 0.5917
这个结果相比于DeepWalk和LINE是有提升的。
可视化
这个结果相比于DeepWalk和LINE可以看到不同类别的分布更加分散了。
参考资料
- Grover A, Leskovec J. node2vec: Scalable Feature Learning for Networks[C]// Acm Sigkdd International Conference on Knowledge Discovery & Data Mining. 2016.
图算法干货汇总
我把近年来主流的图表示学习方法的paper和对应的代码实现进行了汇总整理,扫码关注公众号【浅梦的学习笔记】,后台回复【图算法】即可打包下载。
欢迎加入星球群,一个由1300+小伙伴共建的交流平台,专注于前沿graph embedding算法技术与实践经验的分享学习。
【Graph Embedding】node2vec:算法原理,实现和应用相关推荐
- 论文|Node2vec算法原理、代码实战和在微信朋友圈的应用
1 概述 Node2vec是2016年斯坦福教授 Jure Leskovec.Aditya Grover提出的论文,论文的下载链接为:https://arxiv.org/pdf/1607.00653. ...
- 深入理解深度学习——图嵌入(Graph Embedding)
分类目录:<深入理解深度学习>总目录 前面的文章介绍了由Word Embedding延伸出的Item Embedding等,这些延伸都建立在它们有序列特性的基础上.其实,可延伸的领域还有很 ...
- 安全研究 # Neural Network-based Graph Embedding for Cross-Platform Binary Code Similarity Detection
论文分享<Neural Network-based Graph Embedding for Cross-Platform Binary Code Similarity Detection> ...
- 【Graph Embedding】:Billion-scale Commodity Embedding for E-commerce Recommendation in Alibaba
本文是阿里在kdd2018发表的关于使用graph embedding作为淘宝首页推荐召回策略的算法实现.现在利用图embedding来做召回算是业界最前沿的技术,下面我们来看看淘宝是如何来用户行为转 ...
- 【Graph Embedding】DeepWalk:算法原理,实现和应用
本文首先从整体介绍一下图表示学习,然后分别从原理,核心代码,应用三个部分介绍DeepWalk. 图表示学习 我们都知道在数据结构中,图是一种基础且常用的结构.现实世界中许多场景可以抽象为一种图结构,如 ...
- 【Graph Embedding】LINE:算法原理,实现和应用
之前介绍过DeepWalk(DeepWalk:算法原理,实现和应用),DeepWalk使用DFS随机游走在图中进行节点采样,使用word2vec在采样的序列学习图中节点的向量表示. LINE也是一种基 ...
- 一文直击Graph Embedding图表示学习的原理及应用
导读:我们都知道在数据结构中,图是一种基础且常用的结构.现实世界中许多场景可以抽象为一种图结构,如社交网络,交通网络,电商网站中用户与物品的关系等. 目前提到图算法一般指: 经典数据结构与算法层面的: ...
- 【图嵌入】Graph Embedding 方法之 LINE 原理解读
LINE 出自论LINE: Large-scale Information Network Embedding,与 DeepWalk 相比,比较明显的区别在于: DeepWalk 使用的深度优先搜索策 ...
- 【推荐算法】Graph Embedding——引入更多结构信息的图嵌入技术
在互联网背景下,数据对象之间更多的是以图结构的方式呈现的,典型的例子就是由用户行为序列产生的物品关系图,以及由属性和实体之间组成的知识图谱(knowledge graph).在面对图结构时候,传统的序 ...
- 知乎算法团队负责人孙付伟:Graph Embedding在知乎的应用实践
演讲嘉宾 | 孙付伟 出品 | AI科技大本营(ID:rgznai100) 9月6-7日,在由CSDN主办的2019中国AI开发者大会(AI ProCon 2019)的 机器学习专场中,知乎算法团队负 ...
最新文章
- (C++)CSP202006-2 稀疏向量 two pointers
- SQL 基礎語句-case
- 打开word文档提示文件未找到_word图片显示:如何打开多图文档不再卡慢
- 100多个基础常用JS函数和语法集合大全
- eclipse下解决明明有jar包,却找不到的问题
- Redis的启动和关闭(前台启动和后台启动)
- Kotlin 继续助力 Android 开发,并计划涉足更多领域
- DB Query Analyzer中的事务管理在DB2中的应用
- android 退出应用,如何停止服务,Android 完全退出当前应用程序的四种方法
- 自定义控件被忽略的渲染性能
- 「陶哲軒實分析」 習題 3.4.4
- vmware vcenter 4.1升级到5.0
- (最新版 易卷)自动阅卷系统|自动阅卷机|网上阅卷系统
- 锂镍钴价格齐飞,新能源汽车涨价潮何时休?
- 做了一个淘宝内部优惠券分享平台支持微信公众号以及网站
- 电感感应电压公式v(t)=L*di/dt的推导
- 为什么二分K-均值比K-均值的聚类效果更好?
- autojs查找图片相似轮廓
- 区块链之一 起源思想和本质
- 学习Excel VBA(一)——VBA理论初步