知识图谱论文阅读(九)【转】推荐系统遇到知识图谱之MKR模型

文哥的学习笔记: https://www.jianshu.com/p/af5226c7fbbb

知识图谱特征学习在推荐系统中的应用步骤大致有以下三种方式:

在这里插入图片描述
依次训练的方法主要有:Deep knowledge-aware Network(DKN)
联合训练的方法有: Ripple Network
交替训练主要采用multi-task的思路,主要方法有: Multi-task Learning for KG enhanced Recommendation(MKR)

1、MKR原理介绍

由于推荐系统中的物品和知识图谱中的实体存在重合,因此可以采用多任务学习的框架,将推荐系统和知识图谱特征学习视为两个分离但是相关的任务,进行交替式的学习。

MKR的模型框架如下图,其中左侧是推荐系统任务,右侧是知识图谱特征学习任务。推荐部分的输入是用户和物品的特征表示,点击率的预估值作为输出。知识图谱特征学习部分使用的是三元组的头节点和关系作为输入,预测的尾节点作为输出

在这里插入图片描述

由于推荐系统中的物品和知识图谱中的实体存在重合,所以两个任务并非相互独立。所以作者在两个任务中设计了交叉特征共享单元(cross-feature-sharing units)作为两者的连接纽带。

交叉特征共享单元是一个可以让两个任务交换信息的模块。由于物品向量和实体向量实际上是对同一个对象的两种描述,他们之间的信息交叉共享可以让两者都获得来自对方的额外信息,从而弥补了自身的信息稀疏性的不足,其结构如下:

在这里插入图片描述
关于这个交叉单元具体实现,大家可以参照代码进行理解。

最后是损失函数部分,由于是交替训练的方式,所以在训练时首先固定推荐系统模块的参数,训练知识图谱特征学习模块的参数;然后固定知识图谱特征学习模块的参数,训练推荐系统模块的参数。

推荐系统模块是点击率预估模型,损失函数是对数损失加l2正则项;知识图谱特征学习模块希望预测得到的tail向量和真实的tail向量相近,因此首先计算二者的内积(内积可近似表示向量之间的余弦相似度),内积经过sigmoid之后取相反数,再加上l2正则项,即得到了知识图谱特征学习模块的损失。关于损失的计算,我们在代码里可以更清楚的看到

本文的代码地址为:https://github.com/princewen/tensorflow_practice/tree/master/recommendation/Basic-MKR-Demo
参考代码地址为:https://github.com/hwwang55/MKR
数据下载地址为:https://pan.baidu.com/s/1uHkQXK_ozAgBWcMUMzOfZQ 密码:qw30

在对数据进行预处理后,我们得到了两个文件:kg_final.txt和rating_final.txt

rating_final.txt数据形式如下,三列分别是user-id,item-id以及label(0是通过负采样得到的,正负样本比例为1:1)。
在这里插入图片描述

kg_final.txt格式如下,三类分别代表h,r,t(这里entity和item用的是同一套id):
在这里插入图片描述
好了,接下来我们重点介绍一下我们的MKR框架的构建。

2. 模型

模型输入

模型输入有以下几个部分: 用户的id、物品的id、推荐系统部分的lablel、知识图谱三元组的head、relation、tail的对应id:

def _build_inputs(self):self.user_indices = tf.placeholder(tf.int32,[None],'user_indices')self.item_indices = tf.placeholder(tf.int32,[None],'item_indices')self.labels = tf.placeholder(tf.float32,[None],'labels')self.head_indices = tf.placeholder(tf.int32,[None],'head_indices')self.tail_indices = tf.placeholder(tf.int32,[None],'tail_indices')self.relation_indices = tf.placeholder(tf.int32,[None],'relation_indices')

低层网络构建

低层网络指下面的部分:
在这里插入图片描述
可以看到,user_id、item_id、head_id以及relation_id首先转换为对应的Embedding,user_id和relation_id经由多层神经网络向上传播、而head_id和item_id经过交叉单元进行传播!

