本文主要讲YouTube在2016年发表的《Deep Neural Networks for YouTube Recommendations》,这篇文章按照今天的标准来说没什么新颖的地方,但是这篇论文几乎处处是套路,处处是经验,不由惊为神文,字字珠玑。对推荐入门有一个很好的铺垫
下面为系统的整体架构
image.png
读论文的时候,很多时候都是冲着算法的架构去的,这边文章架构并无奇妙的地方,主要贡献在工程师对特征的处理。Youtube拥有全球最大的视频库,需要在百万级的视频库下进行个性化推荐。由于候选集非常之大,考虑online系统延时的问题,不易使用过于复杂的神经网络进行推荐,所以YouTube采用了两层的神经网络来完成整体的推荐过程。

  1. 召回。第一层是Candidate Generation Model 完成候选视频的快速筛选,这一步把候选视频从百万级别降低到百的数量级。
  2. 排序。第二层用的是Ranking Model 对几百个召回的数据集进行精排。

    召回

    下面首先介绍召回部分的Candidate Generation Model :
    image.png
    从下往上看,最底层是的输入包括:用户看过的video的embedding向量,用户搜索词的embedding向量。至于这些embedding是怎么生成的,作者是这样说的
    image.png
  • 作者是用word2vec的方法对video和search token做了embedding,然后再作为输入的。当然还有另外一种操作,就是通过加一个embedding层然后跟上面的DNN层一起训练
  • 特征向量里还包括了用户的地理位置的embedding、年龄、性别等信息。然后把这些信息concatenate起来,一起喂给上层的Relu神经网络。
  • 三层神经网络以后是softmax函数,这里YouTube的工程师把这个问题看做是用户推荐next watch的问题,所以输出应该是一个在所有candidate video上的概率分布,一个多分类的问题。

对于这些步骤,难免会产生一些问题,比如

  1. 架构图的左上角,为什么在online serving的时候不直接用这个神经网络来进行预测,而是采用nearest neighbor search的方法?
  2. 在多分类问题中,Youtube的candidate有百万之多,也就是说有百万个分类,这回严重影响训练的效果和速度,该如何改进?

    排序

    image.png
    乍一看,ranking model 和candidate model 没什么区别,主要的区别就是特征工程部分
    实际论文里也明确说明了,引入另外一套DNN作为ranking model 的目的就是为了引入更多描述视频、用户以及二者之间关系的特征,达到对候选视频集合准确排序的目的。
    image.png
    具体介绍一下输入的特征如下:

  3. impression video ID embedding: 当前要计算的video的embedding

  4. watched video IDs average embedding: 用户观看过的最后N个视频embedding的average pooling
  5. language embedding: 用户语言的embedding和当前视频语言的embedding
  6. time since last watch: 自上次观看同channel视频的时间
  7. #previous impressions: 该视频已经被曝光给该用户的次数

下面重点说一下第4个和第5个特征,这俩个特征加入了对用户行为的观察
第4个特征
image.png
有一些引入attention的意思,这里是用time since last watch 这个特征来反映用户看同类视频的间隔时间。从用户的角度出发,加入我们刚看了”LOL比赛”这个channel的视频,我们很大的概率还是会继续看这个channel的视频,那么该特征就能很好的捕捉用户这一行为信息。
第5个特征
#previous impressions 一定程度上引入了exploration的思想,避免同一个视频持续对同一用户进行无效的曝光。尽量增加用户没看过的新视频曝光的可能性。
到这里论文基本就结束了,如果读完这篇论文你的收获只有这些,那么你只抓住了30%的价值!!!!!!

问题汇总

