深度解析Graph Embedding
Graph Embedding是推荐系统、计算广告领域最近非常流行的做法,是从word2vec等一路发展而来的Embedding技术的最新延伸;并且已经有很多大厂将Graph Embedding应用于实践后取得了非常不错的线上效果。
word2vec和由其衍生出的item2vec是embedding技术的基础性方法,但二者都是建立在“序列”样本(比如句子、推荐列表)的基础上的。而在互联网场景下,数据对象之间更多呈现的是图结构。典型的场景是由用户行为数据生成的物品全局关系图,以及加入更多属性的物品组成的知识图谱。
在面对图结构的时候,传统的序列embedding方法就显得力不从心了。在这样的背景下,对图结构中间的节点进行表达的graph embedding成为了新的研究方向,并逐渐在深度学习推荐系统领域流行起来。
DeepWalk
早期影响力较大的graph embedding方法是2014年提出的DeepWalk,它的主要思想是在由物品组成的图结构上进行随机游走,产生大量物品序列,然后将这些物品序列作为训练样本输入word2vec进行训练,最大化随机游走序列的似然概率,并使用最终随机梯度下降学习参数,得到物品的embedding。其目标函数为:
\[
\zeta(s)=\frac{1}{|s|} \sum_{i=1}^{|s|} \sum_{i-t \leq j \leq i+t,j \neq i}log Pr(v_j|v_i)
\]
其中:
\[
Pr(v_j|v_i) = \frac{exp(v'_j \cdot v_i)}{\sum_{v \in V} exp(v' \dot v_i)}
\]
实际上,也是word2vec的目标函数。
下图用图示的方法展现了DeepWalk的过程。
整个DeepWalk的算法流程可以分为四步:
- 图a展示了原始的用户行为序列
- 图b基于这些用户行为序列构建了物品相关图,可以看出,物品A,B之间的边产生的原因就是因为用户U1先后购买了物品A和物品B,所以产生了一条由A到B的有向边。如果后续产生了多条相同的有向边,则有向边的权重被加强。在将所有用户行为序列都转换成物品相关图中的边之后,全局的物品相关图就建立起来了。
- 图c采用随机游走的方式随机选择起始点,重新产生物品序列。
- 图d最终将这些物品序列输入word2vec模型(使用的是skip-gram模型),生成最终的物品Embedding向量。
在上述DeepWalk的算法流程中,核心是第三步,其中唯一需要形式化定义的是随机游走的跳转概率,也就是到达节点\(v_i\)后,下一步遍历\(v_i\)的临接点\(v_j\)的概率。如果物品的相关图是有向有权图,那么从节点\(v_i\)跳转到节点\(v_j\)的概率定义如下:
\[
p(v_j|v_i) =
\begin{cases}
\frac{M_{ij}}{\sum_{j \in N_+(v_i)}M_{ij}} , v_j \in N_+(v_i)\\
0, \ \ \ \ \ e_{ij} \notin \epsilon
\end{cases}
\]
其中$ N_+(v_i)\(是节点\)v_i\(所有的出边集合,\)M_{ij}\(是节点\)v_i\(到节点\)v_j\(边的权重。 如果物品相关图是无相无权重图,那么跳转概率将是上面公式的一个特例,即权重\)M_{ij}$将为常数\(1\),且$ N_+(v_i) \(应是节点\)v_i$所有“边”的集合,而不是所有“出边”的集合。
算法中有一个参数\(t\),是随机游走的步长,即需要限定随机游走的长度,不要过长,有几个好处,1)可以捕获网络中局部区域的结构信息;2)易于实现并行化,多个线程,进程,甚至服务器,可以同时随机游走网络的不同部分,实现分布式计算;3)能够适应网络的变化,网络局部发生变化时,可以只对局部网络进行学习和训练,而不需要对整个网络重新学习。
DeepWalk具有良好的可伸缩性,可以多台机器同时训练网络的不同部分。而且节点的出现频次符合指数分布,大部分低频节点都分布在长尾。多台机机器同时训练也不太会发生冲突,文中提出可以采用异步的随机梯度下降(ASGD)。
Node2vec
2016年,斯坦福大学在DeepWalk的基础上更进一步,通过调整随机游走权重的方法使graph embedding的结果在网络的 同质性(homophily) 和 结构性(structural equivalence) 中进行权衡权衡。
具体来讲,网络的“同质性”指的是距离相近节点的embedding应该尽量近似,如下图,节点\(u\)与其相连的节点\(s1\)、\(s2\)、\(s3\)、\(s4\)的embedding表达应该是接近的,这就是“同质性“的体现。
“结构性”指的是结构上相似的节点的embedding应该尽量接近,图4中节点u和节点s6都是各自局域网络的中心节点,结构上相似,其embedding的表达也应该近似,这是“结构性”的体现。
DFS反应了同质性,BFS反映了结构性。 对于宽度优先搜索(BFS)来说,其搜索往往是在当前节点(这里以节点\(u\)为例)的邻域进行的,相当于对\(u\)周围的网络结构进行了一次微观扫描(microscope view)。那么这个微观扫描当然更容易得到微观结构的观察,所以BFS就更容易使embedding结果更多反应网络的“结构性”。DFS相当于对网络结构进行了一次宏观扫描(macroscope view),只有在宏观的视角,才能发现大的集团、社区的聚集性,和集团内部节点的“同质性”。
node2vec优化的目标是给定每个顶点条件下,令其近邻顶点出现的概率最大。在条件独立性假设以及特征空间对称性假设下,最终的目标函数定义为:
\[
max_f \sum_{u \in V}[-log Z_u + \sum_{n_i \in N_s(u)} f(n_i) \cdot f(u)]
\]
由于归一化因子\(Z_u=\sum_{v \in V} exp(f(u) \cdot f(v))\)的计算代价高,所以采用负采样技术优化。
在node2vec算法中,主要通过节点间的跳转概率,控制BFS和DFS的倾向性。下图显示了node2vec算法从节点\(t\)跳转到节点\(v\)后,下一步从节点\(v\)跳转到周围各点的跳转概率。
形式化来讲,从节点\(v\)跳转到下一个节点\(x\)的概率为
\[
P(c_i=x|c_{i-1}=v)=
\begin{cases}
\frac{\pi_{vx}}{Z} \ \ \ \ \ if {v,x} \in E \\
0 \ \ \ \ \ \ \ \ otherwise
\end{cases}
\]
其中,\(Z\)是归一化常数。\(\pi_{vx}\)表示顶点\(v\)和顶点\(x\)之间的未归一化转移概率。
\[
\pi_{vx} = \alpha_{pq}(t,x) \cdot \omega_{vx}
\]
其中 \(\omega_{vx}\) 是边\(vx\)的权重, $ \alpha_{pq}(t,x)$ 的定义如下:
\[
\alpha_{pq}(t,x)=
\begin{cases}
\frac{1}{p} \ \ \ \ \ if d_{tx}=0 \\
1 \ \ \ \ \ if d_{tx}=1 \\
\frac{1}{q} \ \ \ \ if d_{tx}=2 \\
\end{cases}
\]
其中,\(d_{tx}\)指的是节点\(t\)到节点\(x\)的距离,参数\(p\)和\(q\)共同控制着随机游走的倾向性。参数\(p\)被称为返回参数(return parameter),\(p\)越小,随机游走回节点\(t\)的可能性越大,node2vec就更注重表达网络的同质性,参数\(q\)被称为进出参数(in-out parameter),\(q\)越小,则随机游走到远方节点的可能性越大,node2vec更注重表达网络的结构性,反之,当前节点更可能在附近节点游走。在文中试验部分,作者对p和q的设置一般是2的指数,比如\(\{1/8,1/4,1/2,1,2,4,8\}\)。
node2vec所体现的网络的同质性和结构性在推荐系统中也是可以被很直观的解释的。同质性相同的物品很可能是同品类、同属性、或者经常被一同购买的物品,而结构性相同的物品则是各品类的爆款、各品类的最佳凑单商品等拥有类似趋势或者结构性属性的物品。毫无疑问,二者在推荐系统中都是非常重要的特征表达。由于node2vec的这种灵活性,以及发掘不同特征的能力,甚至可以把不同node2vec生成的embedding融合共同输入后续深度学习网络,以保留物品的不同特征信息。
EGES
2018年阿里公布了其在淘宝应用的Embedding方法EGES(Enhanced Graph Embedding with Side Information),其基本思想是在DeepWalk生成的graph embedding基础上引入补充信息。
如果单纯使用用户行为生成的物品相关图,固然可以生成物品的embedding,但是如果遇到新加入的物品,或者没有过多互动信息的长尾物品,推荐系统将出现严重的冷启动问题。为了使“冷启动”的商品获得“合理”的初始Embedding,阿里团队通过引入了更多补充信息来丰富Embedding信息的来源,从而使没有历史行为记录的商品获得Embedding。
生成Graph embedding的第一步是生成物品关系图,通过用户行为序列可以生成物品相关图,利用相同属性、相同类别等信息,也可以通过这些相似性建立物品之间的边,从而生成基于内容的knowledge graph。而基于knowledge graph生成的物品向量可以被称为补充信息(side information)embedding向量,当然,根据补充信息类别的不同,可以有多个side information embedding向量。
那么如何融合一个物品的多个embedding向量,使之形成物品最后的embedding呢?最简单的方法是在深度神经网络中加入average pooling层将不同embedding平均起来,阿里在此基础上进行了加强,对每个embedding加上了权重,如图所示,对每类特征对应的Embedding向量,分别赋予了权重\(a_0,a_1…a_n\)。图中的Hidden Representation层就是对不同Embedding进行加权平均操作的层,得到加权平均后的Embedding向量后,再直接输入softmax层,这样通过梯度反向传播,就可以求的每个embedding的权重\(a_i(i=0…n)\)。
在实际的模型中,阿里采用了 \(e^{a_j}\) 而不是\(a_j\)作为相应embedding的权重,一是避免权重为\(0\),二是因为 \(e^{a_j}\) 在梯度下降过程中有良好的数学性质。
阿里的EGES并没有过于复杂的理论创新,但给出一个工程性的结合多种Embedding的方法,降低了某类Embedding缺失造成的冷启动问题,是实用性极强的Embedding方法。
时至今日,Graph Embedding仍然是工程和学术领域研究和实践的热点,除了本节介绍的DeepWalk,Node2vec,EGES等主流的方法,还有LINE,SDNE等方法也很流行。
Q&A
在使用Graph Embedding生成物品的Embedding之后,应该如何生成用户的Embedding?除了Average Pooling有更好的方法吗?
若使用用户行为序列对应item embedding构建呀用户embedding会出现user embedding与item embedding不在一个向量空间的问题,这会造成无法利用user embedding和item embedding的内积直接得到推荐列表。
使用异构网络可以解决这个问题,例如metapath2vec,它本身会将不同类型的节点放到同一个网络来训练 所以得到的vector是同一空间
graph embedding对比item embedding的优势是什么?
- 通过随机游走获得的商品序列包含了直接关联和间接关联的,如此构造的序列比之前简单基于用户下单物品顺序构造的序列更广泛,也就是扩宽了推荐内容;
- 直接用原始的序列,可能存在的问题是,有一些item出现频次非常高,有一些item出现频次很低,导致部分item过度训练,而另外一些item训练不足,训练结果朝着那些热门item偏移。生成graph之后,只保留了item之间的结构,而丢掉了item出现的频次信息。在做随机游走的时候,每个节点都要作为起点游走生成序列,因此每个节点都能保证一定数量的出现频次,使得所有item都能得到有效的训练。冷门物品在序列中出现的次数更多了,其实这有利于新上线的商品(同样与其他物品关联很少)的embedding训练。
参考:
DeepWalk及node2vec简单理解学习
Graph Embedding在淘宝推荐系统中的应用
深度学习中不得不学的Graph Embedding方法
关于Node2vec算法中Graph Embedding同质性和结构性的进一步探讨
【Graph Embedding】node2vec:算法原理,实现和应用
论文:DeepWalk: Online Learning of Social Representations
论文:node2vec: Scalable Feature Learning for Networks
论文:Billion-scale Commodity Embedding for E-commerce Recommendation in Alibaba
深度解析Graph Embedding的更多相关文章
- 推文《阿里凑单算法首次公开!基于Graph Embedding的打包购商品挖掘系统解析》笔记
推文<阿里凑单算法首次公开!基于Graph Embedding的打包购商品挖掘系统解析>笔记 从17年5月份开始接触Graph Embedding,学术论文读了很多,但是一直不清楚这技术是 ...
- 基于图嵌入的高斯混合变分自编码器的深度聚类(Deep Clustering by Gaussian Mixture Variational Autoencoders with Graph Embedding, DGG)
基于图嵌入的高斯混合变分自编码器的深度聚类 Deep Clustering by Gaussian Mixture Variational Autoencoders with Graph Embedd ...
- Graph Embedding总结
图嵌入应用场景:可用于推荐,节点分类,链接预测(link prediction),可视化等场景 一.考虑网络结构 1.DeepWalk (KDD 2014) (1)简介 DeepWalk = Rand ...
- Graph Embedding Review:Graph Neural Network(GNN)综述
作者简介: 吴天龙 香侬科技researcher 公众号(suanfarensheng) 导言 图(graph)是一个非常常用的数据结构,现实世界中很多很多任务可以描述为图问题,比如社交网络,蛋白体 ...
- GNN 相关资料记录;GCN 与 graph embedding 相关调研;社区发现算法相关;异构信息网络相关;
最近做了一些和gnn相关的工作,经常听到GCN 和 embedding 相关技术,感觉很是困惑,所以写下此博客,对相关知识进行索引和记录: 参考链接: https://www.toutiao.com/ ...
- 华为全栈AI技术干货深度解析,解锁企业AI开发“秘籍”
摘要:针对企业AI开发应用中面临的痛点和难点,为大家带来从实践出发帮助企业构建成熟高效的AI开发流程解决方案. 在数字化转型浪潮席卷全球的今天,AI技术已经成为行业公认的升级重点,正在越来越多的领域为 ...
- [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析
[WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...
- 第37课 深度解析QMap与QHash
1. QMap深度解析 (1)QMap是一个以升序键顺序存储键值对的数据结构 ①QMap原型为 class QMap<K, T>模板 ②QMap中的键值对根据Key进行了排序 ③QMap中 ...
- Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN
http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...
随机推荐
- AD19如何单独设置单个焊盘与铜皮的连接方式
我们用过Altium Designer做设计的人都知道,Altium中有个强大的规则管理器,由于功能太多这里就先不介绍,有需要可以留言,今天的主题是讲解AD19的新功能,快速给单个焊盘设置与铜皮的连接 ...
- Charles 教程
本文介绍 charles 教程 - 代理抓包的使用方法 本文参考了:阿西河 Charles 教程 Charles Charles是一个HTTP代理/ HTTP监视器/反向代理,使开发人员能够查看其机器 ...
- 【计算机视觉】Object Proposal之BING理解
发现: 本论文主要有两大亮点.第一个亮点是发现了在固定窗口的大小下,物体与背景的梯度模式有所不同.如图1所示.图1(a)中绿框代表背景,红框代表物体.如果把这些框都resize成固定大小,比如8X8, ...
- Shiro加盐加密
接本人的上篇文章<Shiro认证.角色.权限>,这篇文章我们来学习shiro的加盐加密实现 自定义Realm: package com.czhappy.realm; import org. ...
- Linux centos 7下搭建mosquitto
Centos7安装 1.网卡名改为enth0 A: vim /etc/sysconfig/grub B: 第三行添加"net.ifnames=0 biosdevname=0" ...
- golang中switch用法细节
1. switch穿透-fallthrough, 如果在case语句块后增加fallthrough,则会继续执行下一个case,也叫switch穿透,默认只穿透一层 2. Type Switch: s ...
- pandas之聚合运算
通过聚合运算可以得到我们比较感兴趣的数据以方便处理 import pandas as pd import numpy as np # 先创建一组数据表DataFrame df = pd.DataFra ...
- 数据结构——java实现栈
栈 定义: 栈是一种先进后出的数据结构,我们把允许插入和删除的一端称为栈顶,另一端称为栈底,不含任何元素的栈称为空栈 栈的java代码实现: 基于数组: import org.junit.jupite ...
- Linux 系统下提取 ShellCode
未完待续 1.使用C语言编写一个获得系统Shell的小程序. #include <unistd.h> int main() { char * shell[2]; shell[0]=&quo ...
- 并不对劲的THUWC2020
day -inf 因为一些(不是寒假时长锐减的)小原因,今年(2020)THUWC在去年(2019)就举办了! 这导致某个小弱智只能临阵磨枪了QAQ- day 1 早: 没有看到吕爷,签到.试机. 签 ...