Causal Representation Learning for Out-of-Distribution Recommendation

Causal Representation Learning for Out-of-Distribution Recommendation

1 INTRODUCTION

推荐系统从历史交互数据中学习用户偏好表示,然而用户偏好转移是常见的,这是一种OOD问题

目前解决user feature shifts问题的方法分为三类

  1. Feature-based models :FM 但无法将用户特征和历史偏好解耦
  2. Disentangled recommendation:MacridVAE 以往的研究大多忽略了用户特征,将过时的交互编码在表示中
  3. Model re-training :面临着再训练频率和计算成本问题,需要在特征转移后收集新的交互

在这里插入图片描述

现有的方法通过E1和D来学习偏好表示,所以会出现OOD问题,OOD推荐是对干预后相互作用概率的推断:P(D|do(E1 = e ′1), E2)

用户偏好变化对E1有影响,进而影响Z1,可以使用不变偏好Z2迅速适应变化

2 CAUSAL OOD RECOMMENDATION

Causal Representation Learning

在这里插入图片描述

通过重建历史交互D来进行优化参数集θ ={θ1, θ2, θ3}

具体来说就是给定e1和d,最大化对数似然log p(d |e1)

然鹅e2是不可观测的,借用变分推理的思想,得到可信度下界(evidence lower bound,ELBO):

在这里插入图片描述

😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊

Encoder Network

q(e2 |·) = q(e2 |d, e1) 通过d和e1来预测e2,为了达到更精准的评估,使用了amortized inference(平摊推理),并设计了一个encoder

在这里插入图片描述

Decoder Network

在图三(b)中,根据等式(1)对p(d∣e1,e2)进行了分解,得到:

在这里插入图片描述

为了避免(5)中的积分计算,这里采用了蒙特卡洛采样方法,通过采样z1和z2来近似p**(de1,e2)**:

在这里插入图片描述

这里的L和M是采样数量,z1a和z2b是从分布 在计算条件概率的时候依然十分耗时,本论文又使用了一种常见的近似方法

COR Optimization

首先是在VAE的隐向量采样中使用了重参数化技巧,并且使用了KL annealing​ ​(KL退火),超参数为β​ ​,来限制KL散度的正则化。最终对于用户u​ ​的ELBO目标函数为:

在这里插入图片描述

Causal Inference of COR

利用VAE对交互生成进行因果建模,接下来讲述推导干预后的概率p(d ′|e ′1, e2),

最直白的方式是将d和e1’给到encoder,然后将e1’和e2给decoder得到d ,但是这种方法d可能带有过时的交互(out-of-date inteactions)

从而影响到e2。为了保证这些过时的信息不影响到e1’ ,去除e2到z1的影响,同时保留e2到z2的影响,采用了三个步骤:
在这里插入图片描述

  • Abduction :根据真实数据D =d 单独估计z2
  • Action : 执行do操作(D=0)来估计e2’和z1’ D=0 表示空的交互
  • Prediction : 通过z1’和z2来得到d ′ = fθ3 (z′1, z2)

算法流程如图:

在这里插入图片描述

考虑模型适应性(Fast Adaptation) 由于在不同的环境下Z2是不变的,所以在可以重复利用不变的用户表示。VAE中的函数都是基于因果关系构建的,这些函数在干预下更加稳定,并且需要更少的数据来调整从IID环境到OOD环境的参数偏差

COR with Fine-grained Causal Graph 细粒度的因果图

考率到E1E2 ​Z1之间的细粒度因果图,例如“收入”影响用户对“价格”和“品牌”的偏好而不影响对“商品尺寸”的偏好

在估计g p(z1 |e1, e2)的时候将细粒度的因果图融入到decoder中,将MLP fθ1 (·) 替代为Neural Causal Models (NCM) 可以编码细粒度的因果关系

在这里插入图片描述

NCM将其在因果图中父结点的表示进行加和,“收入”、“年龄”以及e2的表示被相加后作为“价格”的偏好,然后将这些加和投入MLP来预测Z1,这种对应关系是基于细粒度因果图在训练期间通过隐式地学习获得的。

