【论文标题】Collaborative Memory Network for Recommendation Systems (SIGIR'18)
【论文作者】—Travis Ebesu (Santa Clara University)、—Bin Shen (Google)、—Yi Fang (Santa Clara University)
【论文链接】Paper (10-pages // Double column)
【摘要】
在现代网络平台上,推荐系统对于保持用户对个性化内容的关注起着至关重要的作用。深度学习已经彻底改变了许多研究领域,最近人们对将其应用于协同过滤(CF)的兴趣大增。然而,现有的方法使用隐含因子模型构建深度学习体系结构,忽略了CF模型、邻域或基于内存( memorybased ?)的方法这一大类。我们提出了协同记忆网络(CMN),这是一种利用隐含因子模型的全局结构和基于局部邻域结构的非线性方式将两类CF模型统一起来的深度架构。在记忆网络成功的激励下,我们将记忆组件和神经注意机制融合为邻域组件。[ 记忆模块中与用户和物品记忆的关联寻址方案编码复杂的用户-物品关系,并结合神经注意机制,学习用户-物品特定的邻域。] 最后,输出模块与用户和物品记忆共同利用邻域生成排名分数。将多个记忆模块堆叠在一起可以得到更深层的架构,以捕获日益复杂的用户-物品关系。此外,我们还展示了CMN组件、记忆网络和三类CF模型之间的紧密联系。综合实验结果表明,CMN在三个公共数据集上的有效性优于竞争基线。注意力权重的定性可视化提供了对模型推荐过程的洞察,并建议存在更高阶的交互。
【关键词】
深度学习、记忆网络、协同过滤。
【Reference】
1、推荐系统遇上深度学习(二十九)--协同记忆网络理论及实践:https://www.jianshu.com/p/3e80d8426f7f
2、记忆网络之Memory Networks:https://zhuanlan.zhihu.com/p/29590286
3、记忆网络之End-To-End Memory Networks:https://zhuanlan.zhihu.com/p/29679742
1 介绍】
在信息过载的时代,推荐系统显得十分重要。而在推荐系统中,协同过滤是一种非常受欢迎且有效的方法。协同过滤基于用户和物品的过去交互行为,同时认为相似的用户会消费相似的物品,从而进行推荐。
基于邻域的方法。这也是我们常说的基于物品的协同过滤和基于用户的协同过滤方法。我们首先需要计算用户之间、物品之间的相似度,随后基于计算的相似度进行推荐。这种方法的一个主要缺陷就是只使用了局部的结构,而忽略了很多全局的信息,因为我们只使用K个相似用户或者相似物品进行相关的推荐。比如KNN
基于隐向量的方法。(隐含因子模型)这一分支中最具代表性的是矩阵分解及后面的各种改进方法。通常的做法是将每一个用户和物品表示成一个n维的向量,通过用户矩阵和物品矩阵的相乘,希望能够尽可能还原评分矩阵。这种做法虽然考虑了全局的信息,但是忽略了一些比较强的局部联系。比如MF矩阵分解
基于混合模型的方法。由于上述两种方法都有各自的缺陷,因此混合方法开始出现。结合基于邻域的方法和隐含因子模型来强化预测能力。最具代表性的是因子分解机和SVD++方法。
也就是说,在使用协同过滤这些方法时,我们通常需要关注两点:
1、需要考虑全局的信息,充分利用整个评分矩阵。
2、需要考虑局部的信息,考虑用户或者物品之间的相似性。相似性高的用户或者物品给予更高的权重。
本文将要介绍的协同记忆网络,便是充分利用了上述两方面的信息。协同过滤我们已经介绍了,那么什么是记忆网络呢?我们接下来进行介绍。
2. 记忆网络Memory Network简介
Memory Network是深度学习的一个小分支,从2014年被提出到现在也逐渐发展出了几个成熟的模型。我们这里只介绍其中两个比较基础的模型。一个是 Basic Memory Network,另一个是End to End Memory Network。
我们首先要搞清楚的是,为什么要有记忆网络?在翻译、问答等领域的任务中,我们通常使用的是Seq2Seq结构(是一个Encoder-Deocder结构的模型,输入是一个序列,输出也是一个序列。),由两个循环神经网络组成。传统的深度学习模型、循环神经网络(RNN,LSTM,GRU等)使用hidden states或者Attention机制作为他们的记忆功能,但是这种方法产生的记忆太小了,无法精确记录一段话中所表达的全部内容,也就是在将输入编码成dense vectors的时候丢失了很多信息。因此,在模型中加入一系列的记忆单元,增强模型的记忆能力,便有了Memory Network。
2.1 Basic Memory Network
基本的Memory Network由Facebook在2014年的“Memory Networks”一文中提出。该模型主要包含一系列的记忆单元m(可以看成是一个数组,每个元素保存一句话的记忆)和I,G,O,R四个模块。主要由一个记忆数组m和I,G,O,R四个模块。结构图如下所示:
简单来说,就是输入的文本经过Input模块编码成向量,然后将其作为Generalization模块的输入,该模块根据输入的向量对memory进行读写操作,即对记忆进行更新。然后Output模块会根据Question(也会经过Input模块进行编码)对memory的内容进行权重处理,将记忆按照与Question的相关程度进行组合得到输出向量,最终Response模块根据输出向量编码生成一个自然语言的答案出来。
basic model的实现细节如下:
1) basic model的I模块就是一个简单的embedding lookup操作,也就是将原始文本转化为词向量的形式;
2)G模块则是直接将输入的向量存储在memory数组的下一个位置,不做其他操作,也就是直接写入新的记忆,对老的记忆不做修改。
主要的工作在O和R两个模块进行。
3)O模块根据输入的问题向量在所有的记忆中选择出top-K相关的记忆,具体选择方式为,先选记忆中最相关的memory:
接下来根据选择出的o1和输入x一起选择与他们两个最相关的记忆o2:
(对于上面这个等式,如果x和o1采用的都是线性的向量表示(BOW等),则可以拆分成下面加和的方式,否则不可以。
)
就这样选择出于Question最相关的top-K个memory slot即可。将其作为
4)R模块的输入,用于生成最终的答案。
其实这里也很简单就是使用与上面相同的评分函数计算所有候选词与R输入的相关性,得分最高的词语就作为正确答案输出即可:
而上面多次用到的评分函数满足下面的形式即可:
最终模型选择margin ranking loss作为损失函数,即要求正确答案的得分比错误答案的得分高至少一个margin r。公式如下:
这里的错误答案都是随机从样本中采样而来,而不是计算所有错误样本。下面我们举一个简单的例子来说明上述过程:
对于第一个问题:where is the milk now?输出模块会对所有的memory(其实就是输入的句子)进行评分,得到“Joe left the milk。”得分最高,也就是与问题最相关,然后再对剩下的记忆进行评分,找出与where is the milk now?和Joe left the milk最相关的memory。我们发现是“Joe travelled to the office”。这样我们就找到了最相关的记忆,接下来使用R模块对所有的单词进行评分找到得分最高的单词作为答案即可。
(这篇论文的重点在于他提出了一种普适性的模型架构(Memory Network),但是很多部分并没有做得很完善,论文后面也对输入是词、memory比较大、新词等问题进行了专门的阐述,不过我觉得看后面别人在此基础上发的论文更有借鉴意义。所以这里不再进行详细的介绍。)
2.2 End to End Memory Network
End to End Memory Network是Memory Network的一个改进版本,可以进行端对端的学习。原文中介绍的网络模型应用于QA任务。
这是Facebook AI在Memory networks之后提出的一个更加完善的模型,前文中我们已经说到,其I和G模块并未进行复杂操作,只是将原始文本进行向量化并保存,没有对输入文本进行适当的修改就直接保存为memory。而O和R模块承担了主要的任务,但是从最终的目标函数可以看出,在O和R部分都需要监督,也就是我们需要知道O选择的相关记忆是否正确,R生成的答案是否正确。这就限制了模型的推广,太多的地方需要监督,不太容易使用反向传播进行训练。因此,本文提出了一种end-to-end的模型,可以视为一种continuous form的Memory Network,而且需要更少的监督数据便可以进行训练。论文中提出了单层和多层两种架构,多层其实就是将单层网络进行stack。
我们先来看一下单层模型的架构:
单层 Memory Networks
单层网络的结构如下图所示,主要包括下面几个模块:
模型主要的参数包括A,B,C,W四个矩阵,其中A,B,C三个矩阵就是embedding矩阵,主要是将输入文本和Question编码成词向量,W是最终的输出矩阵。从上图可以看出,对于输入的句子s分别会使用A和C进行编码得到Input和Output的记忆模块,Input用来跟Question编码得到的向量相乘得到每句话跟q的相关性,Output则与该相关性进行加权求和得到输出向量。然后再加上q并传入最终的输出层。接下来详细介绍一下各个模块的原理和实现(这里跟论文中的叙述方式不同,按照自己的理解进行介绍)。
首先是输入模块(对应于Memory Networks那篇论文的I和G两个组件),这部分的主要作用是将输入的文本转化成向量并保存在memory中,本文中的方法是将每句话压缩成一个向量对应到memory中的一个slot(上图中的蓝色或者黄色竖条)。其实就是根据一句话中各单词的词向量得到句向量。论文中提出了两种编码方式,BoW和位置编码。
BoW就是直接将一个句子中所有单词的词向量求和表示成一个向量的形式,这种方法的缺点就是将丢失一句话中的词序关系,进而丢失语义信息;
而位置编码的方法,不同位置的单词的权重是不一样的,然后对各个单词的词向量按照不同位置权重进行加权求和得到句子表示。位置编码公式如下:lj就是位置信息向量(这部分可以参考我们后面的代码理解)。
此外,为了编码时序信息,比如Sam is in the bedroom after he is in the kitchen。我们需要在上面得到mi的基础上再加上个矩阵对应每句话出现的顺序,不过这里是按反序进行索引。将该时序信息编码在Ta和Tc两个矩阵里面,所以最终每句话对应的记忆mi的表达式如下所示:
输出模块
上面的输入模块可以将输入文本编码为向量的形式并保存在memory中,这里分为Input和Output两个模块,一个用于跟Question相互作用得到各个memory slot与问题的相关程度,另一个则使用该信息产生输出。
首先看第一部分,将Question经过输入模块编码成一个向量u,与mi维度相同,然后将其与每个mi点积得到两个向量的相似度,在通过一个softmax函数进行归一化:
pi就是q与mi的相关性指标。然后对Output中各个记忆ci按照pi进行加权求和即可得到模型的输出向量o。
Response模块
输出模块根据Question产生了各个memory slot的加权求和,也就是记忆中有关Question的相关知识,Response模块主要是根据这些信息产生最终的答案。其结合o和q两个向量的和与W相乘再经过一个softmax函数产生各个单词是答案的概率,值最高的单词就是答案。并且使用交叉熵损失函数做为目标函数进行训练。
多层 Memory Networks
多层记忆网络模型,其实就是将多个单层模型进行stack在一块。这里成为hop。其结构图如下所示:
首先来讲,上面几层的输入就是下层o和u的和。至于各层的参数选择,论文中提出了两种方法(主要是为了减少参数量,如果每层参数都不同的话会导致参数很多难以训练)。
1. Adjacent:这种方法让相邻层之间的A=C。也就是说Ak+1=Ck,此外W等于顶层的C,B等于底层的A,这样就减少了一半的参数量。
2. Layer-wise(RNN-like):与RNN相似,采用完全共享参数的方法,即各层之间参数均相等。Ak=...=A2=A1,Ck=...=C2=C1。由于这样会大大的减少参数量导致模型效果变差,所以提出一种改进方法,即令uk+1=Huk+ok,也就是在每一层之间加一个线性映射矩阵H。
【本文主要贡献】
1) 基于记忆网络的成功经验,我们提出了一种解决隐式协同过滤问题的协同记忆网络(CMN)。CMN增强了外部记忆和神经注意力机制。记忆模块的关联寻址方案作为识别相似用户的最近邻模型。该注意力机制根据特定的用户和物品学习用户邻域的自适应非线性加权。输出模块利用自适应邻域状态与用户、物品记忆之间的非线性相互作用,推导出推荐值。
2)我们揭示了CMN与两类重要的协同过滤模型之间的联系:隐含因子模型和基于邻域的相似度模型。进一步,我们揭示了非线性积分融合两种模型的优点,得到了一个混合模型。
3)在三个公共数据集上的综合实验证明了CMN在七个对比基线上的有效性。多个实验配置证实了记忆模块的额外好处。
4)注意力权重的定性可视化提供了对记忆组件的深入了解,为更深层次的体系结构捕获更高阶的复杂交互提供了支持证据。
【2 相关工作】
【2.1 推荐系统中的深度学习】