DeepRecommender:基于自编码器的协同过滤(Collaborative Filtering),英伟达论文选读及其pytorch实现

有时候,读读工程类的文章,虽然简单,但是能看到别人踩过的坑用过的tricks,也是挺有意思。NVIDIA不久前放出的协同过滤新标杆DeepRecommender Netfix 2009年的netflixprize竞赛数据为基准,使用基于自编码器协同过滤,准确率比普通模型都高。

netflixprize竞赛目标非常简单,预测一个用户对一部影片评分的可能值(Netflix要推荐用户最感兴趣的影片来赚钱,不是吗?)事实上,评价竞赛分数的loss函数也很简单,是一个均方误差:ri是真实评分yi是模型预测评分mi是一个外加的mask控制项,如果真实评分ri=0,那mi=0,否则mi就可以等于1.

很显然这是一个协同过滤问题。用户A看过的电影是那么有限,以至于把所有Netflix电影库中的电影拿出来做个list,这个人评估分的影片是那么少,从而这个list的那么稀疏但是。。。我们Netflix是大公司,有辣么多用户,根据类似用户,我们就能为用户A把那长长的一串空list填满了(填的好不好就看你model啦)

而英伟达用的DeepRecommender告诉我们,以前的协同过滤方法太low了,看看我们用DL自编码器的效果:

来自:https://arxiv.org/pdf/1708.01715.pdf

RMSE指标和MMSE指标转换只是加了一个根号:RMSE=√MMSE。

关键是,自编码器是端到端的,更容易训练:

这里自编码器输入是某个用户稀疏的电影评分list,输出是这个用户所有的电影评分预测。只要模型第一次对第一个用户的预测产生dense的电影list评分,对其它用户的误差就产生了(因为其它用户评分的是另一些电影)

来看看文章用的自编码器架构:

其中输入和输出的n指的都是电影list的长度(应该是很长一串)。之后的128,256,256,256,128都是各层的输出,可见这些网络都是6层的自编码器。

dp是dropout的缩写,这引出了文章提出的第一个Trick 加大Dropout的比例。文章自编码器的dropout比较特殊,不仅仅是它使用在中间层,而且它的dropout比例如此之大(0.8)。可见中间层压缩的信息是如此密集,以至于dropout多数的单元都毫无关系(还能提高泛化能力)。

另外文章告诉我们用带有负值的激活函数也相当重要:

此外,文章还提出协同过滤特有的Dense re-feeding的Trick。DeepRecommender把预测出来f(x)重新塞到自编码器中作为新的样本预测f(f(x)) ,  结果应该和f(x) 一致,这种奇特的验证方式,或者说数据增强方式也帮助防止了过拟合(通过稍微增大learning rate的方式):

来自:https://arxiv.org/pdf/1708.01715.pdf

最后,文章还给出了项目源码:https://github.com/NVIDIA/DeepRecommender

参考文献:

  1. Training Deep AutoEncoders for Collaborative Filtering
  2. https://github.com/NVIDIA/DeepRecommender

本文采用署名 – 非商业性使用 – 禁止演绎 3.0 中国大陆许可协议进行许可。著作权属于“David 9的博客”原创,如需转载,请联系微信: david9ml,或邮箱:yanchao727@gmail.com

或直接扫二维码:

发布者

David 9

邮箱:yanchao727@gmail.com 微信: david9ml

发表回复

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