"Structure-Aware Transformer for Graph Representation Learning"是一篇使用Transformer模型进行图表示学习的论文。这篇论文提出了一种名为SAT(Structure-Aware Transformer)的模型,它利用了图中节点之间的结构信息,以及节点自身的特征信息。SAT模型在多个图数据集上都取得了非常好的结果。 以下是SAT模型的dgl实现代码,代码中使用了Cora数据集进行示例: ``` import dgl import numpy as np import torch import torch.nn as nn import torch.nn.functional as F class GraphAttentionLayer(nn.Module): def __init__(self, in_dim, out_dim, num_heads): super(GraphAttentionLayer, self).__init__() self.num_heads = num_heads self.out_dim = out_dim self.W = nn.Linear(in_dim, out_dim*num_heads, bias=False) nn.init.xavier_uniform_(self.W.weight) self.a = nn.Parameter(torch.zeros(size=(2*out_dim, 1))) nn.init.xavier_uniform_(self.a.data) def forward(self, g, h): h = self.W(h).view(-1, self.num_heads, self.out_dim) # Compute attention scores with g.local_scope(): g.ndata['h'] = h g.apply_edges(fn.u_dot_v('h', 'h', 'e')) e = F.leaky_relu(g.edata.pop('e'), negative_slope=0.2) g.edata['a'] = torch.cat([e, e], dim=1) g.edata['a'] = torch.matmul(g.edata['a'], self.a).squeeze() g.edata['a'] = F.leaky_relu(g.edata['a'], negative_slope=0.2) g.apply_edges(fn.e_softmax('a', 'w')) # Compute output features g.ndata['h'] = h g.update_all(fn.u_mul_e('h', 'w', 'm'), fn.sum('m', 'h')) h = g.ndata['h'] return h.view(-1, self.num_heads*self.out_dim) class SATLayer(nn.Module): def __init__(self, in_dim, out_dim, num_heads): super(SATLayer, self).__init__() self.attention = GraphAttentionLayer(in_dim, out_dim, num_heads) self.dropout = nn.Dropout(0.5) self.norm = nn.LayerNorm(out_dim*num_heads) def forward(self, g, h): h = self.attention(g, h) h = self.norm(h) h = F.relu(h) h = self.dropout(h) return h class SAT(nn.Module): def __init__(self, in_dim, hidden_dim, out_dim, num_heads): super(SAT, self).__init__() self.layer1 = SATLayer(in_dim, hidden_dim, num_heads) self.layer2 = SATLayer(hidden_dim*num_heads, out_dim, 1) def forward(self, g, h): h = self.layer1(g, h) h = self.layer2(g, h) return h.mean(0) # Load Cora dataset from dgl.data import citation_graph as citegrh data = citegrh.load_cora() g = data.graph features = torch.FloatTensor(data.features) labels = torch.LongTensor(data.labels) train_mask = torch.BoolTensor(data.train_mask) val_mask = torch.BoolTensor(data.val_mask) test_mask = torch.BoolTensor(data.test_mask) # Add self loop g = dgl.remove_self_loop(g) g = dgl.add_self_loop(g) # Define model and optimizer model = SAT(features.shape[1], 64, data.num_classes, 8) optimizer = torch.optim.Adam(model.parameters(), lr=0.005, weight_decay=5e-4) # Train model for epoch in range(200): model.train() logits = model(g, features) loss = F.cross_entropy(logits[train_mask], labels[train_mask]) optimizer.zero_grad() loss.backward() optimizer.step() acc = (logits[val_mask].argmax(1) == labels[val_mask]).float().mean() if epoch % 10 == 0: print('Epoch {:03d} | Loss {:.4f} | Accuracy {:.4f}'.format(epoch, loss.item(), acc.item())) # Test model model.eval() logits = model(g, features) acc = (logits[test_mask].argmax(1) == labels[test_mask]).float().mean() print('Test accuracy {:.4f}'.format(acc.item())) ``` 在这个示例中,我们首先加载了Cora数据集,并将其转换为一个DGL图。然后,我们定义了一个包含两个SAT层的模型,以及Adam优化器。在训练过程中,我们使用交叉熵损失函数和验证集上的准确率来监控模型的性能。在测试阶段,我们计算测试集上的准确率。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值