文章目录
1. 总览
2016年,YouTube发表了深度学习推荐系统论文Deep Neural Networks for YouTube Recommendations,这是一篇理论和实践俱佳的论文。从Matching到Ranking到线上serving的各个环节,论文都给出了Youtube的实践方法。总体框架如下:
- 召回网络:此阶段主要目的是从百万级的视频中检索出一小部分的视频用于之后的排序操作,这部分需要处理的数据量非常大,速度要求快,所有使用的模型和特征都不能太复杂。召回网络会根据用户的历史信息(比如用户的历史观看、搜索等)进行召回,这一阶段召回的视频满足用户泛化的兴趣,用户之间的相似度则通过粗略的特征来表示,如用户观看视频的ID,搜索query和用户画像。
- 排序网络:此阶段会使用更加丰富和精细的用户和视频特征,预测用户对召回的视频打分,然后根据分数进行排序,依次展示给用户。这部分最主要是能够精准的将视频推送给用户,所以需要更加复杂的模型和特征来提升推荐效果。
2. 召回(Matching)
2.1 什么特征?如何选择数据样本?
在Youtube视频推荐场景下,考虑到如下特征(各个特征concat到一起后,送到后续的DNN中):
- 用户观看视频的ID序列:对序列中各ID的embedding进行mean pooling(tf.reduce_mean),得到整个序列的embedding。
- 用户搜索词query的序列:同样对各query的embedding进行mean pooling,得到搜索词序列的embedding。
- 用户地理特征和用户设备特征:均为一些离散特征,可以采用embedding方法或者直接采用one-hot方法(当离散维度较小时),得到用户的地理向量和设备向量。
- 人口属性特征:比如性别,年龄。
- Example Age:涉及到item的冷启动问题。在推荐系统中很重要的一点是视频的新颖性,用户更倾向于观看新视频,但机器学习模型都是基于历史观看视频记录学习,所以在某种程度上,模型和业务是相悖的,所以文中构建了一个特征example age,简单的可以理解为是视频的年龄,初始值设为0,随着时间的增长,记录视频的年龄。加入之后效果十分明显,如图所示,蓝色曲线是引入Example Age前的模型预估值,可以看出与时间没有显著关系,而引入Example Age后的模型预估十分接近经验分布。
注:序列中ID的初始embedding,论文中是通过word2vec来获取的。
关于数据样本的选择:
- 使用更广的数据源:不仅仅使用推荐场景的数据进行训练,其他场景比如搜索等的数据也要用到,这样也能为推荐场景提供一些explore。
- 为每个用户生成固定数量训练样本:目的是减少高度活跃用户对模型损失的过度影响,使模型过于偏向活跃用户的行为模式,忽略数量更广大的长尾用户的体验。
2.2 训练方式及优化
关于如何训练,论文中说到对两种方式进行了实验,图(a)是hold-out方式,利用上下文信息预估中间的一个视频;图(b)是predicting future watch的方式,则是利用上文信息,预估下一次浏览的视频。发现图(b)的方式在线上A/B test中表现更佳。
YoutubeNet采用的训练方式是预测下一个视频ID,所以这是一个多分类问题,但是视频库里面的视频类别多达百万级,使用softmax无疑是低效的。Youtube采用类似于word2vec中的负采样优化算法,在非下一个watch的候选集合中采样一定数量的视频作为负样本。区别于word2vec的是,word2vec的负采样的优化方式是二元LR,而YoutubeNet中,采用交叉熵函数进行优化,正样本的label索引对应的才是1。
2.3 如何获取User和Item的Embedding
User Embedding就是DNN中最后一个ReLU(Dense)层的输出向量,其shape为[bs,emb_size],其中,bs是一个训练batch中的样本数。
我们知道,假设负采样10个样本,带上正样本1个,那么label一定是一个长度为11的one-hot。送给交叉熵的也一定是个长度为11的softmax函数计算后的向量。那么最后一个ReLU的输出,是如何计算得到这样的一个长度为11的向量呢?
论文中的图其实省略了一些东西,原论文中的softmax,其实是一个套上softmax函数的Embedding table(代码实现上,可以用全连接层,或者矩阵,或者nn.Embedding来实现)。下图可能更直观:
我们知道,user embedding的shape就是[bs,emb_size],其中bs是一个batch中user的个数(其实user embedding就是[1,emb_size])。而embedding table的shape是[emb_size,N],N就是上面说到的11,及多分类的类别总数。这个embedding table就是Item Embedding的table,它的每一列都是一个Item embedding。于是我们有[bs,emb_size] * [emb_size, N],得到[bs,N],参与到交叉熵的计算中。
原论文中的softmax是按照下面公式计算的:
其中,u矩阵就是user embedding矩阵,v矩阵就是item embedding矩阵,这样获取embedding的方式,和word2vec中embedding table的生成是一样的。
2.4 线上Serving
上图左上角是线上召回服务的方法。模型训练好后,Item Embedding就是一个Embedding table,将其存储到redis等数据库中。线上召回时,用户Embedding通过调用模型计算(最后一个ReLU的输出),实时返回用户Embedding;而Item Embedding则直接在数据库中调取(模型训练完后是个静态的embedding table)。
这里讲一下,上面讲的Embedding放到redis,只是存储方法。线上相似度检索并不是直接从几百万Embedding中计算相似度,一般都是基于ANN检索(近似最邻近检索),比如使用Facebook的向量检索工具Faiss,离线构建索引,然后计算每个用户最邻居的K个Item,最后再把每个用户最邻近的K个Item存储到redis中,线上直接查找K个结果就可以。
3. 排序(Ranking)
召回阶段已经给出了候选集,在排序阶段,其目的是对给定的小规模候选集进行精细化的排序。排序的基本框架和召回是类似的,需要重点关注模型的输入层和输出层,即排序模型的特征工程和优化目标。
排序的特征工程更为精细化,此处不做赘述,因为不同的业务场景下考虑的特征也会不同。这里重点关注输出层。负样本是有曝光无点击的视频,正样本是有曝光有点击的视频,预测用户的观看时长。正样本记录了用户观看视频的时长,为了预测观看时长,专门设计了一个加权逻辑回归模型(其实就是加权的二元交叉熵损失)。加入了观看时长这一衡量标准,也是为了用来解决噪声的,因为很多时候用户点击观看一个视频并不代表用户真的喜欢,满意这个内容。我们用观看时长对正样本做了加权,负样本都用单位权重(即不加权)。
至于线上serving的优化目标,这里直接贴上王喆书中的描述:
4. 其他一些讨论
这里参照王喆的讨论
1. 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模型有了更多的掌握和利用。
2. 在处理测试集的时候,YouTube为什么不采用经典的随机留一法(random holdout),而是一定要把用户最近的一次观看行为作为测试集?
只留最后一次观看行为做测试集主要是为了避免引入future information,产生与事实不符的数据穿越。
3. 在确定优化目标的时候,YouTube为什么不采用经典的CTR,或者播放率(Play Rate),而是采用了每次曝光预期播放时间(expected watch time per impression)作为优化目标?
这个问题从模型角度出发,是因为 watch time更能反应用户的真实兴趣,从商业模型角度出发,因为watch time越长,YouTube获得的广告收益越多。而且增加用户的watch time也更符合一个视频网站的长期利益和用户粘性。
4. 在进行video embedding的时候,为什么要直接把大量长尾的video直接用0向量代替?
这又是一次工程和算法的trade-off,把大量长尾的video截断掉,主要还是为了节省online serving中宝贵的内存资源。当然从模型角度讲,低频video的embedding的准确性不佳是另一个“截断掉也不那么可惜”的理由。
5. 为什么ranking model不采用经典的logistic regression当作输出层,而是采用了weighted logistic regression?
因为在第3问中,我们已经知道模型采用了expected watch time per impression作为优化目标,所以如果简单使用LR就无法引入正样本的watch time信息。因此采用weighted LR,将watch time作为正样本的weight,在线上serving中使用e(Wx+b)做预测可以直接得到expected watch time的近似,完美。
参考:
1.Deep Neural Networks for YouTube Recommendations
2.深入理解YouTube推荐系统算法
3. YouTube深度学习推荐系统的十大工程问题