CoNet: Collaborative Cross Networks for Cross-Domain Recommendation(CIKM 2018)

5
(2)


模型复现:

import torch
from torch import nn
import numpy as np 
import pandas as pd
from torch import nn
from torch.nn import functional as F

class CoNet(nn.Module):
    def __init__(self, n_users, n_source_item, n_target_item, n_factors=80):
        super().__init__()
        self.user_factors = nn.Embedding(n_users + 1, n_factors, sparse=True)
        self.source_item_factors = nn.Embedding(n_source_item + 1, n_factors, sparse=True) #(1, 160)
        self.target_item_factors = nn.Embedding(n_target_item + 1, n_factors, sparse=True) #(1, 160)


        self.source_fc1 = nn.Linear(n_factors * 2, 128) #(160, 128)
        self.target_fc1 = nn.Linear(n_factors * 2, 64) #(160,64)
        self.cross_v1 = nn.Parameter(torch.randn(64, 128)) # (64,128)


        self.source_fc2 = nn.Linear(128, 64)
        self.target_fc2 = nn.Linear(64, 32)
        self.cross_v2 = nn.Parameter(torch.randn(32, 64))

        self.source_fc3 = nn.Linear(64, 32)
        self.target_fc3 = nn.Linear(32, 16)

        self.source_out = nn.Linear(32, 2)
        self.target_out = nn.Linear(16, 2)

    def forward(self, user, source_item, target_item):
        source_embedding = torch.cat((self.user_factors(user), self.source_item_factors(source_item)), 1) # (1,160)
        target_embedding = torch.cat((self.user_factors(user), self.target_item_factors(target_item)) ,1) # (1,160)
        out_source_v1 = F.relu(self.source_fc1(source_embedding) + torch.mm(self.target_fc1(target_embedding), self.cross_v1)) # (1 * 128) + (1 * 64) * (64 * 128)
        out_target_v1 = F.relu(self.target_fc1(target_embedding) + torch.mm(self.source_fc1(source_embedding), torch.t(self.cross_v1))) #(1 * 64) +(1,128) (128, 64)

        out_source_v2 = F.relu(self.source_fc2(out_source_v1) +  torch.mm(self.target_fc2(out_target_v1), self.cross_v2)) #(1,64) + (1, 32) * (32, 64)
        out_target_v2 = F.relu(self.target_fc2(out_target_v1) + torch.mm(self.source_fc2(out_source_v1), torch.t(self.cross_v2)) # (1,32) + (1, 64) * (64, 32)

        out_source = F.relu(self.source_fc3(out_source_v2))
        out_target = F.relu(self.target_fc3(out_target_v2))
    
        out_source = self.source_out(out_source)
        out_target = self.target_out(out_target)
        return out_source, out_target

最后,这里有两个问题论文中并没有提到:
1. CoNet模型在训练的时候使用的是源域和目标域之间的交集数据,那么对于只在源域中出现的用户(或者只在目标域中出现的用户)CoNet是怎么处理的呢?(我个人觉得CoNet比较像DSSM,DSSM是直接喂入0,但是不知道CoNet是怎么做的…)
2. 在使用模型做预测的时候,当我想预测目标域中的用户x是否会有交互行为,我们是否还需要用户在源域中的输入数据呢?(我个人理解是需要的,因为在forward的时候有weight transfer matrix W需要参与计算)如果需要的话,在众多源域用户x信息中,如何选取合适的一条作为输入呢?
在实验里,我是把user的embedding取了平均之后喂进去的,我给作者发了email,但是人家并没有回我……太忙了吧可能。

这篇文章是否对您有帮助?

请您为我打分吧!

平均分数 5 / 5. 投票数量: 2

5 thoughts on “CoNet: Collaborative Cross Networks for Cross-Domain Recommendation(CIKM 2018)

  1. 季皓宣烨 says:

    作者您好
    我最近在做跨域推荐的对比实验的工作,作者关于了这个文章复现的完整代码方便发我一下么?还有能方便推荐几篇关于这个任务的论文么?我邮箱jihaoxuanye@qq.com
    不胜感激
    季皓(郑州大学 信息工程学院)

  2. 根号2加上4 says:

    作者您好,我想请教一下您,在训练的时候,是如何把同个用户的不同商品的数据进行配对的呢?是笛卡尔积的操作吗?遍历所有可能的(源域商品,目标域商品)对?这样会导致数据量激增吧?
    还有就是为什么要把交叉的矩阵设成parameter而不是Linear呢?
    我是上财的一名研究生,目前正在研究这方面的论文,望您抽空解答,谢谢!

    • Dennis says:

      我也想和您分享一些我的思考,有些地方不太成熟,欢迎批评指正:
      1. 对于第一个问题,我觉得这个问题和多视角学习比较像,都是基于用户在多个领域下的样本进行随机匹配喂入模型,笛卡尔操作开销比较大,所以从领域A抽取用户A的一条样本,从领域B抽取用户U的一条样本,进行合成(先采样再合成),如果先合成再采样的话(先进行笛卡尔乘积)这样算法的开销太大了,得不偿失
      2. 第二个问题,我的想法是,首先parameter要比linear具有更好的特征迁移能力。其次矩阵parameter有一个好处就是可以对齐参数,比如领域A的某一个层是(30 * 50), 领域B内的某一层是(40 * 60),那么我只需要用一个(50*60)的矩阵就完成了在两个层之间的参数迁移,这个在编程的时候也很方便 容易被并行化处理(只是多了一次矩阵运算而已)

      不知道我的回答能否让您满意,期待和您的进一步交流

      • 根号2加上4 says:

        十分感谢您的解答,关于第一个问题,模型的输入应该是(用户u,领域A商品a,领域B商品b)这样的三元组,用户应该是一样的。如果我没理解错 您的意思的话,意思就是从领域A用户u交互过的商品中抽样一条,再从领域B用户u交互过的商品中抽样一条,这样组成三元组,然后重复多次构造训练数据,是吗?
        第二个问题我理解了,谢谢您。
        另外,如果可以的话,想学习一下您的复现代码,我的邮箱是1165871724@qq.com,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注