推荐系统中的常用算法——基于Session的推荐

推荐系统中的常用算法——基于Session的推荐

1. 概述

《Session-based recommendations with recurrent neural networks》首次提出将RNN方法应用于Session-based Recommendation。文章中提到当前主流的基于因子分解的模型或者基于邻域的模型很难对整个Session建模,得益于序列化建模算法的发展,使得基于Session的推荐模型成为可能,针对具体的任务,文章中设计了模型的训练以及ranking loss。

2. 算法原理

在文章中采用的GRU(Gated Recurrent Unit)序列化建模算法,这是一种改进的RNN算法,能够较好的解决RNN中的长距离以来问题。在Session-based Recommendation中,将用户登录后产生点击作为RNN的初始状态,基于这个初始状态查询后续是否会点击,其流程大致如下所示:

www.zeeklog.com  - 推荐系统中的常用算法——基于Session的推荐


其中, x 0 \mathbf{x}_0 x0​作为初始状态, h \mathbf{h} h表示RNN的隐藏状态, y ^ \mathbf{\hat{y}} y^​表示输出,由初始状态,可以得到后续的输出。

2.1. GRU

GRU全称为Gated Recurrent Unit,是RNN模型的增强版,能够有效解决RNN模型中的长距离以来问题。在GRU中,输入为前一时刻隐藏层 h t − 1 \mathbf{h}_{t-1} ht−1​和当前输入 x t \mathbf{x}_t xt​,输出为当前时刻隐藏层信息 h t \mathbf{h}_t ht​。GRU中包含两个门,即reset门 r t r_t rt​和update门 z t z_t zt​,其中 r t r_t rt​用来计算候选隐藏层 h ~ \mathbf{\tilde{h}} h~,控制的是保留多少前一时刻隐藏层 h t − 1 \mathbf{h}_{t-1} ht−1​的信息。 z t z_t zt​用来控制加入多少候选隐藏层 h ~ \mathbf{\tilde{h}} h~的信息,从而得到输出 h t \mathbf{h}_{t} ht​。GRU的结构如下图所示:

www.zeeklog.com  - 推荐系统中的常用算法——基于Session的推荐

2.2. 模型结构

通过堆叠多层的GRU,可以实现对用户点击序列的建模,Session-based Recommendation的模型结构如下图所示:

www.zeeklog.com  - 推荐系统中的常用算法——基于Session的推荐


在模型的损失函数方面,文章中采用了pairwise ranking losses,其中pointwise在训练过程中并不稳定。

三种ranking的方式:
  • Pointwise ranking:针对的是单个样本预测得分,典型的如CTR;
  • Pairwise ranking:对样本对的预测,使得正样本正样本的得分要比负样本的小;
  • Listwise ranking:预测的是所有样本的得分,以得到最终的排序;

文中使用了两种基于Pairwise ranking的损失函数:Bayesian Personalized Ranking(BPR)和TOP1,其中BPR是一种矩阵分解的方法,其公式为:

L s = − 1 N s ⋅ ∑ j = 1 N s l o g ( σ ( r ^ s , i − r ^ s , j ) ) L_s=-\frac{1}{N_s}\cdot \sum_{j=1}^{N_s}log\left ( \sigma \left ( \hat{r}_{s,i}-\hat{r}_{s,j} \right ) \right ) Ls​=−Ns​1​⋅j=1∑Ns​​log(σ(r^s,i​−r^s,j​))

其中, N s N_s Ns​是样本量, r ^ s , k \hat{r}_{s,k} r^s,k​是item  k k k的分数, i i i表示session中的正样本, j j j表示负样本。TOP1是一种正则估计的方法,其公式为:

L s = 1 N s ⋅ ∑ j = 1 N s σ ( r ^ s , j − r ^ s , i ) + σ ( r ^ s , j 2 ) L_s=\frac{1}{N_s}\cdot \sum_{j=1}^{N_s}\sigma \left ( \hat{r}_{s,j}-\hat{r}_{s,i} \right )+\sigma \left ( \hat{r}_{s,j}^2 \right ) Ls​=Ns​1​⋅j=1∑Ns​​σ(r^s,j​−r^s,i​)+σ(r^s,j2​)

2.3. 模型训练

在训练的过程中,文中提出了两种策略来提高训练的效率,分别为mini-batch和负样本采样。其中mini-batch的过程如下图所示:

www.zeeklog.com  - 推荐系统中的常用算法——基于Session的推荐


简单来讲就是将多个Session可以进行合并,但是在训练的过程中,在同一个Sequence中遇到下一个Session时,要对GRU重新初始化。

如上,从Session中得到的是正样本,但是训练的过程中不能只存在正样本,此时需要负样本,对于上图中Output中的每一位,通过在样本库中随机采样,生成负样本。

3. 实验的结论

由于我没自己做过实验,在此总结下原作者的几条结论,有待后续在工作中具体验证:

  • 一层的GRU单元效果最好。作者没有给出确定的解释;
  • 直接使用one-hot编码,不使用embedding;
  • 使用上一时刻预测当前时刻,这并不会比使用整个session带来更多提升;
  • 在GRU后面使用前馈层并不会带来提升;
  • 增大GRU的size会提升效果;
  • 在输出层使用tanh激活函数。

参考文献

  • Hidasi B, Karatzoglou A, Baltrunas L, et al. Session-based recommendations with recurrent neural networks[J]. arXiv preprint arXiv:1511.06939, 2015.

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk