个性化排序的神经协同过滤

Neural Collaborative Filtering for Personalized Ranking

这一部分将超越显式反馈,介绍神经协作过滤(NCF)框架,用于推荐具有隐式反馈。隐式反馈在推荐系统中普遍存在。诸如点击、购买和观看等行为都是常见的隐性反馈,这些反馈很容易收集并指示用户的偏好。我们将介绍的模型名为NeuMF[He et al.,2017b],是神经矩阵分解的缩写,旨在解决带有隐式反馈的个性化排名任务。该模型利用神经网络的灵活性和非线性,代替矩阵分解的点积,提高模型的表达能力。具体地说,该模型由广义矩阵分解(GMF)和多层感知器(MLP)两个子网络构成,用两条路径来模拟相互作用,而不是简单的内积。将这两个网络的输出连接起来,以计算最终的预测分数。与AutoRec中的评分预测任务不同,该模型基于隐含反馈为每个用户生成一个排名推荐列表。我们将使用最后一节介绍的个性化排名损失来训练这个模型。

  1. The NeuMF model

如上所述,NeuMF融合了两个子网。GMF是矩阵分解的一种神经网络模型,输入是用户和项目潜在因素的元素乘积。它由两个神经层组成:

这个模型的另一个组件是MLP。为了增加模型的灵活性,MLP子网不与GMF共享用户和项嵌入。它使用用户和项嵌入的连接作为输入。通过复杂的连接和非线性变换,它能够模拟用户和物品之间的复杂交互。更准确地说,MLP子网定义为:


Fig. 1 Illustration of the NeuMF model

from d2l import mxnet as d2l

from mxnet import autograd, gluon, np, npx

from mxnet.gluon import nn

import mxnet as mx

import random

import sys

npx.set_np()

  1. Model
    Implementation

下面的代码实现了NeuMF模型。它由一个广义矩阵分解模型和一个具有不同用户和项目嵌入向量的多层感知器组成。MLP的结构由参数nums_hiddens控制。ReLU用作默认激活功能。

class NeuMF(nn.Block):

def __init__(self, num_factors, num_users, num_items, nums_hiddens,**kwargs):super(NeuMF, self).__init__(**kwargs)self.P = nn.Embedding(num_users, num_factors)self.Q = nn.Embedding(num_items, num_factors)self.U = nn.Embedding(num_users, num_factors)self.V = nn.Embedding(num_items, num_factors)self.mlp = nn.Sequential()for num_hiddens in nums_hiddens:self.mlp.add(nn.Dense(num_hiddens, activation='relu',use_bias=True))def forward(self, user_id, item_id):p_mf = self.P(user_id)q_mf = self.Q(item_id)gmf = p_mf * q_mfp_mlp = self.U(user_id)q_mlp = self.V(item_id)mlp = self.mlp(np.concatenate([p_mlp, q_mlp], axis=1))con_res = np.concatenate([gmf, mlp], axis=1)return np.sum(con_res, axis=-1)
  1. Customized Dataset with Negative Sampling

对于成对排序损失,一个重要的步骤是负采样。对于每个用户,用户未与之交互的项是候选项(未观察到的条目)。下面的函数以用户身份和候选项作为输入,并从每个用户的候选项集中随机抽取负项。在训练阶段,该模型确保用户喜欢的项目的排名高于其不喜欢或未与之交互的项目。

class PRDataset(gluon.data.Dataset):

def __init__(self, users, items, candidates, num_items):self.users = usersself.items = itemsself.cand = candidatesself.all = set([i for i in range(num_items)])def __len__(self):return len(self.users)def __getitem__(self, idx):neg_items = list(self.all - set(self.cand[int(self.users[idx])]))indices = random.randint(0, len(neg_items) - 1)return self.users[idx], self.items[idx], neg_items[indices]
  1. Evaluator

在这一部分中,我们采用按时间分割的策略来构造训练集和测试集。给定截线命中率的两个评价指标ℓℓ (Hit@ℓHit@ℓ) and area
under the ROC curve (AUC),用ROC曲线下面积(AUC)评价模型的有效性。给定位置命中率ℓ,对于每个用户,指示建议的项目是否包含在顶部ℓ排行榜。正式定义如下:

#@save

def hit_and_auc(rankedlist, test_matrix, k):

hits_k = [(idx, val) for idx, val in enumerate(rankedlist[:k])if val in set(test_matrix)]hits_all = [(idx, val) for idx, val in enumerate(rankedlist)if val in set(test_matrix)]max = len(rankedlist) - 1auc = 1.0 * (max - hits_all[0][0]) / max if len(hits_all) > 0 else 0

return len(hits_k), auc

然后,总体命中率和AUC计算如下。

#@save

def evaluate_ranking(net, test_input, seq, candidates, num_users, num_items,

                 ctx):ranked_list, ranked_items, hit_rate, auc = {}, {}, [], []all_items = set([i for i in range(num_users)])for u in range(num_users):neg_items = list(all_items - set(candidates[int(u)]))user_ids, item_ids, x, scores = [], [], [], [][item_ids.append(i) for i in neg_items][user_ids.append(u) for _ in neg_items]x.extend([np.array(user_ids)])if seq is not None:x.append(seq[user_ids, :])x.extend([np.array(item_ids)])test_data_iter = gluon.data.DataLoader(gluon.data.ArrayDataset(*x),shuffle=False,last_batch="keep",batch_size=1024)for index, values in enumerate(test_data_iter):x = [gluon.utils.split_and_load(v, ctx, even_split=False)for v in values]scores.extend([list(net(*t).asnumpy()) for t in zip(*x)])scores = [item for sublist in scores for item in sublist]item_scores = list(zip(item_ids, scores))ranked_list[u] = sorted(item_scores, key=lambda t: t[1], reverse=True)ranked_items[u] = [r[0] for r in ranked_list[u]]temp = hit_and_auc(ranked_items[u], test_input[u], 50)hit_rate.append(temp[0])auc.append(temp[1])return np.mean(np.array(hit_rate)), np.mean(np.array(auc))
  1. Training and Evaluating the Model

培训功能定义如下。我们以成对的方式训练模型。

#@save

def train_ranking(net, train_iter, test_iter, loss, trainer, test_seq_iter,

              num_users, num_items, num_epochs, ctx_list, evaluator,candidates, eval_step=1):timer, hit_rate, auc = d2l.Timer(), 0, 0animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0, 1],legend=['test hit rate', 'test AUC'])for epoch in range(num_epochs):metric, l = d2l.Accumulator(3), 0.for i, values in enumerate(train_iter):input_data = []for v in values:input_data.append(gluon.utils.split_and_load(v, ctx_list))with autograd.record():p_pos = [net(*t) for t in zip(*input_data[0:-1])]p_neg = [net(*t) for t in zip(*input_data[0:-2],input_data[-1])]ls = [loss(p, n) for p, n in zip(p_pos, p_neg)][l.backward(retain_graph=False) for l in ls]

l += sum([l.asnumpy() for l in ls]).mean()/len(ctx_list)

        trainer.step(values[0].shape[0])metric.add(l, values[0].shape[0], values[0].size)timer.stop()with autograd.predict_mode():if (epoch + 1) % eval_step == 0:hit_rate, auc = evaluator(net, test_iter, test_seq_iter,candidates, num_users, num_items,ctx_list)animator.add(epoch + 1, (hit_rate, auc))print('train loss %.3f, test hit rate %.3f, test AUC %.3f'% (metric[0] / metric[1], hit_rate, auc))print('%.1f examples/sec on %s'% (metric[2] * num_epochs / timer.sum(), ctx_list))

现在,我们可以加载MovieLens
100k数据集并训练模型。由于在MovieLens数据集中只有评级,但准确性会有所下降,因此我们将这些评级进行二值化,即0和1。如果一个用户对一个项目进行评分,我们认为隐含反馈为1,否则为零。给一个项目评分的行为可以看作是一种提供隐性反馈的形式。在这里,我们在seq感知模式下分割数据集,在这种模式下,用户的最新交互项被排除在外进行测试。

batch_size = 1024

df, num_users, num_items = d2l.read_data_ml100k()

train_data, test_data = d2l.split_data_ml100k(df, num_users, num_items,

                                          'seq-aware')

users_train, items_train, ratings_train, candidates = d2l.load_data_ml100k(

train_data, num_users, num_items, feedback="implicit")

users_test, items_test, ratings_test, test_iter = d2l.load_data_ml100k(

test_data, num_users, num_items, feedback="implicit")

num_workers = 0 if sys.platform.startswith(“win”) else 4

train_iter = gluon.data.DataLoader(PRDataset(users_train, items_train,

                                         candidates, num_items ),batch_size, True,last_batch="rollover",num_workers=num_workers)

然后我们创建并初始化模型。我们使用一个三层MLP,隐藏大小恒定为10。

ctx = d2l.try_all_gpus()

net = NeuMF(10, num_users, num_items, nums_hiddens=[10, 10, 10])

net.initialize(ctx=ctx, force_reinit=True, init=mx.init.Normal(0.01))

下面的代码训练模型。

The following code trains the model.

lr, num_epochs, wd, optimizer = 0.01, 10, 1e-5, ‘adam’

loss = d2l.BPRLoss()

trainer = gluon.Trainer(net.collect_params(), optimizer,

                    {"learning_rate": lr, 'wd': wd})

train_ranking(net, train_iter, test_iter, loss, trainer, None, num_users,

          num_items, num_epochs, ctx, evaluate_ranking, candidates)

train loss 4.030, test hit rate 0.322, test AUC 0.736

13.1 examples/sec on [gpu(0), gpu(1)]

6. Summary

· Adding nonlinearity to matrix factorization model is beneficial for improving the model capability and effectiveness.

· NeuMF is a combination of matrix factorization and Multilayer perceptron. The multilayer perceptron takes the concatenation of user and item embeddings as the input.

个性化排序的神经协同过滤相关推荐

  1. FedNCF:Federated Neural Collaborative Filtering | 联邦神经协同过滤

    论文信息 标题:FedNCF: Federated Neural Collaborative Filtering 作者:Vasileios Perifanis ∗ ^* ∗, Pavlos S. Ef ...

  2. 计算机系统应用的书,基于个性化图书推荐的协同过滤算法

    摘 要本文对基于个性化图书推荐的协同过滤算法的设计方案进行实验,目的是为证实在真实用户的多标准评估过程中怎样产生数据集,从而找到一种科学的算法.并通过图书推荐的应用案例来说明算法,以验证其是否有效. ...

  3. 【科研导向】Outer Product-based Neural Collaborative Filtering (ConvNCF)基于外积的神经协同过滤<论文理解代码分析>

    Outer Product-based Neural Collaborative Filtering--IJCAI'18 文章简介 一.摘要解析 二.技术要点 三.实验部分 代码解析 一.模型构建 二 ...

  4. 【科研导向】Neural Collaborative Filtering 神经协同过滤 <论文理解代码分析>

    Neural Collaborative Filtering--WWW'17 文章简介 一.摘要解析 二.技术要点 三.实验部分 代码解析 一.模型构建 二.难点问题 未来展望 文章简介 该文由何向南 ...

  5. 神经协同过滤Neural Collaborative Filtering(NCF)

    Neural Collaborative Filtering 简述 矩阵分解(MF) NCF 1.GMF 广义矩阵分解 2.MLP(多层感知机) 3.NeuMF 实验 简述 这篇论文是何向南博士所写 ...

  6. 浅析神经协同过滤NCF在推荐系统的应用

    NCF在推荐领域应用背景 CF,也就是协同过滤,在推荐领域有极其广泛的应用,应该没有谁的智能推荐系统是没用到过CF的.CF其实就是挖掘user和item的交互关系,然后生成I2I或者U2I表示向量.传 ...

  7. ncf 推荐系统_浅析神经协同过滤NCF在推荐系统的应用

    NCF在推荐领域应用背景 CF,也就是协同过滤,在推荐领域有极其广泛的应用,应该没有谁的智能推荐系统是没用到过CF的.CF其实就是挖掘user和item的交互关系,然后生成I2I或者U2I表示向量.传 ...

  8. 推荐系统遇上深度学习(十一)--神经协同过滤NCF原理及实战

    阅读时间 大约10分钟. Neural Collaborative Filterring 1.1 背景 本文讨论的主要是隐性反馈协同过滤解决方案,先来明确两个概念:显性反馈和隐性反馈: 显性反馈行为包 ...

  9. python基于用户行为和内容的个性化新闻推荐系统 基于协同过滤算

    关注公众号,回复:python基于用户行为和内容的个性化新闻推荐系统,获取源码,百度云哦

最新文章

  1. 设计模式之状态模式(State)摘录
  2. 如何知道当前像素的顶点坐标_GT 大神 | 如何高效渲染流体效果(绝对干货)
  3. 开源是如何让Android成为移动市场大佬的?
  4. 关于Keil4 转到 Keil5以后的一些错误解决
  5. PDF文件能编辑吗,怎么删除PDF文档中的空白页
  6. Java在W10_java——基础 在w10环境下如何配置java环境
  7. Skype国际版使用国内卡
  8. xshell官方个人免费版申请下载使用
  9. JSP页面乱码的几种解决方案
  10. html通过拼音首字母定位,input+div 实现输入拼音首字母或汉字自动检索上拉列表...
  11. 迅捷CAD编辑器剪切框架工具具体使用方法
  12. 我奋斗了18年还是不能和你坐在一起喝咖啡
  13. 启动docker时映射到宿主机时出现 usrbindocker-current Error response from daemon driver failed
  14. 题解 P2212 【[USACO14MAR]浇地Watering the Fields】
  15. github Dns 污染
  16. Java实现最近点问题
  17. 大学的终结,终结了什么???
  18. 【密码学探秘】EVM链和并行执行交易
  19. 运维标准化与流程化建设深度指南(转)
  20. Cognos BI交流群共享资料整理

热门文章

  1. libACE-6.3.3.so: cannot open shared object file: No such file or directory
  2. 判断两个树是否相等和判断tree1是否包含tree2 python实现
  3. hadoop,spark,scala,flink 大数据分布式系统汇总
  4. pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法
  5. 使用最新版(2020)IntelliJ IDEA 创建Servlet项目
  6. LeetCode简单题之整数的各位积和之差
  7. LeetCode简单题之图片平滑器
  8. 计算机视觉一些项目实战技术
  9. Keras神经网络集成技术
  10. [JS][编程题]括号匹配