提示:最近系统性地学习推荐系统的课程。我们以小红书的场景为例,讲工业界的推荐系统。
我只讲工业界实际有用的技术。说实话,工业界的技术远远领先学术界,在公开渠道看到的书、论文跟工业界的实践有很大的gap,
看书学不到推荐系统的关键技术。
看书学不到推荐系统的关键技术。
看书学不到推荐系统的关键技术。
王树森娓娓道来**《小红书的推荐系统》**
GitHub资料连接:http://wangshusen.github.io/
B站视频合集:https://space.bilibili.com/1369507485/channel/seriesdetail?sid=2249610
基础知识:
【1】一文看懂推荐系统:概要01:推荐系统的基本概念
【2】一文看懂推荐系统:概要02:推荐系统的链路,从召回粗排,到精排,到重排,最终推荐展示给用户
【3】一文看懂推荐系统:召回01:基于物品的协同过滤(ItemCF),item-based Collaboration Filter的核心思想与推荐过程
【4】一文看懂推荐系统:召回02:Swing 模型,和itemCF很相似,区别在于计算相似度的方法不一样
【5】一文看懂推荐系统:召回03:基于用户的协同过滤(UserCF),要计算用户之间的相似度
【6】一文看懂推荐系统:召回04:离散特征处理,one-hot编码和embedding特征嵌入
【7】一文看懂推荐系统:召回05:矩阵补充、最近邻查找,工业界基本不用了,但是有助于理解双塔模型
【8】一文看懂推荐系统:召回06:双塔模型——模型结构、训练方法,召回模型是后期融合特征,排序模型是前期融合特征
【9】一文看懂推荐系统:召回07:双塔模型——正负样本的选择,召回的目的是区分感兴趣和不感兴趣的,精排是区分感兴趣和非常感兴趣的
【10】一文看懂推荐系统:召回08:双塔模型——线上服务需要离线存物品向量、模型更新分为全量更新和增量更新
【11】一文看懂推荐系统:召回09:地理位置召回、作者召回、缓存召回
【12】一文看懂推荐系统:排序01:多目标模型
【13】一文看懂推荐系统:排序02:Multi-gate Mixture-of-Experts (MMoE)
【14】一文看懂推荐系统:排序03:预估分数融合
【15】一文看懂推荐系统:排序04:视频播放建模
【16】一文看懂推荐系统:排序05:排序模型的特征
【17】一文看懂推荐系统:排序06:粗排三塔模型,性能介于双塔模型和精排模型之间
【18】一文看懂推荐系统:特征交叉01:Factorized Machine (FM) 因式分解机
【19】一文看懂推荐系统:物品冷启01:优化目标 & 评价指标
【20】一文看懂推荐系统:物品冷启02:简单的召回通道
【21】一文看懂推荐系统:物品冷启03:聚类召回
【22】一文看懂推荐系统:物品冷启04:Look-Alike 召回,Look-Alike人群扩散
【23】一文看懂推荐系统:物品冷启05:流量调控
【24】一文看懂推荐系统:物品冷启06:冷启的AB测试
【25】推荐系统最经典的 排序模型 有哪些?你了解多少?
【26】一文看懂推荐系统:排序07:GBDT+LR模型
【27】一文看懂推荐系统:排序08:Factorization Machines(FM)因子分解机,一个特殊的案例就是MF,矩阵分解为uv的乘积
【28】一文看懂推荐系统:排序09:Field-aware Factorization Machines(FFM),从FM改进来的,效果不咋地
【29】一文看懂推荐系统:排序10:wide&deep模型,wide就是LR负责记忆,deep负责高阶特征交叉而泛化
【30】一文看懂推荐系统:排序11:Deep & Cross Network(DCN)
【31】一文看懂推荐系统:排序12:xDeepFM模型,并不是对DeepFM的改进,而是对DCN的改进哦
【32】一文看懂推荐系统:排序13:FNN模型(FM+MLP=FNN),与PNN同属上海交大张楠的作品
【33】一文看懂推荐系统:排序14:PNN模型(Product-based Neural Networks),和FNN一个作者,干掉FM,加上LR+Product
【34】一文看懂推荐系统:排序15:DeepFM模型(Factorization-Machine),xDeepFM可不是对DeepFM的改编哦,而是对DCN的改编
【36】一文看懂推荐系统:经典双塔模型:微软DSSM模型(Deep Structured Semantic Models),无特征交互,后来美团改进了
【37】一文看懂推荐系统:Gate网络(一):新浪微博GateNet,GateNet就是想用attention的方法去搞,和SENet一样,都是张俊林的杰作
【38】一文看懂推荐系统:Gate网络2:百度GemNN(Gating-Enhanced Multi-Task Neural Networks)
提示:文章目录
这篇发表在RecSys’16上的文章,距今已经有些年头了,
初读这篇论文是在18年的时候,如今从实习到工作已3年多时间,
再次重温,心中还是不禁感叹『经典』二字,
还是那句话:『谷歌出品,必属精品』,
虽然这句话不是完全的对,但适用大部分谷歌发表的paper。
谷歌的paper中总是带着强烈浓厚的工业实践风,这也是我个人比较喜欢的,
有些论文你看一眼模型结构图基本就领会了这篇论文的80%-90%,
但YouTubeDNN这篇论文,如果你只看模型结构图,也许只能领会20%-30%。
当然任何商业公司的论文都会基于保密性的出发点,在论文中隐去核心的东西,
所以有时候有一些细节的隐去会导致论文晦涩难懂,YouTube这篇论文也不例外。
YouTubeDNN包含召回和排序两个模块,
目前这个时间点再去按照实用价值评价YouTubeDNN的话,其召回价值大于精排价值,
因为目前精排迭代的模型已经很多了,基本上不会有公司使用YouTubeDNN的精排了,
其召回应该还应用的很广,目前在我们自己的业务中就有一路YouTubeDNN的召回。
本篇博客将会从三个大的方面介绍YouTubeDNN:
YouTubeDNN召回
1.1 优化目标
1.2 样本构造
1.3 高效的训练多分类模型
1.4 YouTubeDNN召回的模型架构
1.5 YouTubeDNN召回在线
YouTubeDNN排序
这是本篇博客的重点,也是目前实用价值更大的一块,下面来具体谈一谈:
YouTubeDNN召回模块没有把CTR作为优化目标,
而是预测用户下一个观看的视频(next watch),
也就说给定一个用户及上下文后,在候选集(所有视频)
中挑选用户在下一次最可能观看的视频(next watch,这里一般是topK个),
因此即转化成了一个多分类问题(数百万),
这里使用一个softmax输出在所有候选视频上的概率分布。
再来看YouTube这里样本的构造,
这里把用户看完的视频作为正样本(注意是看完的,也就是完成播放的,而不是看了的)。
YouTube这里也解释了为什么没有使用YouTube上面『点赞』和『踩』这种显式反馈作为正负样本,
因为使用完播这种隐式反馈所能构造出来的正样本比显式反馈的『点赞』多了一个数量级。
正常情况下,用户看完一个视频去点一下『赞』这种行为是比较少的。
这里有必要说下训练样本是怎么构造的,
感觉也是个非常大的细节。
就拿我们自己的日志举例子吧,我们的原始日志都是item级别的**(有曝光的item)**,
一条原始日志由<item信息,用户信息,上下文信息,是否点击>组成,
我们在抽取训练样本时,只抽取有点击的item,
显然该点击的item就为生成的训练样本的label,
然后我们需要去用户过去X天点击的item序列,用户过去X天query历史,以及一些该item相关的特征等。
YouTube这里介绍了一个trick,
就是每个用户抽取的训练样本数量是相等的,
这样做主要是为了防止活跃用户主导整个模型。
这是一个非常好的trick,大家可以借鉴。
此外还有个非常非常重要的点,大家可以思考下:
当我们在做精排模型时,如果训练样本全都是这个模型曝光出去的item会不会有问题?
答案是显而易见的,这会导致精排模型『自嗨』也就是自我学习,
它在排序的时候会非常倾向于把自己之前排出去过的再次排出去,
没见过的新内容露出的可能性非常小。
由此又涉及到另一个主题EE,即Explore&Expliot。
YouTube这篇论文也提到了这个问题,原话如下:
Training examples are generated from all YouTube watches (even those embedded on other sites) rather than just watches on the recommendations we produce. Otherwise, it would be very difficult for new content to surface and the recom- mender would be overly biased towards exploitation.
YouTube这里的类别数量达到百万的级别,采用softmax来训练显然效率很低。
至于效率为什么低,似乎这个话题又回到了谷歌另一篇旷世之作word2vec论文里了,
这里简单说一下,因为softmax的分母,每一次都要对语料库中所有的item计算一次。
因此,word2vec里提出了两种解决办法:负采样(negative sample)和分层的softmax(hierarchical softmax)。
YouTube这里并没有创新什么方法,也是在自己的场景下通过实验比较了下两种方法,
最终选了一个效果比较好的方法:负采样。
提到负采样就不得不提NCE(Noise-Contrastive Estimation,噪声对比估计),
负采样为NCE的一个变种,NCE通过较大化正样本的概率,
同时最小化负样本的概率来优化目标函数,
也就是在训练每个样本时, 负采样只挑选DNN的部分权重做小范围更新,
举个例子:假设我们的视频语料库大小为1000个,
一条训练样本为{x=A, y=B},即输入特征A,期望的label为B,
即期望B对应的那个神经元为1(最后softmax层),
其余的999个神经元都应该输出0,
也就是视频语料库中除了B之外的999个视频都称之为negative word,
negative sample的做法是随机选择一小部分比如10个negative word来更新对应的权重参数。
这里自底向上的看一下整体模型结构:
1.4.1 特征
这里特征大的方面就两类:类别特征和连续值特征。
具体主要包含用户历史观看的视频序列,用户搜索的query切词,以及用户DMP特征。
对于序列特征,比如用户历史观看的视频,分别对每个视频做完embedding后直接做了个average pooling,
当然现在回过头的话你还可以做各种attention。
YouTube这里有两个trick:
简单的类别特征(比如年龄等二值的)以及连续值特征,直接输入,
并且做了normalization压缩到[0,1]范围内,也就意味着压缩到同一量纲。
从模型结构图能够看出连续值特征还做了x 2 等非线性转换,
实验结果表明对连续值特征做非线性转换有0.2%的性能提升。
特殊特征Example Age: 这是一个非常巧妙的特征,
也完全是YouTube工程师基于对自己场景深刻理解所设计的一个特征,
设计这个特征的出发点是:YouTube工程师观察到YouTube平台上的用户比较喜欢新内容。
关于这个example age到底怎么计算这个细节论文并没有交代的很清楚,
我个人的理解加上参考了一些资料后,
认为是用当前训练时间减去label(视频item,也就是点击的那个item)的点击时间。
更详细的说,我们一般原始日志都是item级别的,即曝光的item,
一条原始日志由
我们在根据原始样本抽取特征生成训练样本时,
这时候如果直接产出Example Age,其实就是用抽取时间减去label item的点击时间,
当然也可以在训练时再产出这个特征,具体哪个方法还要看具体的效果。
有个点就是在线上预估时,直接把这个特征置为0,用于确保预测时处在训练的最后一刻。
1.4.3 网络结构
虽然是一个普通的DNN,但有一个细节非常值得探讨,先来上图。
YouTubeDNN在线召回的架构与DSSM非常类似,
先离线产出item向量,存到ANN索引库里,
在线的时候,用户向量通过模型实时生成,
再去ANN库里根据内积召回topK个item。
这样做的好处非常明显:
item向量离线生成,节省了在线servering的耗时
因为用户行为时刻变化,用户向量实时生成可以捕捉到最新的用户表达。
关于YouTubeDNN的召回就介绍到这里,下面开始介绍YouTubeDNN的排序模型。
推荐领域,排序模型目前已经迭代了非常多,
因此目前应该没有公司还在用YouTubeDNN的rank模型,因此这一块的重要性不如召回。
2.1 特征工程
这一块也算是YouTubeDNN的良心了,
分享了一些对模型性能影响比较大的特征,
虽然每个场景都不一样,但可借鉴下。
总的来说,YouTubeDNN精排模型特征包含两大类:类别特征和连续值特征。比较重要的一些特征包括:
用户历史与item交互的一些特征,比如点击统计量
召回通道号及召回时得分这两个特征
另外就是多值特征embedding直接做了average pooling,
这里参考DIN实际上可以做个attention。
另外就是不同特征中涉及的同一个item的embedding是共享的,
比如曝光的video列表,观看的video列表,这两个特征交集的video的embedding是共享的。
另外还有一些trick:
连续值normalization,
YouTube发现对连续值特征做normalization非常有利于DNN的收敛,
原话为:We found that proper normalization of continuous features was critical for convergence.
连续值特征的非线性变换,比如x 2,l o g x ,sqrt{x} 等,这种变换对于提高模型准性非常有用。
做视频的embedding时,对于长尾视频,直接把其embedding用0来代替。
实际上,目前在工业界这种做法不多了,通常的做法是把长尾的特征直接干掉。
也有一种做法,就是把长尾特征分个类,相当于做了个聚合,直接用聚合后的id代替。
召回模块建模为一个多分类问题,优化目标是next video。
而排序时,优化目标则是**expected watch time,**即视频期望观看时长。
看到这里大家可能第一反应是:既然要优化期望观看时长,
那为什么不搞个回归模型,而还要搞个分类呢?
这个问题我也不知道,如果有懂得大佬可以评论区留言。
既然是二分类,首先正负样本依然是曝光已点击的视频,
负样本为曝光未点击的样本,那么如何和expected watch time这个连续值结合在一起。
这里YouTubeDNN的做法是把正样本的观看时间作为权重,
相当于给正样本做了加权。
这个权重会直接作用到损失函数中,也就是weighted cross entropy。
例如,正常的二分类交叉熵函数如下所示:
提示:如何系统地学习推荐系统,本系列文章可以帮到你
(1)找工作投简历的话,你要将招聘单位的岗位需求和你的研究方向和工作内容对应起来,这样才能契合公司招聘需求,否则它直接把简历给你挂了
(2)你到底是要进公司做推荐系统方向?还是纯cv方向?还是NLP方向?还是语音方向?还是深度学习机器学习技术中台?还是硬件?还是前端开发?后端开发?测试开发?产品?人力?行政?这些你不可能啥都会,你需要找准一个方向,自己有积累,才能去投递,否则面试官跟你聊什么呢?
(3)今日推荐系统学习经验:youtubeNet已经很古老了,适合召回,反正就是搞清楚usr embedding的过程呗,配合item embedding,就可以做双塔模型召回了,另外,独特的场景,考虑独特的特征,很重要,视频推荐,图文推荐,美食推荐,各有不同的场景的