def _build_low_layers(self,args):self.user_emb_matrix = tf.get_variable('user_emb_matrix', [self.n_user, args.dim])self.item_emb_matrix = tf.get_variable('item_emb_matrix', [self.n_item, args.dim])self.entity_emb_matrix = tf.get_variable('entity_emb_matrix', [self.n_entity, args.dim])self.relation_emb_matrix = tf.get_variable('relation_emb_matrix', [self.n_relation, args.dim])# [batch_size, dim]self.user_embeddings = tf.nn.embedding_lookup(self.user_emb_matrix, self.user_indices)self.item_embeddings = tf.nn.embedding_lookup(self.item_emb_matrix, self.item_indices)self.head_embeddings = tf.nn.embedding_lookup(self.entity_emb_matrix, self.head_indices)self.relation_embeddings = tf.nn.embedding_lookup(self.relation_emb_matrix, self.relation_indices)self.tail_embeddings = tf.nn.embedding_lookup(self.entity_emb_matrix, self.tail_indices)for _ in range(args.L):user_mlp = Dense(input_dim=args.dim,output_dim=args.dim)  #通过dense网络tail_mlp = Dense(input_dim=args.dim,output_dim = args.dim)  #通过dense网络cc_unit = CrossCompressUnit(args.dim)   #这是交叉单元self.user_embeddings = user_mlp(self.user_embeddings)self.item_embeddings,self.head_embeddings = cc_unit([self.item_embeddings,self.head_embeddings])self.tail_embeddings = tail_mlp(self.tail_embeddings)self.vars_rs.extend(user_mlp.vars)self.vars_rs.extend(cc_unit.vars)self.vars_kge.extend(tail_mlp.vars)self.vars_kge.extend(cc_unit.vars)

接下来,我们来看一下交叉单元的代码:

v,e = inputsv = tf.expand_dims(v,dim=2)
e = tf.expand_dims(e,dim=1)# [batch_size, dim, dim]
c_matrix = tf.matmul(v, e)
c_matrix_transpose = tf.transpose(c_matrix, perm=[0, 2, 1])# [batch_size * dim, dim]
c_matrix = tf.reshape(c_matrix, [-1, self.dim])
c_matrix_transpose = tf.reshape(c_matrix_transpose, [-1, self.dim])v_output = tf.reshape(tf.matmul(c_matrix,self.weight_vv) + tf.matmul(c_matrix_transpose,self.weight_ev),[-1,self.dim]) + self.bias_ve_output = tf.reshape(tf.matmul(c_matrix, self.weight_ve) + tf.matmul(c_matrix_transpose, self.weight_ee),[-1, self.dim]) + self.bias_ereturn v_output,e_output

item对应的embedding用v表示,head对应的embedding用e表示,二者初始情况下都是batch * dim大小的。过程如下:
1、v扩展成三维batch * dim * 1,e扩展成三维batch * 1 * dim,随后二者进行矩阵相乘v * e,我们知道三维矩阵相乘实际上是后两维进行运算,因此得到c_matrix的大小为 batch * dim * dim
2、对得到的c_matrix进行转置,得到c_matrix_transpose,大小为batch * dim * dim。这相当于将e扩展成三维batch * dim * 1,v扩展成三维batch * 1 * dim,随后二者进行矩阵相乘e * v。这是两种不同的特征交叉方式。
3、对c_matrix和c_matrix_transpose 进行reshape操作,变为(batch * dim ) * dim的二维矩阵
4、定义两组不同的参数和偏置,分别得到交叉后的v_output和e_output.

高层网络构建

高层网络指下面的部分:
在这里插入图片描述
对于推荐部分,可以采用内积直接得到CTR的预估值,也可以经过多层神经网络得到预估值;对于知识图谱部分,将head和relation对应的向量进行拼接,经过多层神经网络,得到一个tail对应向量的预估值,并与真实的tail向量计算内积。代码如下:

