Press "Enter" to skip to content

基于RNN的序列化推荐系统总结

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

作者 | 阳光明媚

 

单位 | 华东师范大学

 

方向 | 推荐系统

 

本文介绍两篇基于RNN的用户序列行为建模的经典论文,原文地址:

 

1. Session-based Recommendations with Recurrent Neural Networks

 

https://arxiv.org/abs/1511.06939

 

2. Parallel Recurrent Neural Network Architectures for Feature-rich Session-based Recommendations

 

http://www.hidasi.eu/content/p__recsys16.pdf

 

Session-based Recommendations with Recurrent Neural Networks

 

本文首次将RNN引入了用户序列行为的建模,并取得了显着的效果提升。

 

解决的关键问题:

 

为了使得推荐系统能够学习用户的序列决策数据,引入一个排序损失函数,并用RNN模型来建模稀疏的序列决策数据。

 

挑战:

 

在序列化推荐的每一步,待选的物品数目巨大,在万到十万级别

 

点击流数据量大

 

关心模型对用户可能感兴趣的top物品的预测能力

 

模型结构与算法细节:

模型的输入是会话的状态,具体的可以是事件中的物品的one-hot编码(1-of-N encoding),或者会话的历史事件的表示的加权和(给较早的时间较低的权重)。出于稳定性考虑,给输入向量做正则化,因为这可以强化局部的顺序约束,而这不容易被RNN的长期记忆捕获。(为什幺正则化可以强化局部顺序约束?怎幺正则化的?)作者还实验了用一层embedding layer来做编码,但1-of-N encoding效果总是更好。

 

网络结构主要就是多层的GRU和用于输出结构的前向传播层。多层的GRU中,上一层的隐状态作为下一层的输入。输入也可以选择去连接到网络中更深的GRU层,作者发现这样效果更好。

 

Session-parallel mini-batches

 

用户序列数据与NLP序列数据做的任务不同,NLP中的mini-batch会用一个滑动窗口来选择句子中的单词,预测其他单词,mini-batch中的每一个元素对应一个滑动窗口;但是对于用户序列数据我们更想要建模用户的长期行为,因此不能用NLP中的这种方式来做mini-batch。文中提出了一种用于用户序列行为数据建模的mini-batch组织方式:

上图展示了batch_size为3的情况,3个session的序列数据同时进入模型,但是每个session的长短可能不同,当batch中某个session已经全部进入网络时,马上接替一个新的session。如图中右侧的input所示,第2行的session最短,只有2个event,第2个event结束之后马上接上第4个session序列,所以i2,2后面跟的是i4,1。

 

Sampling on the output

 

由于物品的数目巨大,不可能对每个物品都计算分数,因此对输出进行采样,只计算一小部分物品的分数,也就是负采样。

 

对于一个session中作为结束的event,一般的解释是用户根本不知道event中的物品的存在,因而没有交互。用户知道这个物品,但是因为不喜欢而去不交互的概率很低。物品越流行,用户越可能了解这个物品,因此作为结束的事件如果包含了这个物品,那很可能说明用户真的不喜欢这个物品。因此我们会根据流行度作为权重来采样物品,而不是为每个训练样例分别采样一些物品,我们使用来自其他mini-batch的训练样例作为负样本。这种方法的好处是我们可以通过跳过采样来进一步降低计算负担。此外,在实现方面,从降低代码复杂度到加快矩阵操作也有好处。同时,该方法也是一种基于流行度的抽样方法,因为一个项目出现在小批量的其他训练示例中的可能性与其流行度成正比。

 

Ranking loss

 

推荐系统的核心是基于相关性对物品排序,为了在序列化推荐中实现这一点,需要选择合适的排序损失函数。排序的学习方式通常有以下三种:

 

 

Pointwise排序估计彼此独立的项目的得分或排名,损失的定义方式应使相关项目的排名较。

 

Pairwise排序比较一个正项目和一个负项目的得分或成对的排名,损失强制要求正项目的排名应低于负项目的排名。

 

Listwise排序使用所有项目的分数和等级,并将它们与完美顺序进行比较。由于它包括排序,通常计算成本更高,因此不经常使用。此外,如果只有一个相关的项目-在我们的案例中-listwise排序可以通过pairwise排序解决。

 

 

作者采用了多种排序损失函数,发现pointwise的损失函数表现不稳定,pairwise的表现更好,文章列出了两种pairwise损失函数:

论文的模型部分到这里就结束了,下面看一下执行细节与实验部分

 

代码地址:

 

https://github.com/yhs968/pyGRU4REC

 

用GRU对输入建模:

 

# reset the hidden states if some sessions have just terminated
hidden = reset_hidden(hidden, mask).detach()
# Go through the GRU layer
logit, hidden = self.gru(input, target, hidden)
# Output sampling
logit_sampled = logit[:, target.view(-1)]
# Calculate the mini-batch loss
loss = self.loss_fn(logit_sampled)

 

模型直观且简单,这里reset_hidden是用于处理batch中结束的session,处理方式就是把对应的hidden_state置为0。GRU的输入是数据和上一层的hidden_state,但在示例代码中,仅使用了一层的GRU。

 

Top1 Loss的计算:

 

def TOP1Loss(logit):
    """
    Args:
        logit (BxB): Variable that stores the logits for the items in the session-parallel mini-batch.
                     Negative samples for a specific item are drawn from the other items in the
                     session-parallel minibatch, as mentioned in the original GRU4REC paper.
                     The first dimension corresponds to the batches, and the second dimension
                     corresponds to sampled number of items to evaluate.
    """
    # differences between the item scores
    diff = -(logit.diag().view(-1, 1).expand_as(logit) - logit)
    # final loss
    loss = F.sigmoid(diff).mean() + F.sigmoid(logit ** 2).mean()
    return loss

 

在session中的每一个event,模型预测下一个event的物品排序列表。评价指标采用了[email protected][email protected],MRR是Mean Reciprocal Rank,计算方式为:

 

 

一个正确物品如果被排到了20名开外,记为0分。

 

baseline选择了基于流行度的推荐,和基于物品相似度的推荐:

实验效果部分,可以看到提升非常显着:

Parallel recurrent neural network architectures for feature-rich session-based recommendations

 

在上文的基础上,本文考虑了用户行为序列中的更多信息,诸如图像、文本,并设计了新的基于RNN的网络模型parellel-RNN,来利用这些信息。有了上文的基础,这里直接介绍本文相对于上文的修改。

上图展示了文中所提出的几种融合特征信息的RNN结构,分成两行:

 

第一行的模型分别为:只考虑ID输入,ID与图像拼接输入,ID与图像分别输入且并行训练

 

第二行的模型分别为:只考虑图像输入,ID与图像分别输入且并行训练但是彼此的网络之间有交互,ID与图像分别输入且共享参数矩阵

 

但是分别处理诸如ID与图像特征时,由于学习的目标不同,两部分的网络不能同时训练,因此文中提出了几种交替训练的方式:

 

 

Simultaneous:所有参数同时进行训练,用作baseline。

 

Alternating:每个epoch只训练一个特征的网络,其他特征对应的网络参数固定,循环进行,例如:第一次训练ID网络,第二次图像网络,第三次ID网络…….

 

Residual:每个网络分支依次训练,但是不会循环,每个网络分支的单次训练长度比Alternating要长,比如ID网络训练10个epoch,接着feature网络基于前面ID网络的参差训练10个epoch。每个网络分支基于之前训练过的网络分支的residual error的ensemble进行训练。

 

Interleaving:对于每个mini-batch,在网络分支间交替进行如下训练:第一个子网络正常训练,第二个子网络基于当前mini-batch在当前网络的残差训练。更为频繁的交替训练能使得网络之间的训练更为平衡,且这样做没有了同步训练的缺点。

 

 

在与Item-KNN的对比试验中,发现Feature-Only(只使用图像特征)的网络竟然不如对方,而ID-Only就已经效果提升很多,说明仅使用图像特征可能无法很好地表示物品。另外第四行,两种信息特征拼接之后的效果,也不如ID-Only,说明单层的GRU无法很好的区别这两种拼接的特征。

上面的实验结果说明复杂的网络结构没有得到很好地利用,因此作者又做了Parallel网络的实验:

 

这次采用了更大的隐藏层,实验效果也有了明显提升。而且此时Feature-Only的网络也终于超过了baseline。同时,Parallel(int)网络也取得了最佳的效果,证明了这种利用了更加丰富的信息的RNN-based的模型结构的有效性。

Be First to Comment

发表评论

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