RippleNet | Propagating User Preferences on the Knowledge
类别:联合学习
将知识图谱特征学习和推荐算法的目标函数结合,使用端到端(end-to-end)的方法进行联合学习。
[论文下载链接]https://arxiv.org/abs/1803.03467
1、背景
上一篇介绍了依次学习中的DKN,需要先学习到entity的向量和relation的向量,然后讲这些向量引入推荐系统来学习user的向量和item的向量。但是学习entity向量和relation向量的目的是为了还原知识图谱中的三元组关系,而并非是为了我们的推荐任务。
为了解决现有的embedding-based方法和path-based方法的限制,作者提出了一种可以将知识图谱自然地融入到推荐系统的端到端的框架RippleNet。
RippleNet原理:
对于每个用户,RippleNet将其历史兴趣视为KG中的种子集,然后沿着KG链接迭代地扩展用户的兴趣,以发现他对候选项目的等级潜在兴趣。我们将偏好传播与由在水上传播的雨滴产生的实际波纹进行类比,其中多个“波纹”叠加以形成用户在知识图上的最终偏好分布。
2、问题制定
用户集 U = { u1, u2, …}
项目集 V = { v1, v2, …}
用户-项 交互矩阵
Y = { yuv | u ∈ U, v ∈ V}
知识图谱
G = { (h,r,t) | h, t ∈ E, r ∈ R }
在许多推荐场景中,item v ∈ V 可能与知识图谱中的一个或多个 entity相关
目标:学习预测函数
yˆuv =F( u, v ; Θ ), yˆuv表示用户 u 点击项目 v 的可能性
3、RippleNet
3.1 水波纹集 Ripple Set
定义1(相关实体)
给定交互矩阵Y和知识图G,用户u 的k-hop相关实体集被定义为:
当k=0时,表示用户历史点击项目,被视为KG中用户u的种子集:
定义2(纹波集)
用户u 的k-hop纹波集被定义为从Ek-1u 开始的知识三元组:
3.2 框架 Framework
输入:用户u 和 预测项v
输出:用户u 点击 项v 的可能性分数
对于每一个输入用户u,他的历史兴趣集Vu被视为KG中的种子,然后沿着KG链接迭代地扩展用户的兴趣,形成多个水波纹集Sku( k = 1,2,…,H)。一个水波纹集Sku是距离种子集Vu有k-hop(s)距离的一组知识三元组。这些水波纹集迭代的与项 v (黄色竖条块)进行交互来获取用户关于项 v 的响应(绿色竖条块),然后将这些响应结合形成user embedding(灰色竖条块),最后使用 user embedding 和 item embedding 计算可能性分数yˆuv。
3.3 偏好传播 Preference Propagation
每个项目v 与项目嵌入v∈Rd 相关联,其中d是嵌入的维度。项目嵌入可以基于应用场景包含 one-hot ID,属性,bag-of-words 或上下文信息。 给定项目嵌入v 和用户u的1-hop纹波集合S1u,通过将项目v与头部hi和关系ri进行比较(hi和ri为S1u中的每个三元组(hi, ri, ti))分配一个关联概率(蓝色块):
Note:Pi可以看作在关系空间Ri∈ Rd×d中,item v 和 entity hi 的相似度。注意,在计算项目v和实体h的相关性时,有必要考虑嵌入矩阵R ,因为项目 - 实体对在通过不同关系测量时可能具有不同的相似性。 例如,“Forrest Gump”和“Cast Away”在考虑他们的导演或明星时非常相似,但如果按流派或作家来衡量,则没有共同之处。
然后将尾部ti和相关权重Pi相乘再求和得到向量o1u:
用户的兴趣从他的历史集合Vu沿着Su1中的链路转移到他的1-hop相关实体Eu1的集合,这在RippleNet中称为偏好传播。
将v用o1u取代可计算出o2u,同理可以计算出o3u, … ,oHu
然后user embedding 可以用用各阶响应之和表示:
Note:尽管在理论上最后一步oHu 包含了之前每一步的信息,但还是有必要把之前的oku加入计算,因为之前的oku的信息传到最后被稀释了。
最后user embedding 和 item embedding一起来预测u点击v的可能性:
3.4 学习算法 Learning Algorithm
在给定知识图谱G,用户的隐式反馈Y时,我们希望最大化后验概率:
其中Θ包括所有实体,关系和项目的嵌入,后验概率展开后相当于最大化
第一项p(Θ)是测量模型参数Θ的先验概率,我们认为参数的先验概率服从零均值和对角协方差矩阵的高斯分布:
第二项是给定Θ的观察知识图G的似然函数,在RippleNet中,我们使用three-way张量分解方法来定义KGE的似然函数:
Note:其中如果(h,r,t)∈G指标 Ih,t,r 等于1,否则为0。因此可以在相同的计算模型下统一KGE中的实体-实体对和偏好传播中的项目 - 实体对的评分函数。
第三项是给定Θ和KG的观察隐式反馈的似然函数,KG被定义为伯努利分布的乘积:
因此,我们可以得到RippleNet的损失函数形式如下:
Note:第一项可以看作是推荐系统的交叉熵损失,第二项可以看作是知识图谱的平方误差,第三个项是防止过度拟合的正则化项。
直接解决上述问题是难以处理的,因此,我们采用随机梯度下降(SGD)算法
来迭代地优化损失函数。 RippleNet的学习算法在算法1中给出。在每次训练迭代中,为了使计算更有效,我们采用负采样策略
随机采样来自Y的正/负相互作用的小批量和来自G的真/假三元组。 。然后,我们计算损失L相对于模型参数Θ的梯度,并基于采样minibatch通过反向传播更新所有参数。
4、相关问题:
纹波集的大小可能随着hop数k的增加而变得太大问题
- 真实KG中的大量实体是sink实体,这意味着它们只有传入链接但没有传出链接,如图3中的“2004”和“PG-13”。
- 在诸如电影或书籍推荐的特定推荐场景中,关系可以限于与场景相关的类别,以减小波纹集的大小并提高实体之间的相关性。例如,在图3中,所有关系都与电影有关,并且在其名称中包含单词“film”。
- 最大hop数H在实践中通常不会太大,因为距离用户历史太远的实体可能带来比positive signal还要多的噪声。我们将在实验部分讨论H的选择。
- 在RippleNet中,我们可以采样固定大小的邻居集,而不是使用完整的纹波集以此来减少计算开销。设计这样的采样器是未来工作的重要方向,尤其是非均匀采样器,以便更好地捕获用户的hierarchical潜在兴趣。
关于学习算法中的数学公式理解
- 先验概率、后验概率、条件概率、贝叶斯概率: https://www.cnblogs.com/yemanxiaozu/p/7680761.html
- 二项分布、正态分布、似然函数:https://space.bilibili.com/257347536/channel/index
- 从贝叶斯角度深入理解正则化:https://blog.csdn.net/zhuxiaodong030/article/details/54408786
- 协方差矩阵的理解:https://www.cnblogs.com/chaosimple/p/3182157.html
协方差矩阵的计算:https://blog.csdn.net/u013555719/article/details/82628835
5、RippleNet的Tensorflow实现
参考的代码地址为:https://github.com/hwwang55/RippleNet
cd desktop/RippleNet/src
python3 preprocess.py
reading item index to entity id file: ../data/movie/item_index2entity_id_rehashed.txt ...
reading rating file ...
converting rating file ...
number of users: 6036
number of items: 2445
converting kg file ...
number of entities (containing items): 182011
number of relations: 12
donepython3 main.py --dataset movie
reading rating file ...
splitting dataset ...
reading KG file ...
constructing knowledge graph ...
constructing ripple set ...epoch 0 train auc: 0.9151 acc: 0.8353 eval auc: 0.9042 acc: 0.8267 test auc: 0.9037 acc: 0.8256
epoch 1 train auc: 0.9312 acc: 0.8546 eval auc: 0.9146 acc: 0.8374 test auc: 0.9134 acc: 0.8365
epoch 2 train auc: 0.9398 acc: 0.8659 eval auc: 0.9173 acc: 0.8411 test auc: 0.9169 acc: 0.8414
epoch 3 train auc: 0.9480 acc: 0.8770 eval auc: 0.9203 acc: 0.8459 test auc: 0.9198 acc: 0.8443
epoch 4 train auc: 0.9544 acc: 0.8862 eval auc: 0.9215 acc: 0.8474 test auc: 0.9209 acc: 0.8472
epoch 5 train auc: 0.9586 acc: 0.8923 eval auc: 0.9217 acc: 0.8465 test auc: 0.9215 acc: 0.8468
epoch 6 train auc: 0.9625 acc: 0.8978 eval auc: 0.9209 acc: 0.8475 test auc: 0.9203 acc: 0.8460
epoch 7 train auc: 0.9627 acc: 0.8995 eval auc: 0.9189 acc: 0.8445 test auc: 0.9190 acc: 0.8447
epoch 8 train auc: 0.9674 acc: 0.9067 eval auc: 0.9167 acc: 0.8413 test auc: 0.9166 acc: 0.8427
epoch 9 train auc: 0.9701 acc: 0.9109 eval auc: 0.9182 acc: 0.8440 test auc: 0.9178 acc: 0.8437