def _build_high_layers(self,args):#RSuse_inner_product = Trueif use_inner_product:self.scores = tf.reduce_sum(self.user_embeddings*self.item_embeddings,axis=1)else:self.user_item_concat = tf.concat([self.user_embeddings,self.item_embeddings],axis=1)for _ in range(args.H - 1):rs_mlp = Dense(input_dim = args.dim * 2 , output_dim = args.dim * 2)self.user_item_concat = rs_mlp(self.user_item_concat)self.vars_rs.extend(rs_mlp.vars)rs_pred_mlp = Dense(input_dim=args.dim * 2,output_dim=1)self.scores = tf.squeeze(rs_pred_mlp(self.user_item_concat))self.vars_rs.extend(rs_pred_mlp)self.scores_normalized = tf.nn.sigmoid(self.scores)#KGEself.head_relation_concat = tf.concat([self.head_embeddings,self.relation_embeddings],axis=1)for _ in range(args.H - 1):kge_mlp = Dense(input_dim=args.dim * 2,output_dim = args.dim * 2)self.head_relation_concat = kge_mlp(self.head_relation_concat)self.vars_kge.extend(kge_mlp.vars)kge_pred_mlp = Dense(input_dim=args.dim * 2,output_dim = args.dim)self.tail_pred = kge_pred_mlp(self.head_relation_concat)self.vars_kge.extend(kge_pred_mlp.vars)self.tail_pred = tf.nn.sigmoid(self.tail_pred)self.scores_kge = tf.nn.sigmoid(tf.reduce_sum(self.tail_embeddings * self.tail_pred,axis=1))#self.rmse = tf.reduce_mean(tf.sqrt(tf.reduce_sum(tf.square(self.tail_embeddings - self.tail_pred),axis=1) / args.dim))

定义损失

推荐系统部分的损失是对数损失加l2正则项:

# RS
self.base_loss_rs = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=self.labels, logits=self.scores))
self.l2_loss_rs = tf.nn.l2_loss(self.user_embeddings) + tf.nn.l2_loss(self.item_embeddings)
for var in self.vars_rs:self.l2_loss_rs += tf.nn.l2_loss(var)
self.loss_rs = self.base_loss_rs + self.l2_loss_rs * args.l2_weight

知识图谱特征学习模块用上一步计算的scores_kge的相反数再加上l2正则项:

# KGE
self.base_loss_kge = -self.scores_kge
self.l2_loss_kge = tf.nn.l2_loss(self.head_embeddings) + tf.nn.l2_loss(self.tail_embeddings)
for var in self.vars_kge:self.l2_loss_kge += tf.nn.l2_loss(var)
self.loss_kge = self.base_loss_kge + self.l2_loss_kge * args.l2_weight

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/476151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 883. 三维形体投影面积

1. 题目 在 N * N 的网格中,我们放置了一些与 x,y,z 三轴对齐的 1 * 1 * 1 立方体。 每个值 v grid[i][j] 表示 v 个正方体叠放在单元格 (i, j) 上。 现在,我们查看这些立方体在 xy、yz 和 zx 平面上的投影。 投影就像影子&a…

asoc linux设备驱动_Linux驱动分析之I2C设备

内核:4.20芯片:HYM8563 RTC下面的代码分析主要都在注释中,会按照驱动中函数的执行顺序分析。(1) 加载和卸载函数static const struct i2c_device_id hym8563_id[] {{ "hym8563", 0 },{}, }; MODULE_DEVICE_TABLE(i2c, hym8563_id)…

诚邀参加微软.NET俱乐部10月24日Windows 7社区发布会

为了配合微软下一代桌面操作系统—Windows7的发布,微软.NET俱乐部联合ZDNET至顶网社区特地组织了“让社区激情随Win 7 一同绽放”—Windows 7 社区发布会。10月24日13点半,将在北京,微软亚洲研究院地下一层阶梯会议中心举行,欢迎当…

知识图谱论文阅读【十二】【KDD2020】 使用贝叶斯图卷积神经网络推荐精确和多样化项目的框架【看不懂,待续】

题目: A Framework for Recommending Accurate and Diverse Items Using Bayesian Graph Convolutional Neural Networks 作者: 原文链接: https://www.researchgate.net/publication/343780326_A_Framework_for_Recommending_Accurate_and…

LeetCode 884. 两句话中的不常见单词

1. 题目 给定两个句子 A 和 B 。 (句子是一串由空格分隔的单词。每个单词仅由小写字母组成。) 如果一个单词在其中一个句子中只出现一次,在另一个句子中却没有出现,那么这个单词就是不常见的。 返回所有不常用单词的列表。 您…

bigdecimal如何做除法_二胎家庭如何平衡两个孩子的关系?聪明的父母都懂这四个法则...

治愈系慢综艺《朋友请听好》上段时间一直霸榜热搜。其中有一集,一位二胎妈妈来电探讨两个孩子的相处问题,引发了网友热议。弹幕里有人说:“别人家的孩子兄友弟恭,其乐融融,我们家永远是你来我往的大型武斗场景。”对此…

操作注册表

