论文地址

这篇论文主要是讲深度学习模型在YouTube视频推荐系统中的应用,包括候选集生成模型排序模型两部分。

系统概览

系统主要由候选集生成和排序两个步骤组成。候选集生成解决的是系统无法对海量视频进行全覆盖的在线实时打分。排序解决的是推荐结果呈现给用户的排列顺序。

整个系统的基本流程是这样的:

  1. 候选集生成模型利用用户的历史行为和访问时的上下文数据,从海量的视频库中检索出一个较小的视频库子集。(离线粗筛)
  2. 排序模型整合多种渠道的视频库子集,利用用户的历史行为、访问时的上下文数据、视频特征等,完成对视频的打分排序。并选择TopN个视频推荐给用户。(在线细筛)

通过该系统,我们可以实现从超大规模的视频库中,筛选出个性化的推荐结果呈现给用户。

注意:离线训练的结果和线上的表现不一定总是相关。所以,模型最终的表现还需要在线上进行A/B测试

候选集生成模型

候选集生成模型完成了从海量的视频库中,粗筛出几百个和用户最相关的候选视频。

模型输出

模型最终得到的是用户、视频在同一个向量空间的投影。即,得到具有相同维度的、能够进行点积计算的用户和视频向量。这样我们就可以将用户$U$对视频$V$的兴趣程度表示为:

$$ score = U \cdot V $$

如果将点乘作为向量相似度的计算方法,则距离用户$U$最近的$N$个视频,就是我们最终需要的视频候选集。

最近邻(NN)与近似最近邻(ANN)

通常来讲,在向量维度不高、计算复杂度尚可接受的情况下,可以选择精确检索方法。如果维度过大,精确检索的计算花费已经到了让人无法容忍的地步,就需要选择近似检索的方法,以牺牲少许的精度,来换取可观的效率提升。

精确检索:KD树、R树、M树

近似检索:局部敏感哈希(LSH)、乘积量化(PQ)

目标问题

上面构想的很好,那么该如何得到它们呢?YouTube团队巧妙地将视频推荐问题转换成了多分类问题。

这里我们将每个视频作为一个类别,则视频推荐问题可以这样描述:

在给定用户$U$和上下文$C$的情况下,预测在时间$t$,类别$w_t$为视频$i$的概率

$$P(w_t=i|U,C) = \dfrac {e^{u \cdot v_i}} {\sum_{j \in V} {e^{u \cdot v_i}}}$$

上面是多分类中用到的SoftMax公式,这里 $v_i \in R^N$,$u \in R^N$,分别表示视频和用户的嵌入向量。接下来的训练任务就是得到这两个嵌入向量。

下面说一下按照SoftMax直接训练的一些问题。

softmax loss

单条样本损失函数:

$$Loss = - \sum_{i \in V}^{|V|} {y_i} \log {P(y=i)}$$

$V$表示类别空间,$y_i$是实际的概率值,所以它的取值只有0和1。如果是单分类问题,每条样本只对应一个类别,就会只有一个$y_i$的值为1。

$P(y=i)$是模型预测类别为$i$的概率值,所以,取值介于[0,1]。具体计算公式如下(就是softMax公式):

$$P(y=i) = \dfrac {e^{u \cdot v_i}} { \sum_{j \in V} { e^{u \cdot v_i}}}$$

通过上面的公式可以发现,为了计算一条样本的loss,我们需要对$V$中的每个类别都计算一次softMax。当$|V|$的值很大的时候,单条样本loss的计算成本会很高。

论文中的目标问题就是一个类别空间超级大的多分类问题。

负采样

为了加快模型训练,论文中采用了负采样的方法。负采样是一种候选采样方法。

应用场景描述

假设我们有这样一个问题,给定一个样本集,其中每个样本由$(x_i, T_i)$,其中$x_i$是输入特征,$T_i$是一个target小集合,满足$T \subset L$, $|T| << |L|$。我们的目标是学习一个$F(x, y)$,使得给定一个$x$,我们可以预测出类别$y$为正的可能性。

如果我们使用正常的softmax方法,那么在计算每一个sample时,我们都需要遍历整个集合,对每一个可能的类别都计算一次。在类别集合特别大的情况下,这种方法的计算成本很高。

候选采样

