YouTube于2016年发表在RecSys会议上的“Deep Neural Network YouTube Recommendations”是非常具有工程价值的论文,在深度学习还没有被广泛应用于计算广告、推荐领域的当时,深受欢迎。哪怕放到现在,这篇文章也是必读的经典好文。以作笔记的形式对这篇优秀的文章做简单总结。
YouTube是全球最大的UGC的视频网站之一,每天都有大量的视频被上传、分享、观看。因此用户推荐个性化是YouTube非常重视的业务领域。但是由于用户量和视频量巨大,YouTube推荐系统面临以下三种主要挑战:
数据规模:由于数据规模大很多推荐算法在YouTube推荐场景中不奏效。
新鲜度:连续不断的有新的视频被上传,因此YouTube视频库是动态变化的,所以YouTube推荐系统需要对新上传的视频以及用户的新actions有足够快的响应能力。
噪声:YouTube很少从用户历史行为中获取用户的显示反馈(如评论、分享、点赞或者打分等行为),因此需要根据用户的隐式反馈建模,这样难免会引入很多的噪声数据。
由于候选视频集合太大,YouTube介绍的推荐系统由两个神经网络构成,分别是:候选生成模型和深度排序模型。候选生成模型根据用户的历史行为从百万级别的候选视频中筛选出与用户兴趣比较相关数百级别视频,可以认为是一个粗略的筛选;而深度排序模型算出每个视频的score,然后将数百级别的视频按照score从高到低的顺序展示给用户。YouTube推荐系统的整体结构如下图:
可以将推荐视作多分类问题,每个视频看做一个类别,那么可以用条件概率表示,如下:
它表示在用户U和上下文C的基础上,从视频库V中在时刻t观看视频i的概率。其中u表示(users,context)对的embedding向量;vi表示每个候选视频的embedding向量。使用用户的隐式反馈进行建模,将用户看完一个视频视为正样本。
由于每个视频表示一个类别,那么共有百万个类别,为了提高训练的效率,从候选样本中抽样负类(负采样),然后通过重要性加权对这个采样进行校正。候选生成模型的架构如下图:
对观看视频和搜索词进行embedding,得到长度变化的序列,对embedding进行平均操作得到size固定的稠密向量,对watch vector、search vector、地理位置的embedding以及年龄、性别等特征连接成为一个长向量作为输入层;后面接3层隐藏层,激活函数为ReLU,然后通过softmax得到每个类别的概率。框架的左上角serving没用采用网络结构,而是使用了最邻近方法,是因为最近邻搜索的效率高。
前面说过YouTube推荐系统的三大挑战之一就是新鲜度问题,每秒钟有很多小时的视频被上传到YouTube上,所以为用户推荐新鲜的内容对YouTube来说是非常重要的,虽然用户喜欢新鲜的内容,但是并不会以牺牲相关性为代价,也就是说给用户推荐新鲜但其不感兴趣的视频是不受用户欢迎的。为了拟合用户对新鲜内容的偏置,模型引入了’example age’这个特征,此特征能够把视频的新鲜度对视频流行度的影响引入模型中;但是在做模型serving的时候,将此特征置0.
Note:关于example age的定义,文中并没有明确给出,应该是将sample log到当前时间作为example age。关于这一点大神王喆在他的文章中有说明。
可以看到,引入example age后模型预测更接近与经验分布,可准确表示数据中观察到的上传时间和随时间变化的流行度;而基线模型几乎是一条直线。
推荐问题经常会涉及到解决surrogate问题并将结果转化成特殊的context。一个典型的例子是:精确的预测评分可以有效的进行电影推荐。训练集是从所有的YouTube视频中产生,而不仅仅是从推荐视频中产生,这样可以避免过度个性化以至于用户看不到新内容;此外为每一个用户生成固定数量训练样本,这样可以避免高度活跃的用户对loss的过度影响。
需要格外注意分类器的保留信息,防止surrogate问题过拟合。比如,用户刚刚搜索了Kobe Bryant,紧接着推荐系统就把用户主页推荐结果大部分都变成了和Kobe Bryant相关的视频,这其实是非常差的用户体验。YouTube通过丢弃时序信息,并用无序的bag of tokens来表示搜索词,这样可将用户的历史信息同等看待。
使用随机留一法选择labels和context然后进行预测,这会泄露future information。因此YouTube把最近观看的视频作为输入,去预测future watch。
由于排序模型只需要对百级别的视频进行评分,所以模型可以引入更多的描述用户以及用户和视频关系的特征,这样可以更精准的将视频推荐给用户。排序模型的结构图如下:
排序模型和候选生成模型的结构非常类似。输入分别为:impression video ID embedding、watched video IDs embedding+average pooling、user language embedding、video language embedding、time since last watch+normalize、#previous impressions+normalize。其中对后两个特征,对归一化后的特征进行平方开平方操作,这样可以引入特征的非线性,提高模型的表达能力。将以上向量和数连接成一个wide向量作为网络的输入;经过三层激活函数为ReLu的隐藏层,以weighted LR作为输出层,在serving时使用指数函数进行预测。
模型的优化目标没有采用CTR,而是以expected watch time作为优化目标。这是因为使用CTR进行排序会产生用户没有看完视频的欺骗性行为(只点开了视频没有观看或者观看时间很短),而观看时间能更好的捕获用户的参与度(点赞、转发、评论等行为)。在文章中,YouTube对长尾video的处理是用全0向量代替。
排序模型中为什么用weighted LR预测期望观看时间?做模型serving时为什么又使用指数函数进行预测?什么是weighted LR,其实就是给每一个样本都赋予一定的权重,在YouTube的原文中是这样做的:正样本被视频观看时间T加权,负样本的权重都为1。原文中提到了Odds(几率/发生率)这个词,那么我们就从Odds开始说起,其定义如下:
其中p为事情发生的概率,对应到YouTube的论文中就是impression被点击的概率,对Odds去自然对数,并让其等于线性回归函数得到:
再对上式两边同时去自然指数,得到:
可以惊奇的发现,serving中的指数函数计算的是Odds。前面说过,排序模型是以expected watch time为优化目标,那么Odds和优化目标有什么关系呢?我们知道weighted LR是对正样本以视频观看时间进行了加权,那么有:
由于在YouTube中每个impression被点击的概率p很小,而权重是对第i个impression的观看时长(这里有一个点文中没有说清楚,YouTube上的视频的长短不一,用户观看时长也是不同的,观看时长的单位没有明确说明,如果单位是秒的话,那么值将会比较大,我认为视频时长的单位是小时可能会比较合适),所以上面的式子可近似写为:
因为p为impression被点击的概率,是观看视频的时长,所以为观看视频的期望时长。这恰好是之前设定的优化目标,只需对预测的期望时长进行一个排序然后推荐给用户即可。
1. Deep Neural Networks for YouTube Recommendations
2. 重读Youtube深度学习推荐系统论文,字字珠玑,惊为神文
3. YouTube深度学习推荐系统的十大工程问题