操作注册表 Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\MyKey"); RegistryKey rk Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\MyKey", true); rk.SetValue("姓名", "小芳"); …

LeetCode 893. 特殊等价字符串组

1. 题目 你将得到一个字符串数组 A。 如果经过任意次数的移动,S T,那么两个字符串 S 和 T 是特殊等价的。 一次移动包括选择两个索引 i 和 j,且 i % 2 j % 2,交换 S[j] 和 S [i]。 现在规定&#xff…

知识图谱论文阅读(十三)【2020 arXiv】Attentive Knowledge Graph Embedding for Personalized Recommendation

题目: Attentive Knowledge Graph Embedding for Personalized Recommendation 论文链接: 代码链接: 知识图谱特征学习在推荐系统中的应用步骤大致有以下三种方式: BPThrough Time 【5】Backpropagation: theory, architecture…

ad批量走线_AD PCB直角布线批量改为圆角,怎么批量修改呢?

1.拖动器件不让连接线跟着一起走,怎么设置呢?答:执行快捷键OP,将Always Drag选项的勾掉即可,如图所示:2.如图中所示,有很多元件位号重复或者位号需要重新编辑命名,请哪位大神有什么快…

[转帖]Mootools源码分析-02 -- Utils

原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-400118 原作者:我佛山人 //检查对象是否已经定义或者已经赋值function$chk(obj) { return!!(obj ||ōbj 0);};//通用清除计时器的方法,即能清setTimeout,又能清setIn…

ios realm 文件_iOS Realm数据库使用

Realm 是 SQLite 和 Core Data 的替代者,得益于其零拷贝的设计,Realm 比任何 ORM 都要快很多。Objective‑C版本的 Realm 能够让您以一种安全、耐用以及迅捷的方式来高效地编写应用的数据模型层,如下例所示:Dog.hinterface Dog : …

李宏毅机器学习(十一)meta-learning和ML一样是三个步骤

Meta-learning就是教会它怎么学! 大家以为AI都是很牛,但其实就是在调参,在工业界怎么样子调参呢? 使用1000GPUs,而学业界只有一张! 我们知道Machine learning可以学出来,那么hyperparameters是…

教育的真谛

湖畔疑云 大学将是你人生最重要的时光,在大学里你会发现学习的真谛。你以前经常会问到 “这个课程有什么用”,这是个好问题,但是我希望你理解:“教育的真谛就是当你忘记一切所学到的东西之后所剩下的东西。”我的意思是&#xff0…

LeetCode 748. 最短完整词

1. 题目 如果单词列表(words)中的一个单词包含牌照(licensePlate)中所有的字母,那么我们称之为完整词。 在所有完整词中,最短的单词我们称之为最短完整词。 单词在匹配牌照中的字母时不区分大小写&#x…

单反录像按钮在哪_单反与微单到底哪不同

数码相机发展到现在从卡片相机到单反相机然后到微单相机,而单反相机和微单相机都是比较专业的数码相机,具有很好的操作性能,那么单反与微单的区别到底在哪或是单反与微单到底哪不同呢?接下来我们就来看看。单反和微单主要的区别就…

(十四)【RecSys 2016】Personalized Recommendations using Knowledge Graphs: A Probabilistic【看不懂】

题目: Personalized Recommendations using Knowledge Graphs: A Probabilistic Logic Programming Approach(一种概率逻辑编程方法) 论文链接: 代码: 想法 (1)推荐系统就是求出user和item的特…

Flash 杂志《summer tree》 第六期发布

经过几天的排版,Summer Tree 第六期出来了,在这里感谢Anson和Star的帮助。 封面拿了一张底贴上去,基本上无点ps ,实在无什么美感可言。暂时忍耐一下。 Anson的博客:http://blog.csdn.net/kongweian 下载地址&#xff1…

利用瑞利里兹方法计算固有频率的程序_不可不知的电机磁致伸缩计算方法

磁致伸缩是指电机硅钢片铁芯在交变磁场的作用下,发生微小的尺寸变化的现象,磁致伸缩使铁心随励磁频率的变化做周期性振动。本文主要研究磁致伸缩力和麦克斯韦力对电机振动噪声的贡献,从而对电机的振动噪声控制提供依据。分析必要性电机的振动…

LeetCode 917. 仅仅反转字母

1. 题目 给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。 示例 1: 输入:"ab-cd" 输出:"dc-ba"示例 2: 输入&…