在上一篇文章中介绍了DeepWalk,这是第一次将word2vec的思路引入到graph或network中。这篇文章继续介绍graph embedding之node2vec,附个链接http://snap.stanford.edu/node2vec/,其中有文章也有代码。
一、基本思路
graph embedding也是一种特征表示学习方式,借鉴了word2vec的思路。在graph中随机游走生成顶点序列,构成训练集,然后采用skip-gram算法,训练出低维稠密向量来表示顶点。之后再用学习出的向量解决下游问题,比如分类,或者连接预测问题等。可以看做是两阶段的学习任务,第一阶段先做无监督训练生成表示向量,第二阶段再做有监督学习,解决下游问题。
在graph中主要存在两种关系,用作者的原话叫homophily和structual equivalence。所谓homophily,即是在graph中紧密相连的邻域,例如图1中的,他们之间的关系就是homophily,邻域同理。具有这种关系的顶点之间,学习出来的向量应该接近或者相似。所谓structural equivalence,就是指在图中具有相似作用的顶点,他们之间未必相邻,甚至可能相隔较远,比如图1中的u和,都是所在邻域的中心顶点。满足这种关系的顶点之间,特征向量也应该接近或者相似。通常在现实世界的graph中,会同时存在这两种关系。
但是在不同的任务中需要关注的重点不同,可能有些任务需要关注网络的homophily,而有些任务比较关注网络的structual equivalence,可能还有些任务两者兼而有之。在第一阶段的表示向量学习过程中,如何学习出表示向量,会影响到下游任务的效果。在DeepWalk中,在采样时作者只是单纯地采用随机游走,无法灵活地捕捉这两种关系,无法在这两种关系中有所侧重。
实际上,对于这两种关系的偏好,可以通过不同的序列采样方式来实现。有两种极端的方式,一种是Breadth-First Sampling(BFS),广度优先搜索,如图1中红色箭头所示,从u出发做随机游走,但是每次都只采样顶点u的直接邻域,这样生成的序列通过无监督训练之后,特征向量表现出来的是structual equivalence特性。另外一种是Depth-First Sampling(DFS),深度优先搜索,如图1中蓝色箭头所示,从u出发越走越远,学习得到的特征向量反应的是图中的homophily关系。
该如何在两种随机游走中自由切换或者有所选择?在介绍之前,我们先来公式化表达graph的随机游走。假设从某顶点出发开始随机游走,第i-1步走到当前顶点v,要探索第i步的顶点x。下面的公式表示从顶点v到x的转移概率,E是graph中的边缘集合,(v, x)表示顶点v和x之间的边,可视作边缘的权重,Z是归一化常数,是权重之和。对于无权重的网络,。最简单的方式,就是按照这个转移概率进行随机游走,但是无法对寻路方式进行控制。
作者提出了二阶随机游走,通过修改转移概率的方式来实现控制。假设刚刚从顶点t走到v,并且停在v,现在要决定下一步去哪里,如图2所示。下面两个公式对转移概率做了修改,其中表示下一步顶点x和顶点t之间的最短距离。只有3种情况,如果又回到顶点t,那么;如果x和t直接相邻,那么;其他情况,如图2所示。参数p控制着重新返回顶点t的概率。如果,那么下一步较小概率重新返回t;如果,那么下一步会更倾向于回到顶点t。对于参数q,如果q>1,那么下一步倾向于回到t或者t的临近顶点,这接近于BFS的探索方式;如果q<1,那么下一步倾向于走到离t更远的顶点,接近于DFS寻路方式。因此,可以通过设置p和q来控制游走网络的方式。所谓的二阶随机游走,意思是说下一步去哪,不仅跟当前顶点的边的权重相关,还跟上一步顶点相关。在文中试验部分,作者对p和q的设置一般是2的指数,比如。
二、具体算法
接下来介绍一下node2vec的具体实现,整个过程主要包括三步,第一步是计算转移概率矩阵,第二步是做采样,生成训练样本序列,第三步是用梯度下降做优化,具体如图3所示。
图4中的Part1介绍了算法的流程。在第1行中,G=(V, E, W),其中V表示node集合,E表示edge集合,W表示edge的权重集合。l表示随机游走的长度,k表示训练样本的长度。这里有个技巧要介绍一下,每一次随机游走生成长度为l的序列,例如,然后从第1个顶点作为起始点,截断k长度的序列,假设k=3,那么;然后是第2个顶点,;接着是第3个顶点,,然后到此为止,因为再往后边走长度就不足k了。因此做一次长度为l的序列采样,可以生成l-k个长度为k的训练样本序列。最后,Return p和In-Out q就是上文中介绍的两个参数。
第2,3行是计算新的转移概率矩阵,并且对G做更新。第4行将游走序列集合walks初始化为空集合。第5行到第8行进行随机游走生成顶点序列,一共进行r轮,每一轮都对图中的所有顶点作为起始点来一次长度为的随机游走,并且将序列添加到集合walks中。
第9行是做梯度下降优化。这里作者不再采用DeepWalk中的Hierarchical Softmax,而是采用负采样的方式,同样可以加速训练。
Part2是对Part1中第7行的node2vecWalk函数的具体描述。第1步初始化序列walk,然后进行步随机游走。第3行获取当前顶点curr,第4行是获取当前顶点curr的直接相邻顶点集合,第5行是根据转移概率得到下一步的顶点s,并加入序列walk。
三、应用
对顶点的表示学习只是第一步,目的还是为了解决下游任务,下游任务一般有两类,第一类是对顶点的多标签分类,第一类是预测顶点之间是否存在连接。这里主要介绍一下第二类。对于graph中的任意两个顶点对,例如(u, v),假设学到特征向量为f(u)和f(v),f为顶点到特征向量的映射函数。通过一些算子,生成顶点对(u,v)的表示向量。不管顶点对之间存在连接,都要生成顶点对的表示向量用于后续使用。作者给出了一些算子作参考,如图4所示,在多个试验中,Hadamard表现最佳。
最后,相对于DeepWalk,node2vec更加灵活,而且作者也通过试验证明了nodevec效果确实优于DeepWalk。