剩下的70%,将体现在下面的问题里
1、文中把推荐问题转换成多分类问题,在next watch的场景下,每一个备选video都会是一个分类,因此总共的分类有数百万之巨,这在使用softmax训练时无疑是低效的,这个问题Youtube是如何解决的?
采用负采样(negative sampling)并用importance weighting的方法对采样进行calibration。文中还介绍了另外一种方法,hierarchical softmax,但是没有取得很好的效果。对于采样的具体技术细节以及好坏,感兴趣的同学可以参考下tensorflow中的介绍https://www.tensorflow.org/extras/candidate_sampling.pdf,以及NLP经典的论文https://www.aclweb.org/anthology/P15-1001.pdf
2、在candidate generation model的serving过程中,Youtube为什么不直接采用训练时的model进行预测,而是采用了一种最近邻搜索的方法?
这个问题的答案是一个经典的工程和学术做trade-off的结果,在model serving过程中对几百万个候选集逐一跑一遍模型的时间开销显然太大了,因此在通过candidate generation model得到user 和 video的embedding之后,通过最近邻搜索的方法的效率高很多。我们甚至不用把任何model inference的过程搬上服务器,只需要把user embedding和video embedding存到redis或者内存中就好了
3、Youtube的用户对新视频有偏好,那么在模型构建的过程中如何引入这个feature?
为了拟合用户对fresh content的bias,模型引入了“Example Age”这个feature,文中其实并没有精确的定义什么是example age。按照文章的说法猜测的话,会直接把sample log距离当前的时间作为example age。比如24小时前的日志,这个example age就是24。在做模型serving的时候,不管使用那个video,会直接把这个feature设成0。大家可以仔细想一下这个做法的细节和动机,非常有意思。
当然我最初的理解是训练中会把Days since Upload作为这个example age,比如虽然是24小时前的log,但是这个video已经上传了90小时了,那这个feature value就是90。那么在做inference的时候,这个feature就不会是0,而是当前时间每个video的上传时间了。
我不能100%确定文章中描述的是那种做法,大概率是第一种,文章也验证了,example age这个feature能够很好的把视频的freshness的程度对popularity的影响引入模型中。
image.png
4、在对训练集的预处理过程中,Youtube没有采用原始的用户日志,而是对每个用户提取等数量的训练样本,这是为什么?
为了减少高度活跃用户对于loss的过度影响
5、Youtube为什么不采取类似RNN的Sequence model,而是完全摒弃了用户观看历史的时序特征,把用户最近的浏览历史等同看待,这不会损失有效信息吗?
这个原因应该是YouTube工程师的“经验之谈”,如果过多考虑时序的影响,用户的推荐结果将过多受最近观看或搜索的一个视频的影响。YouTube给出一个例子,如果用户刚搜索过“tayer swift”,你就把用户主页的推荐结果大部分变成tayer swift有关的视频,这其实是非常差的体验。为了综合考虑之前多次搜索和观看的信息,YouTube丢掉了时序信息,讲用户近期的历史纪录等同看待。
但RNN到底适不适合next watch这一场景,其实还有待商榷,@严林 大神在上篇文章的评论中已经提到,youtube已经上线了以RNN为基础的推荐模型, 参考论文如下:https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/46488.pdf
看来时隔两年,YouTube对于时序信息以及RNN模型有了更多的掌握和利用。
6、在处理测试集的时候,Youtube为什么不采用经典的随机留一法(rando m holdout),而是一定要把用户最近的一次观看行为作为测试集?
只留最后一次观看行为做测试集主要是为了避免引入future information,产生与事实不符的数据穿越。
7、在确定优化目标的时候,Youtube为什么不采用经典的CTR,或者播放率(Play Rate),而是采用了每次曝光预期播放时间(expected watch time per impression)作为优化目标?
这个问题从模型角度出发,是因为 watch time更能反应用户的真实兴趣,从商业模型角度出发,因为watch time越长,YouTube获得的广告收益越多。而且增加用户的watch time也更符合一个视频网站的长期利益和用户粘性。
8、在进行video embedding的时候,为什么要直接把大量长尾的video直接用0向量代替?
这又是一次工程和算法的trade-off,把大量长尾的video截断掉,主要还是为了节省online serving中宝贵的内存资源。当然从模型角度讲,低频video的embedding的准确性不佳是另一个“截断掉也不那么可惜”的理由。
9、针对某些特征,比如#previous impressions,为什么要进行开方和平方处理后,当作三个特征输入模型?
这是很简单有效的工程经验,引入了特征的非线性。从YouTube这篇文章的效果反馈来看,提升了其模型的离线准确度。
10、为什么ranking model不采用经典的logistic regression当作输出层,而是采用了weighted logistic regression?
在第7问中,我们已经知道模型采用了expected watch time per impression作为优化目标,所以如果简单使用LR就无法引入正样本的watch time信息。因此采用weighted LR,将watch time作为正样本的weight,在线上serving中使用e(Wx+b)做预测可以直接得到expected watch time的近似,完美。具体细节可参考https://zhuanlan.zhihu.com/p/61827629
训练Weighted LR一般来说有两种办法:
将正样本按照weight做重复sampling,然后输入模型进行训练;
在训练的梯度下降过程中,通过改变梯度的weight来得到Weighted LR。