在训练每个样本$(x_i, T_i)$时,我们只需要$F(x, y)$在一个小的候选类别集合$C_i$进行评估。其中,$C_i = T_i \bigcup S_i$。这里的$S_i$是基于指定的随机采样方法获得的一个类别子集,其中,$S_i \subset L$

上述随机采样得到$S_i$的过程,是否依赖$x_i$和$T_i$不做限制。

论文中采用的负采样方法就是从视频库中随机选择一些视频作为负例标签

tensorflow关于候选采样的介绍

模型结构

接下来,我们看一下模型是如何实现用户、视频特征向同一空间投影的。

样本特征

用户历史观看视频列表,用户历史搜索记录列表,用户性别,用户年龄,用户地域,行为访问设备,用户登录状态,样本年龄,视频ID

不同类型特征的处理

  • 离散特征:【用户历史观看视频列表,用户历史搜索记录列表,用户性别,用户年龄,用户地域,行为访问设备,用户登录状态,视频ID】

    • oneHot:为所有取值匹配一个位置编号。其中,只有一个位置的值为1,其余位置都为0。
      • 比如:性别特征包括男性、女性两种,则用[1,0]表示男性,用[0,1]表示女性
    • multiHot:对于多值特征,每个值对应的位置都设置为1,其余位置都为0。
      • 比如:擅长的语言包括Java、C、Python、Swift,如果同时会Java和Python,则用[1,0,1,0]表示
    • Embedding:为每一种取值匹配一个$n$维的向量,向量的值是通过模型训练得到的。
      • 比如:城市类型包括一线城市、二线城市、三线城市、四线城市,如果用3维的向量来做嵌入,则一线城市可以表示为[1.2,3.1,2.1]。
  • 连续特征:【样本年龄】

    • 特征离散化,按照离散特征处理
    • 进行归一化、开方、平方等方式处理

将上面各个向量(除了视频ID)进行连接操作(concat),得到一个1 * N 维的向量。如果是多批次训练,会得到一个batch_size * 1 * N的向量。这里的N是上面所有特征的维度之和。

关于离散特征和连续特征的区分

不能说数值型特征就一定是连续特征。比如,对于年龄这种数值型特征,其只有比较意义,并不能直接进行计算。所以,年龄应该属于离散特征。

关于用户历史观看视频列表和用户历史搜索记录列表的合并

将多个视频的嵌入向量合并成一个向量,可以采用sum、mean、sqrtn、attention等方法

关于视频ID嵌入向量的说明

模型中有两个地方都使用了视频ID的嵌入向量,分别是计算用户历史观看视频列表和模型输出时计算用户向量和视频向量的点积

经过实验对比,这两个地方进行嵌入向量的共享比分别做嵌入的实际效果要好。推荐使用共享视频ID嵌入向量的实现方法。

关于样本年龄的说明

在视频领域,通常来说,用户更倾向于点击新上传的视频。而基于用户历史行为的训练,模型通常会倾向于推荐已观看的旧视频。

基于这个特点,论文中将样本年龄加入到了模型特征中,使得模型可以学习到用户行为的时序特征。

样本年龄指的是,训练样本的触发时间距离模型训练时的时间间隔。

比如,模型训练的时间是2019年10月01号,而样本中用户行为的触发时间是2019年09月20号,则这里的样本时间就是10天。

加入样本年龄之后,整个预测的结果就和预期的用户点击行为分布基本一致了。

在模型预测时,会将样本年龄设置为0或者一个很小的负数,表示模型在对当前的样本进行预测。

样本年龄为什么会有效果

样本年龄能够反映一个视频从开始被点击,到点击量达到最高点,再到点击量逐渐回落的变化趋势。
模型通过对这种趋势的学习,能够识别出那些点击量处在较高位置的新视频

为什么不使用视频上传时间

通过模型结构我们可以发现,样本年龄是模型的输入特征。而输入特征都是为了得到最终的用户向量。由于某一个用户向量是不可能只依赖某一个视频特征的,所以,输入特征里不能包含某一个视频的上传时间。

隐含层

论文中采用塔式的层结构(具体可见参加上面的模型结果图),对包含0、1、2、3、4层隐含层进行实验,分别对应0、256、512、1024、2048个隐藏单元。下图展示了不同情况下的实验结果:

总的来说,隐含层超过3层,对模型效果的提升贡献就不大了。所以,推荐使用3层隐含层。

