推荐系统&知识图谱(4)---KGCN

论文:Knowledge Graph Convolutional Networks for Recommender Systems,WWW,2019,Microsoft Research Asia

1. 应用背景

知识图谱卷积网络(Knowledge Graph Convolutional Networks,KGCN)是一种自动捕捉KG中高阶的结构信息和语义信息的推荐方法。其关键思想是在计算KG中给定实体的表示时,将具有偏差的邻域信息进行汇总和合并
KGCN好处有二:
1.通过汇总邻居,局部临近结构(local proximity structure)可以有效的捕捉并存贮在实体中;
2.邻居的权重取决于连接关系和特定用户,这既代表了KG的语义信息(semantic information),又体现了用户对关系的个性化兴趣(personalized interests)。
文章贡献有三:
1.提出KGCN,通过扩展KG中每个实体的表示域,来捕获用户的高阶个性化兴趣;
2.在movielen-20M,book-crossing,lastFM三个real-world数据集上实验并与state-ofart比较;
3.开源代码和数据集;

2. 模型结构

2.1 问题表述

使用知识图谱的推荐算法的问题描述和符号定义是基本一致的,贴一个基础符号的表示表。


推荐系统&知识图谱(4)---KGCN_第1张图片

2.2 KGCN结构

KGCN的结构如图所示

推荐系统&知识图谱(4)---KGCN_第2张图片
KGCN

主要关注的是KGCN是如何在KG中学习实体的表示的,下面进行推导:
记一个用户为;
记一个候选物品/实体为;
记KG中与相连的实体集合为;
记实体与的关系边为;
0.记算用户对关系的得分:,函数;

举个例子:电影推荐场景下,有的用户可能更关注和历史浏览有相同 'star' 的电影;而有的用户更关注和历史浏览有相同 'genre' 的电影。'star' 和 'genre' 属于不同的边,表示了用户对于不同关系的不同关注度。

1.对每个用户对边的得分进行标准化表示,得:
2.得到的拓扑邻近结构:
但在实际的KG中,往往的尺寸大小会差别很大,因此使用固定尺寸的代替,
3.得到使用的邻近表示:
4.设计并使用聚合器函数:,来聚合和

作者设计了sum,concat,neighbor三种聚合器,最终效果是sum最好,其表示为:

5.用h-1层的聚合结果作为h层的实体表示:

2.3 损失函数

通过这种聚合更新,可以在KG上训练得到实体对于用户的H层向量表示:
预测结果为:
使用类似pairwise的交叉熵损失:其中,是交叉熵,是用户对应负样本的个数,满足 ,服从均匀分布。

3. 实验结果

数据集:
MovieLens-20M,Book-Crossing dataset,Last.FM dataset
知识图谱:
Microsoft Satori
数据描述:


推荐系统&知识图谱(4)---KGCN_第3张图片

实验结果:


推荐系统&知识图谱(4)---KGCN_第4张图片

相关分析:
1.neighbor的尺寸大小:
推荐系统&知识图谱(4)---KGCN_第5张图片

2.迭代的深度:
推荐系统&知识图谱(4)---KGCN_第6张图片

4. 代码实现

输入:user_id , item_id , label

self.user_indices = tf.placeholder(dtype=tf.int64, shape=[None], name='user_indices')
self.item_indices = tf.placeholder(dtype=tf.int64, shape=[None], name='item_indices')
self.labels = tf.placeholder(dtype=tf.float32, shape=[None], name='labels')

可训练矩阵:user_emb_matrix,entity_emb_matrix,relation_emb_matrix

self.user_emb_matrix = tf.get_variable(
            shape=[n_user, self.dim], initializer=KGCN.get_initializer(), name='user_emb_matrix')
self.entity_emb_matrix = tf.get_variable(
            shape=[n_entity, self.dim], initializer=KGCN.get_initializer(), name='entity_emb_matrix')
self.relation_emb_matrix = tf.get_variable(
            shape=[n_relation, self.dim], initializer=KGCN.get_initializer(), name='relation_emb_matrix')

找到 item 的n层的邻居很容易,主要难点是关注如何聚合:

def _mix_neighbor_vectors(self, neighbor_vectors, neighbor_relations, user_embeddings):
    avg = False
    if not avg:
        # [batch_size, 1, 1, dim]
        user_embeddings = tf.reshape(user_embeddings, [self.batch_size, 1, 1, self.dim])

        # [batch_size, -1, n_neighbor]
        user_relation_scores = tf.reduce_mean(user_embeddings * neighbor_relations, axis=-1)
        user_relation_scores_normalized = tf.nn.softmax(user_relation_scores, dim=-1)

        # [batch_size, -1, n_neighbor, 1]
        user_relation_scores_normalized = tf.expand_dims(user_relation_scores_normalized, axis=-1)

        # [batch_size, -1, dim]
        neighbors_aggregated = tf.reduce_mean(user_relation_scores_normalized * neighbor_vectors, axis=2)
    else:
        # [batch_size, -1, dim]
        neighbors_aggregated = tf.reduce_mean(neighbor_vectors, axis=2)

    return neighbors_aggregated

可以看到,neighbors_aggregated向量是通过邻居向量x用户-关系得分权重得到的。

5. 个人总结

KGCN是将GCN与RS任务相结合,其做法是:
对于一个实体向量v,每个Hop选固定size的neighbor来当做类CNN的感知野,用neighbor在特定“user-relation”下的得分作为权重,neighbor加权的结果来表示neighbor向量,尝试通过sum/concat/replace三种方式来更新v,迭代H个hop,得到KG中所有实体的emb。

其核心思想还是:利用邻居向量来扩充当前实体的向量表示,再通过Loss回传更新。

与RippleNet有意思的区别是:RippleNet关注于用户历史的扩充,KGCN关注于物品实体的扩充,其实可以尝试同时扩充二者,获取更丰富的表示。

你可能感兴趣的:(推荐系统&知识图谱(4)---KGCN)