这篇论文 Deep Neural Networks for YouTube Recommendations 是google的YouTube团队在推荐系统上DNN方面的尝试,发表在16年9月的RecSys会议。本文所介绍的YouTube的推荐系统主要包括Deep Candidate Generation model和Deep Ranking model两个部分:Deep Candidate Generation model在成千上万的视频集中选出几百个视频作为推荐候选集;Deep Ranking model对这些候选集里所有视频进行打分排序,然后按照排序的结果像用户推荐视频。
在推荐系统领域,特别是YouTube的所在视频推荐领域,主要面临三个挑战:
整个推荐系统分为candidate generation(后用Matching代替)和Ranking两个阶段。
由于候选视频集合过大,考虑online系统延迟问题,不宜用复杂网络直接进行推荐,所以Youtube采取了两层深度网络完成整个推荐过程:
把推荐问题建模成一个“超大规模多分类”问题。
即在时刻 t t t 为用户 U U U (上下文信息 C C C )在视频库 V V V 中精准的预测出视频 i i i 的类别(每个具体的视频视为一个类别, i i i 即为一个类别),用数学公式表达如下:
P ( w t = i ∣ U , C ) = e v i , u ∑ j ∈ V e v j u P(w_t=i|U,C)=\frac{e^{v_i,u}}{\sum\limits_{j \in V}e^{v_ju}} P(wt=i∣U,C)=j∈V∑evjuevi,u
向量 u ∈ R N u\in R^N u∈RN 是 < u s e r , c o n t e x t >
DNN的目标就是在用户信息和上下文信息为输入条件下学习用户的embedding向量 u \ u u。
整个模型架构是包含三个隐层的DNN结构。
输入是用户浏览历史、搜索历史、人口统计学信息和其余上下文信息concat成的输入向量。
输出分线上和离线训练两个部分:离线训练阶段输出层为softmax层;线上直接利用user向量查询相关视频。
Q: 入是用户观看过的video的embedding向量,以及搜索词的embedding向量 ,那么这个embedding向量是如何生成的呢?
A: 先用word2vec方法对video和search token做了embedding之后再作为输入。
使用更广的数据源(全部的观看记录):不仅仅使用推荐场景的数据进行训练,其他场景比如搜索等的数据也要用到,这样也能为推荐场景提供一些explore。
为每个用户生成固定数量训练样本:在实际工程中发现如果为每个用户固定样本数量上限,平等的对待每个用户,避免loss被少数active用户domanate,能明显提升线上效果。
抛弃序列信息:在实现时尝试的是去掉序列信息,对过去观看视频/历史搜索query的embedding向量进行加权平均。这点其实违反直觉,可能原因是模型对负反馈没有很好的建模。
不对称的共同浏览(asymmetric co-watch)问题:所谓asymmetric co-watch值的是用户在浏览视频时候,往往都是序列式的,开始看一些比较流行的,逐渐找到细分的视频。下图所示图(a)是hled-out方式,利用上下文信息预估中间的一个视频;图(b)是predicting next watch的方式,则是利用上文信息,预估下一次浏览的视频。我们发现图(b)的方式在线上A/B test中表现更佳。而实际上,传统的协同过滤类的算法,都是隐含的采用图(a)的held-out方式,忽略了不对称的浏览模式。
Ranking阶段的最重要任务就是精准的预估用户对视频的喜好程度。不同于Matching阶段面临的是百万级的候选视频集,Ranking阶段面对的只是百级别的商品集,因此我们可以使用更多更精细的feature来刻画视频(item)以及用户与视频(user-item)的关系。比如用户可能很喜欢某个视频,但如果list页的用的“缩略图”选择不当,用户也许不会点击,等等。
Ranking阶段的模型和Matching基本相似,不同的是training最后一层是一个weighted LR层,而serving阶段激励函数用的是 e x e^x ex。
① 特征工程
比如我们要度量用户对视频的喜欢,可以考虑用户与视频所在频道间的关系:
这两个连续特征的最大好处是具备非常强的泛化能力。另外除了这两个偏正向的特征,用户对于视频所在频道的一些PV但不点击的行为,即负反馈Signal同样非常重要。
② Embedding 离散特征
NN更适合处理连续特征,因此稀疏的特别是高基数空间的离散特征需要embedding到稠密的向量中。 每个维度(比如query/user_id)都有独立的embedding空间,一般来说空间的维度基本与log(去重后值得数量)相当。实际并非为所有的id进行embedding,比如视频id,只需要按照点击排序,选择top N视频进行embedding,其余置为0向量。而对于像“过去点击的视频”这种multivalent特征,与Matching阶段的处理相同,进行加权平均即可。
同维度不同feature采用的相同ID的embedding是共享的(比如“过去浏览的视频id” “saw视频id”),这样可以大大加速训练,但显然输入层仍要分别填充
③ 归一化 连续特征
NN对输入特征的尺度和分布都是非常敏感的,实际上基本上除了Tree-Based的模型(比如GBDT/RF),机器学习的大多算法都如此。我们发现归一化方法对收敛很关键,推荐一种排序分位归一到[0,1]区间的方法,即 x ‾ = ∫ − ∞ x d f \overline x=\int^x_{-\infty}df x=∫−∞xdf,累计分位点。
把归一化后的 x ‾ \overline{x} x 的根号 x \sqrt{x} x 和平方 x 2 x^2 x2 作为网络输入,以期能使网络能够更容易得到特征的次线性(sub-linear)和(super-linear)超线性函数。
目标是预测期望观看时长。有点击的为正样本,有PV无点击的为负样本,正样本需要根据观看时长进行加权。因此,我们训练阶段网络最后一层用的是 weighted logistic regression。
正样本的权重为观看时长 T i T_i Ti,负样本权重为1。这样的话,LR学到的odds为:
∑ T i N − k \frac{\sum T_i}{N-k} N−k∑Ti
其中 T T T 是总的样本数量, k k k是正样本数量, T i T_i Ti 是第 i i i 样本的观看时长。一般来说, k k k 相对 N N N 比较小,因此上式的odds可以转换成 E [ T ] ( 1 + P ) E[T](1+P) E[T](1+P),其中 P P P 是点击率,点击率一般很小,这样odds接近于 E ( T ) E(T) E(T),即期望观看时长。因此在线上serving的inference阶段,采用 e x e^x ex作为激励函数,就是近似的估计期望的观看时长。
Q1: 文中把推荐问题转换成多分类问题,在预测next watch的场景下,每一个备选video都会是一个分类,因此总共的分类有数百万之巨,这在使用softmax训练时无疑是低效的,这个问题YouTube是如何解决的?
负采样(negative sampling)并用importance weighting的方法对采样进行calibration(校正)。
Q2:在candidate generation model的serving过程中,YouTube为什么不直接采用训练时的model进行预测,而是采用了一种最近邻搜索的方法?
这是一个经典的工程和学术做trade-off的结果,在model serving过程中对几百万个候选集逐一跑一遍模型的时间开销显然太大了,因此在通过candidate generation model得到user 和 video的embedding之后,通过最近邻搜索的方法的效率高很多。我们甚至不用把任何model inference的过程搬上服务器,只需要把user embedding和video embedding存到redis或者内存中就好了。
Q3: user vector和video vector是怎么生成的?
DNN输入的特征是
类的特征,及根据用户每次刷新的状态去输入到网络中得到的最后一层的向量作为user vector,可以做到实时反馈,每次最新的浏览点击都能反馈到输入层进而得到不同的user vector。 video vector则是Softmax中video与最后一层的w作为这个video的vector,最终通过user_vec与item_vec的内积最大索引就能快速得到结果。
Q4: Youtube的用户对新视频有偏好,那么在模型构建的过程中如何引入这个feature?
为了拟合用户对fresh content的bias,模型引入了“Example Age”这个feature,文中其实并没有精确的定义什么是example age。按照文章的说法猜测的话,会直接把sample log距离当前的时间作为example age。比如24小时前的日志,这个example age就是24。在做模型serving的时候,不管使用那个video,会直接把这个feature设成0。
Q5: 在对训练集的预处理过程中,YouTube没有采用原始的用户日志,而是对每个用户提取等数量的训练样本,这是为什么?
了减少高度活跃用户对于loss的过度影响。
Q6:YouTube为什么不采取类似RNN的Sequence model,而是完全摒弃了用户观看历史的时序特征,把用户最近的浏览历史等同看待,这不会损失有效信息吗?
如果过多考虑时序的影响,用户的推荐结果将过多受最近观看或搜索的一个视频的影响。YouTube给出一个例子,如果用户刚搜索过“Taylor swift”,你就把用户主页的推荐结果大部分变成Taylor swift有关的视频,这其实是非常差的体验。为了综合考虑之前多次搜索和观看的信息,YouTube丢掉了时序信息,讲用户近期的历史纪录等同看待。
Q7:在处理测试集的时候,YouTube为什么不采用经典的随机留一法(random holdout),而是一定要把用户最近的一次观看行为作为测试集?
只留最后一次观看行为做测试集主要是为了避免引入future information,产生与事实不符的数据穿越。
Q8:在确定优化目标的时候,YouTube为什么不采用经典的CTR,或者播放率(Play Rate),而是采用了每次曝光预期播放时间(expected watch time per impression)作为优化目标?
因为 watch time更能反应用户的真实兴趣,从商业模型角度出发,因为watch time越长,YouTube获得的广告收益越多。而且增加用户的watch time也更符合一个视频网站的长期利益和用户粘性。
Q9:在进行video embedding的时候,为什么要直接把大量长尾的video直接用0向量代替?
把大量长尾的video截断掉,主要还是为了节省online serving中宝贵的内存资源。当然从模型角度讲,低频video的embedding的准确性不佳是另一个“截断掉也不那么可惜”的理由。
Q10:针对某些特征,比如#previous impressions,为什么要进行开方和平方处理后,当作三个特征输入模型?
这是很简单有效的工程经验,引入了特征的非线性。从YouTube这篇文章的效果反馈来看,提升了其模型的离线准确度。
Q11:为什么ranking model不采用经典的logistic regression当作输出层,而是采用了weighted logistic regression?
模型采用了expected watch time per impression作为优化目标,所以如果简单使用LR就无法引入正样本的watch time信息。因此采用weighted LR,将watch time作为正样本的weight,在线上serving中使用$\ e^(Wx+b)\ $做预测可以直接得到expected watch time的近似,完美。
Q12:为什么YouTuBe排序模型在serving阶段采用了exp(Wx+b)的形式,训练阶段却采用了加权LR的形式?
几率比 o d d s = p 1 − p odds=\frac{p}{1-p} odds=1−pp 即:一件事发生与不发生的概率之比
对于逻辑回归而言,一件事情发生的概率p有sigmoid函数得到,即:
p = s i g m o i d ( W x + b ) = 1 1 + e − ( W x + b ) p=sigmoid(Wx+b)=\frac{1}{1+e^{-(Wx+b)}} p=sigmoid(Wx+b)=1+e−(Wx+b)1
结合几率比的定义可得:
o d d s = e ( W x + b ) = p 1 − p odds=e^{(Wx+b)}=\frac{p}{1-p} odds=e(Wx+b)=1−pp
加权逻辑回归的意义就是引入正样本的权重信息,那么在YouTuBe的场景下,正样本的权重应该是什么呢?==> 显然是观看时长!
假设正样本的观看时长为T,则代表正样本发生的概率变成了原来的T倍;正样本的odds变为:
o d d s = T p 1 − T p odds = \frac{Tp}{1 - Tp} odds=1−TpTp
由于在YouTuBe视频推荐场景下,p值很小,故 T p / ( 1 − T p ) ≈ T p Tp/(1 - Tp) ≈ Tp Tp/(1−Tp)≈Tp, 仔细观察,这个 T p Tp Tp 是什么?不就是期望E(T)吗?!所以odds本质上意义就是“每次曝光期望观看时长”,以此为优化目标很符合预期。
本文仅作为个人学习记录,不作为商业用途,谢谢理解。
参考:
1.https://zhuanlan.zhihu.com/p/52504407
2.https://www.jianshu.com/p/9762ed39647f
3.https://zhuanlan.zhihu.com/p/25343518