[图协同过滤]整理一些论文

简介

本文目的是简单整理一些图+协同过滤的论文找灵感,可能有些地方理解不对,望大佬们指正,正在更新中。
转载请标明原作者和源地址。

标题简称文章地址代码地址
Neural Graph Matching based Collaborative FilteringGMCF地址地址
Improving Graph Collaborative Filtering with Neighborhood-enriched Contrastive LearningNCL地址地址

GMCF

模型和模块

GMCF模型图
GMCF用协同过滤实现相关物品的推荐,它的模型主要分为三个部分:图的构建(1),基于节点匹配的GNN(2),图匹配(3)。
(1) 图的构建
分别构建了用户属性图和项目属性图,每个用户(或项目)都表示为一个属性图,其属性为节点,节点表示使用的是属性表示embedding;内部交互关系为边,实际上每对节点都会用一条边相连。
(2) 基于节点匹配的GNN
实际上这里的GNN考虑到了内部交互和交叉交互(比如用户和物品的交互关系)。
外部交互目的是实现协同过滤,也就是说用户1对物品1的属性有很高的偏好,它们的嵌入应该相似。采取了Bi-interaction算法建模交互属性: s i , j = u i ⊙ u j ^ s_{i,j}=u_i \odot \hat{u_j} si,j=uiuj^,即逐元素乘积。

class cross_GNN(MessagePassing):
    def __init__(self, dim, hidden_layer):
        super(cross_GNN, self).__init__(aggr='mean')
    ... ...
    def message(self, x_i, x_j, edge_weight):
        # x_i has shape [E, dim]
        # x_j has shape [E, dim]

        # pairwise analysis
        pairwise_analysis = x_i * x_j
    ... ...

内部交互目的是捕获用户(项目属性图则目标是捕获项目)信息,采用的是MLP建模交互关系,在消息传递中实现 z i , j = f n e u r a l ( u i , u j ) z_{i,j}=f_{neural}(u_i,u_j) zi,j=fneural(ui,uj),代码里对应的是这部分:

# 只取用inner GNN相关部分,剩余部分用省略号进行表示
class inner_GNN(MessagePassing):
    def __init__(self, dim, hidden_layer):
        super(inner_GNN, self).__init__(aggr='mean')
        #construct pairwise modeling network(MLP模块)
        self.lin1 = nn.Linear(dim, hidden_layer)
        self.lin2 = nn.Linear(hidden_layer, dim)
        self.act = nn.ReLU()
        self.drop = nn.Dropout(p=0.5)
     ... ...
    def message(self, x_i, x_j, edge_weight):
        # pairwise analysis(输入是2个节点特征,输出是交互关系)
        pairwise_analysis = x_i * x_j
        pairwise_analysis = self.lin1(pairwise_analysis)
        pairwise_analysis = self.act(pairwise_analysis)
        pairwise_analysis = self.lin2(pairwise_analysis)
        pairwise_analysis = self.drop(pairwise_analysis)
    ... ...

节点聚合表示时,此时获得了初始节点表示 u i u_i ui,消息传递的内容 z i z_i zi(这个在inner_GNN里完成),节点匹配结果 s i s_i si(这个是cross_GNN做的),使用了一个函数聚合它们,本文里采用了GRU。
(3) 图匹配
用函数 f G f_G fG获得整体图表示之后,直接用点乘做预测(是否该给这个用户推荐这个商品)。
在这里插入图片描述

训练和预测

训练目标如下图所示:
在这里插入图片描述
也就是最小化损失,损失的来源是GMCF预测label和真实label的差异。

总结

这篇文章实际上把user和item建立了两种图,通过交互把它们连接起来。我觉得这篇文章好的地方是区别对待交互关系,也就是内部交互和交叉交互,下面的左图体现了它的新颖性。
交互关系建模示意

NCL

模型和模块

总体框架图
(1)GNN的基本操作
采取多层GNN对特征进行提取,主要包含两个函数。
GNN作用
f p r o p a g a t e f_{propagate} fpropagate负责聚合同一层的邻居的信息,以获得更高一层的表示; f r e a d o u t f_{readout} freadout负责获得最后的表示用于推荐,聚合的是多层的信息。
本文中的GNN负责建模用户和项目之间的交互,其中 f p r o p a g a t e 做法为: f_{propagate}做法为: fpropagate做法为:
传播函数
f r e a d o u t f_{readout} freadout做法为:
聚合多层
这里的LOSS采用了Bayesian Personalized Ranking (BPR) ,找了一篇讲BPR损失的,之后我再补上 (挖坑+1)
代码里是在最后聚合所有损失的时候加上的:

def calculate_loss(self, interaction):
    ... ...
    # calculate BPR Loss
        pos_scores = torch.mul(u_embeddings, pos_embeddings).sum(dim=1)
        neg_scores = torch.mul(u_embeddings, neg_embeddings).sum(dim=1)

        mf_loss = self.mf_loss(pos_scores, neg_scores)

        u_ego_embeddings = self.user_embedding(user)
        pos_ego_embeddings = self.item_embedding(pos_item)
        neg_ego_embeddings = self.item_embedding(neg_item)
    ... ...

(2)结构邻居的对比损失
结构邻居是指通过高阶路径在结构上连接的节点,这个模块是想用结构邻居捕获user和item的潜在关系。具体做法是将用户自身的嵌入和偶数层GNN的相应输出的嵌入视为正对,因为图G是一个二部图,偶数次信息传播才能收集到同质邻居的信息(比如说我从用户出发,走偶数次才能走到另一个用户)。方法如下所示。
用户侧结构损失:
用户侧结构损失
项目侧结构损失:
项目侧结构损失
综合结构损失:
综合结构损失
代码里对应的是这个部分:

# 截取了很少的一部分
def ssl_layer_loss(self, current_embedding, previous_embedding, user, item):
    ... ...
    ssl_loss = self.ssl_reg * (ssl_loss_user + self.alpha * ssl_loss_item)
    return ssl_loss

(3)语义邻居的对比损失
由于结构邻居对比损失对所有邻居一视同仁,所以可能会引入噪声,因此采用语义邻居扩展对比损失。语义邻居的识别采用潜在原型的方式,原型是一组语义邻居的中心(所以用聚类算法聚出来一个),实现方式是采用EM算法进行原型的学习。方法如下所示。
用户原型:
用户原型学习损失
项目原型:
项目原型学习损失
综合一下:
综合原型学习损失

def ProtoNCE_loss(self, node_embedding, user, item):
    ... ...
    proto_nce_loss = self.proto_reg * (proto_nce_loss_user + proto_nce_loss_item)
    return proto_nce_loss

(4) 终极损失,就是把上面的再加点超参融合一下,用EM算法做优化。
终极损失
在函数calculate_loss融合了一下:

def calculate_loss(self, interaction):
    ... ...
    reg_loss = self.reg_loss(u_ego_embeddings, pos_ego_embeddings, neg_ego_embeddings)

    return mf_loss + self.reg_weight * reg_loss, ssl_loss, proto_loss

训练和预测

优化是采用EM算法迭代进行的,之后再补 (挖坑+1)

总结

这篇是把user和item建模在一个图里,以二部图的方式构建图。利用多层GNN设计了结构损失,并且提出了语义邻居的概念。总之就是多层GNN和层间交互+两种角度的损失+对比学习的这么一个框架,感觉对于我这个小白而言真的挺精巧的,对比学习是好东西啊!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值