摘要
什么是embedding?
Embedding在数学上表示的是一个映射关系,F: X -> Y,也就是一个函数。该函数具有两个性质:injective和structure-preserving。Injective,即我们所说的单射函数,对于每个 Y 只有唯一的 X 对应,反之亦然;structure-preserving,结构保存,比如在X所属的空间上X1<X2,那么映射后在Y所属空间上Y1<Y2。
深度学习中,Embedding特指用一个低维度向量表示一个实体,可以是一个词(Word2Vec),可以是一个物品(Item2Vec),亦或者网络关系中的节点(Graph Embedding)。
Embedding的初始化状态可以理解为是一组随机数,随着算法的优化与不断迭代更新,当网络达到收敛状态的时候,网络中各个层的参数就相对固化,这样就得到了隐层权重表,此时就相当于得到了我们想要的embedding。在实际应用中,通常将神经网络倒数第二层的权重参数当作对应样本的embedding。
什么是Graph Embedding?
Graph Embedding用低维、稠密、实值的向量表示网络中的节点。目前,Graph Embedding已经是推荐系统、计算广告领域非常流行的做法,并且在实践后取得了非常不错的线上效果。
Graph Embedding技术将图中的节点以低维稠密向量的形式进行表达,要求在原始图中相似(不同的方法对相似的定义不同)的节点其在低维表达空间也接近。得到的表达向量可以用来进行下游任务,如节点分类,链接预测,可视化或重构原始图等。
Graph Embedding是把图结构转化成一个向量或者一组向量的变换,在这里,Embedding能够捕捉到图的拓扑结构、节点到节点的关系、其他关于图、子图和节点的相关信息等。
Graph Embedding算法的演进
DeepWalk(2014)Line(2015)Node2vec(2016)EGES(2018)
DeepWalk: Online Learning of Social Representations
- 论文地址:https://arxiv.org/pdf/1403.6652.pdf 【KDD 2014】
- Github地址:https://github.com/phanein/deepwalk
- deepwalk工具:http://www.perozzi.net/projects/deepwalk/
算法讲解:
1、Random Walk
假设以节点为根的随机游走为,那么生成随机变量,,...,将是一个随机选择的过程,这里,是从节点的邻居节点中随机选择的一个节点。
RandomWalk是一种可重复访问已访问节点的深度优先遍历算法。DeepWalk采用随机游走采样图的节点序列。给定当前访问起始节点,从其邻居中随机采样节点作为下一个访问节点,重复此过程,直到访问序列长度满足预设条件。这里的随机游走长度是一个明确规定的指定值。
2、Skip Gram
首先SkipGram是一个语言模型,这个语言模型能够最大化一个句子中出现在同一个窗口内的词的共现概率。SkipGram通过一个独立分布假设,计算如下的条件概率:
为了避免巨大的计算开销和加速训练时间,SkipGram同样应用了HierarchicalSoftmax来计算概率分布。
DeepWalk利用word2vec的思想将RandomWalk中拿到的随机游走的节点序列作为语料库,训练神经网络模型,进而学习每个节点的向量表示。
3、Deep Walk
DeepWalk算法核心过程包含两个步骤:第一步使用随机游走采样节点序列,直到采样序列的长度达到预设长度(通常是一个指定值),第二步使用SkipGram进行向量表达。论文中特别说明了两个case:(1)随机游走的长度是一个固定值,但并没有限制。(2)随机游走可以有相同的根,但这并没有什么用。
DeepWalk伪代码:
Algorithm_1的第3-9行是DeepWalk的核心代码,外层循环指明了每个节点需要的随机游走次数为,内层循环遍历了图中的每个节点,然后对每个节点进行一次深度为t的随机游走,然后使用该随机游走序列来SkipGram模型依据提出的目标函数来更新节点的向量表示。
line3:次随机游走
line5:迭代图中的每个顶点(进行一个随机游走和向量更新)
line6:顶点生成一个深度为t的随机游走
line7:SkipGram算法更新顶点的向量表示
Algorithm_2以滑动窗口的方式遍历随机游走的顶点序列,窗口的大小为,在每个窗口内,针对当前中心顶点,使用上文的目标函数更新当前顶点的表示,从而学得每个顶点的一般表示。
DeepWalk应用在推荐系统领域,首先需要获取的是用户的一个行为序列,基于这些用户的行为序列才能构建了item的相关图,图中的边是由用户行为产生的,比如用户先后浏览了item-A和item-B,那么就会产生了一条有向边由A指向B。其他的有向边也是一样的道理,假如有多个有A指向B的有向边,那么该条边的权重就会被加强。经过这样的方法就可以将所有用户的行为序列转换成item的一个相关图,也就是DeepWalk需要的全局的item相关图。在这个图中应用Algorithm_1就得到了每个item的向量表示。
需要注意的是,deepwalk中的游走是完全随机的,所以才有了后面其他的改进算法。
参考代码:
deepwalk_walk方法对应Algorithm_1中伪代码的第6行:
def deepwalk_walk(self, walk_length, start_node):
walk = [start_node]
while len(walk) < walk_length:
cur = walk[-1]
cur_nbrs = list(self.G.neighbors(cur))
if len(cur_nbrs) > 0:
walk.append(random.choice(cur_nbrs))
else:
break
return walk
_simulate_walks方法对应Algorithm_1伪代码中的第3行开始的外层循环:
def _simulate_walks(self, nodes, num_walks, walk_length,):
walks = []
for _ in range(num_walks):
random.shuffle(nodes)
for v in nodes:
walks.append(self.deepwalk_walk(alk_length=walk_length, start_node=v))
return walks