训练数据的处理

论文中对训练过程不同的数据处理方式进行了尝试,给出了一些值得借鉴的训练数据处理建议:

  • 选择更广泛的训练数据,不仅仅只包含推荐的行为数据
    • 发现新内容,避免推荐结果被过分利用(Exploration & Exploitation)
  • 为每个用户生成固定数据的训练数据
    • 避免loss被少数特别活跃的用户影响
  • 去除视频观看的序列特征
    • 论文中给出的解释是:可能模型没有对负反馈进行很好的建模
  • 不对称浏览行为
    • 利用上下文预测中间行为(下面的更好)
      • 很多协同过滤系统其实就是基于上下文预测中间行为
    • 利用上文信息预测接未来行为(这个更好)

Exploration & Exploitation

探索与利用问题是强化学习中一个基础概念

场景举例

公司附近有很多餐馆,我们已经尝试过几家,并有了一个基本的评价。如果我们想得到最大化美食带来的体验,我们应该如何选择餐馆?

探索:我们随机的选择餐馆,以得到对更多餐馆更精确的评价。如果餐馆数量特别多,这样需要大量的尝试,效率太低。
利用:我们只选择已经掌握评价信息的餐馆。最大体验被限制,如果体验次数太多,会带来体验下降的风险。

折中的策略是:大部分时间利用(exploitation),同时以一定的概率探索(exploration),这就是探索-利用平衡。

排序模型

排序模型是在候选生成模型的基础上,实现对粗筛之后的候选视频的精准排序。在模型设计上,排序模型采用了和候选生成模型类似的模型架构设计,只是在模型的输入层和输出层进行了修改。

模型结构

模型输入

不同于候选生成模型需要对海量的视频进行处理计算,排序模型需要处理的只是经过一系列粗筛之后得到的小规模视频集合。所以,排序模型可以使用更加复杂的特征作为模型的输入,以期达到更为精准的排序目的。

另一方面,候选集生成模型最终是为了得到用户和视频的向量,而排序模型就是对最终用户是否会点击视频进行预测。所以,两者输入特征的构成也是有区别的。

样本特征

待预测视频的ID、用户历史观看视频列表、用户语言、视频语言、最近视频观看时间、待预测视频的历史观看次数

关于输入特征处理的一些技巧

  • 对同源特征使用编码的共享,可以实现模型训练的加速和效果提升

    • 例如用户语言和视频语言、待预测视频ID和历史观看视频ID列表这种,属于同源特征
  • 连续特征可以增加对特征的开方、平方,以挖掘特征的非线性关系

    • 例如最近视频观看时间、待预测视频的历史观看次数

模型输出

排序模型解决的是点击预测的二分类问题,所以,最终输出使用了经典的logistics:

$$ P(y=1) = \dfrac {1} {1 + e^{-(Wx+b)}} $$

但是为了达到更直接的推荐效果,排序模型应该能够把那些期望观看时间更长的视频尽量往前排。所以,在模型训练的时候,对损失函数加入了视频观看时长$T$的加权:

$$ loss = \dfrac {1} {N} * \sum^{N}_{i=1} {T_i} [y log P(y=1) + (1 - y) log (1 - P(y=1))] $$

这里的$N$表示样本数量。需要说明的是,对于负样本的$T_i=1$。

线上服务使用下面的公式来预测视频的期望观看时长:

$$ E[T] = e^{Wx + b} $$

线上预测公式的推导

$$ odds = \dfrac {P(y=1)} {1 - P(y=1)} = \dfrac {\sum T_i} {N - k} = \dfrac {\dfrac {1} {N} * \sum T_i} {1 - \dfrac {k} {N}} = \dfrac {E[T]} {1 - clickRate} \approx E[T] $$

$$ odds = \dfrac {P(y=1)} {1 - P(y=1)} = \dfrac {\dfrac {1} {1 + e^{-(Wx+b)}}} {1 - \dfrac {1} {1 + e^{-(Wx+b)}}} = \dfrac {1} {1 + e^{-(Wx+b)} - 1} = e^{Wx+b} $$

总结

这篇论文可以说是干货满满。虽然模型设计并没有给人眼前一亮的感觉,但是文章中给出的很多知识点还是很值得工业界学习的。大家有时间可以拜读一下原文,也希望这篇文章能对大家更好地理解原作提供帮助。