推荐系统基础

概要01:推荐系统的基本概念

推荐内容

曝光-点击-停留几秒(有效点击而不是手滑)-阅读(滑动到底)-点赞-收藏-转发-评论

每个产品的转化流程不一样,抖音没有曝光和点击

image-20250121221639446

短期消费指标:评估推荐的效果

  • 只关注这些,多样性会很差,让用户失去兴趣

归一化函数跟笔记长度有关,不然对长笔记不公平

image-20250121221712866

长期消费指标:小红书使用的,表示金标准,比短期指标更重要

  • 不管一天、一个月登陆几次,DAU和MAU都是一次

image-20250121221843662

离线实验:不需要部署,不占用线上流量,不影响实际用户和产品

线上实验:北极星指标只能通过线上实验获得

  • 小流量测试:把用户随机分为A\B,实验组是新策略,对照组是旧策略。如果新策略显著好,就可以加大流量最终推全。

image-20250121222413159

概要02:推荐系统的链路

TODO:截断不是很懂,应该是带着打分分数进入重排

召回:从物品数据库(很多笔记,每个通道取回一些)选用户可能感兴趣的几千篇笔记

粗排:规模小的机器学习模型给笔记逐一打分,用分数截断,保留分数高

精排:规模大的神经网络打分,可以做截断或者不做截断,小红书不做排序和截断

重排:根据精排分数和多样性分数随机选择,打散,加入广告和运营内容

image-20250121222958629

小红书有几十条召回通道

融合:去重、过滤(去掉用户不喜欢的作者和话题)

排序分为粗排和精排,减少工作量

  • 精排的特征多,网络层多,计算量大,分数更准确

重排:主要是考虑多样性,随机抽样,用规则把内容相似的笔记打散

注意数字都是随便说的,只是举例子,不是公司真实使用的

image-20250121223409699

神经网络结构各异,输出很多数值,是对用户行为的预估。分数是加权和,表示是否曝光,以及笔记曝光的位次

image-20250121223639138

重排:相似的笔记要打散,生态要求(比如前面不能全是美女图)

image-20250121223848229

粗排也会有一些规则,保证多样性

重排的规则非常复杂

漏斗很重要,如果笔记数量过大就用不了MMR和DPP了

image-20250121224656955

概要03:推荐系统的AB测试

基本原理

离线实验有提升,上线不一定也提升

小流量:只给一小部分用户,如随机选的10%

还可以测试参数,如深度学习网络的层数,哪组效果好就用哪个

image-20250122235853012

如果用户数量足够大,那DAU/留存/渗透率这些指标都是相等的

image-20250123000227474

三个桶的参数分别是1/2/3层,四号桶没有用GNN。每个用户落在哪个桶,策略都不一样。

推全:流量扩大到100%

image-20250123000336058

分层实验

分层实验:解决流量不够用的问题。比如分为10个桶,同时只能做9组实验,但AB测试需要很多桶(组)。

image-20250123000442613

解决方案:分层实验。把实验分为很多层,同层互斥(避免一个用户同时被两个召回实验影响),不同层正交(召回2号桶和粗排2号桶可交集小)

image-20250123000632860

数学形式表示:u/v对用户来说各有10种选择,所以交集有100种选择

image-20250123000851578

image-20250123000923532

用户界面和召回不会互相影响,所以同时进行正交实验image-20250123000952882

两组召回实验(两种策略)可能同时对指标造成影响,所以要控制变量image-20250123001158072

Holdout机制

实验叠加到一起往往效果会折损,holdout用于整体比较(融合每层后的结果)

image-20250123001402250

image-20250123001553244

推全是完成一次实验的完整覆盖,让所有用户都体验到新策略

划分后接近为0是实验开始前的理想状态,随着实验diff增大,说明策略有正反馈或负反馈

image-20250123001701419

实验推全&反转实验

diff正向则推全,推全会影响非holdout的用户,diff理论上会扩大9倍(原来是10%,现在是90%)

其实就是比如说一个新的召回策略应用到90%的用户上,但因为其他层正交所以仍然可以做其他层的实验,经过考核周期就扩大到holdout

image-20250123002428361

有些指标需要长期观测,但尽快推全也有好处,这个矛盾用反转实验解决

开反转桶:用旧策略。一个考核周期结束后,holdout会被清除而推全,但反转桶不会。大概就是即使推全,也留一个桶不推,做这个AB test一段时间

image-20250123002606406

image-20250123002726825

image-20250123003012979

先在10%->推全到90%->推全到holdout 100%(为了看长期指标用反转实验,其实还是推全到90%)

召回

召回01:基于物品的协同过滤(ItemCF)

CF:协同过滤的缩写

通过用户的好评行为知道相似

image-20250206173414283

通过对旧物品的兴趣*旧物品与新物品的相似度预估对新物品的兴趣

如果有2000个候选物品,逐一计算分数,然后返回分数最高的物品

image-20250206173605028

物品相似度

image-20250206174337908

边表示用户喜欢的物品

image-20250206174431430

image-20250206174450093

开根号是为了保证sim在0-1之间,因为|v|<|w1|,|v|<|w2|,|v|*2<|w1|*|w2|

image-20250206174713032

不考虑喜欢的程度:喜欢看作1,不喜欢看作0

考虑喜欢的程度:对同时喜欢i1,i2的用户v求喜欢程度的乘积,分母是对物品i1和i2的兴趣分数

image-20250206181219940

用户对j感兴趣,传递到候选物品,就是用户对候选物品的兴趣:需要知道sim和like

兴趣分数:比如点赞、收藏、转发、评论各算1分,相加就是兴趣分数(最高4分)

为什么是余弦相似度?因为物品i1,i2是两个向量,向量值是用户对物品的偏好(只考虑用户和物品有交互时的非零元素),余弦相似度关注的是向量在方向上的相似性,而不是向量的长度,取值为0-1(0不相似,1相似)

image-20250206200006154

完整流程

事先做离线计算:k=10/100

image-20250206200828024

image-20250206201002736

image-20250206201028689

线上做召回:last-n是用户最近交互过的列表

image-20250206201133143

索引:即已经离线计算好了like和k个sim,让兴趣分数好计算,计算量没那么大

image-20250206204920148

使用上面列表的兴趣分数和下面列表的相似度分数即可获得兴趣分数

image-20250206205010813

总结

根据用户的行为而不是物品的类别,判断物品相似

image-20250206210403430

该条召回通道很重要,需要维护两个索引(通常用哈希表记录key-value):用户->物品,物品->物品

image-20250206210457906

召回02:Swing 模型

ItemCF的变体:唯一的区别是定义物品的相似度

image-20250207132123475

如果重叠部分V多,那两个文章的相似度就高

不足之处:两篇不同的笔记完全不同,但分享到同一个微信群,所以小圈子里的人都交互过两个物品

  • 解决:避免小圈子,设置用户权重

image-20250207132220762

image-20250207132325747

α是人工设置的参数,需要调。用overlap可以降低小圈子对sim的影响。

image-20250207132422907

总结

如果u1,u2来自同一个小圈子,对物品相似度的贡献比较小

image-20250207132553746

召回03:基于用户的协同过滤(UserCF)

ItemCF基于物品相似度,UserCF基于用户相似度

image-20250207202056466

实现:离线算好每两个用户的相似度,然后利用相似用户对候选物品的兴趣,预估当前用户对候选物品的兴趣

  • 相比ItemCF就是把sim(item)变成了sim(user)

image-20250207202222778

用户相似度

相似表示兴趣点相似,喜欢的物品类似

image-20250207202315520

image-20250207202324870

以物品作为集合(相比item以用户作为集合)image-20250207202352155

越热门的物品对用户相似度越没有价值,因为大家都喜欢。重合的冷门才更有可能是同行image-20250207202521368

权重相同时:分子是|I|image-20250207202555981

权重不同时:让热门物品的权重降低(nl大)

image-20250207214121164

image-20250207214300906

完整流程

离线计算:建立两个索引

image-20250207214737694

image-20250207214746476

image-20250207214802175

召回通道:从nk种选出100个物品,因为有索引所以很快

image-20250207214829668

image-20250207214906587

总结

image-20250207215045114

image-20250207215117345

召回04:离散特征处理

前三节课是协同过滤召回,后面几节课介绍向量召回。

one-hot编码和embedding

离散特征有很多种类型,所以难处理。每个用户id会映射成一个向量。

image-20250207215313490

one-hot:200个国家,就是200维的向量

image-20250207223010306

one-hot

image-20250207223903310

image-20250207223935861

局限性:维度太大,性别2维可以,物品ID和单词太高维了

image-20250207223952525

Embedding

每个类别是低维稠密向量

如国籍这里的大小是4*1,未知国籍是全0(如可以是浮点数0-0.0001,可以表示9999个数)

image-20250207224112792

神经网络中的反向传播会自动学习embedding参数,这里的参数矩阵是(4,200)

image-20250207224247842

一个神经网络绝大多数的参数都在embedding层(嵌入向量),所以会对其进行存储和效率的优化

image-20250207224339989

如果神经网络训练的好,相似的embedding会更靠近

image-20250207224530325

每个embedding都是参数矩阵的一个列(红色部分)

image-20250207224648195

总结

image-20250207224750337

召回05:矩阵补充、最近邻查找

输入是两个ID(a,b都是参数矩阵的一列),输出是用户对物品兴趣的预估值,即内积

模型有两个embedding层,不共享参数

image-20250208153848054

训练

image-20250208153911866

image-20250208153942667

矩阵AB是需要学的,数据集是已知的

image-20250208154104075

训练:定义优化问题的目标函数

image-20250208154155770

为什么叫矩阵补充?用绿色位置的值预估灰色位置,是该训练的目的

image-20250208154336164

缺点:用属性可以弥补id embedding信息不足的问题

image-20250208154510715

负样本:在学术中可以,但在实践中效果不好

image-20250208154653795

工业界使用余弦相似度和交叉熵

  • 回归和分类都是对输入做出预测,并且都是监督学习
  • 分类(classification)将实例数据划分到合适的类别中。例如 判断网站是否被黑客入侵(二分类 ),手写数字的自动识别(多分类),多目标分类(多分类)。输出的是物体所属的类别(工业界用分类判定正负样本)
  • 回归(regression)主要用于预测数值型数据。例如: 股票价格波动的预测,房屋价格的预测等。输出的是物体的

image-20250208154726718

线上服务

训练好模型后,把模型用作召回通道,即可在用户刷xhs时快速做推荐

模型存储:矩阵很大(几亿维),存储成key-value表

image-20250208155648729

查找:逐一计算a和每个物品向量bi的时间复杂度非常大,如何优化?用近似最近邻查找

image-20250208155811523

衡量最近邻的标准:目前推荐系统最常用的是余弦相似度。有些系统不支持余弦相似度,很好解决,把所有向量做归一化,让分母等于1,这样内积就等于余弦相似度

image-20250208161316569

image-20250208160736528

每个点是物品的embedding向量,用户的id是a

如何避免暴力枚举?数据预处理,把数据划分成很多区域(用cosine相似度就是扇形,用L2就是多边形)

每个区域用一个向量表示,向量的长度都是1,把向量作为key,区域里的每个物品点作为value

假设有一万个向量(一万个key),给定一个向量可以快速取回该区域内所有的点(类似聚类的分层查找)

image-20250208161447184

有了向量索引后,把a和向量对比,找到最近的向量。再计算a和区域内所有点的相似度

如果有几亿个物品被划分到几万个区域,平均每个区域只有几万个点,计算量也不大。找最相近的三个点(夹角最小的三个点)

image-20250208161756838

image-20250208161909569image-20250208161959930

总结

image-20250208162051510

image-20250208162317819

召回06:双塔模型——模型结构、训练方法

模型结构

image-20250208163941252

对于性别等类别少的特征,用one-hot即可,可以不做embedding

连续特征:年龄、活跃程度、消费金额等

神经网络可以是简单的全连接,也可以是复杂的深度交叉等,输出是用户的表征,做召回要用到这个向量

image-20250208164209991

image-20250208164235649

双塔模型:模型最终的输出是内积,评估用户对物品的兴趣

现在更常用的是余弦相似度,就是先做归一化再做内积,大小位于-1到+1之间

image-20250208175100444

训练方法

image-20250208175306714

负样本的选择各厂商不同image-20250208175451497

Pointwise训练

image-20250208175619177

Pairwise训练

物品正负样本的embedding层是相同的,用一样的参数和全连接层获得表征

image-20250208231023835

跟pointwise的区别是每个训练样本是三元组,希望损失函数越小越好

image-20250208231115341

还有其他的损失函数:还是让cos(a,b-)尽量小,cos(a,b+)尽量大。σ是大于0的超参数,需要手动设置

image-20250208231229048

Listwise训练

这里的负样本打错了

image-20250208231430457

类似对比学习

softmax输出的s分数介于0-1之间,希望s+越大越好接近1,s-接近0

最小化交叉熵,作为损失函数(虽然损失函数与负样本无关,但softmax用到了负样本)

image-20250208231643978

总结

image-20250208231756261

以下是粗排/精排模型,而不是召回模型:

分别提取用户和物品的特征,前期融合(进入全连接前就拼接)不是召回,召回是后期融合(两个塔在输出相似度时才连接起来)

不适用的原因是需要把所有的用户和物品输入。假设有1亿个物品,每给用户做一次召回,模型就要跑一亿次,计算量很大,且用不了近似最近邻优化

  • 双塔神经网络输出的是用户和物品的复杂embedding,可以离线存储,支持用最近邻查找来优化计算,因为已经知道向量
  • 前期融合神经网络直接输出的是相似度,不知道复杂向量,只知道特征变换后的简单用户/物品特征,这不足以获得离线的用户向量和物品向量 ,所以不能用最近邻查找

这种模型通常用于排序,从几千个中选出几百个

image-20250208232406149召回07:双塔模型——正负样本

image-20250209205516113

image-20250209205817567

如何选双塔模型的负样本?在不同阶段有着不同表现的样本

  • 这里的图和后文有矛盾,被曝光但没被点击不能作为负样本

简单负样本:针对没有被召回

几乎和全体物品一样

image-20250209211910691

注意打压热门物品:0.75是经验值

image-20250209211953140

选取正样本的标准是一个用户点击了一个物品,而与剩下的物品都是负样本

image-20250209212042086 image-20250209212302179

n个用户,n个物品,组成n个正样本,n(n-1)个负样本

image-20250209221619378

但注意这样做需要修正偏差,即让热门物品称为负样本的概率减小:-logpi让物品没有那么热门,有等价的结果

image-20250209224018572image-20250209224108896

困难负样本:针对粗排、精排淘汰

image-20250209224413504

image-20250209224437935

注意不能使用曝光但没有点击的物品作为负样本,双塔模型效果会变差

  • 只要被曝光了的物品都通过了排序(粗排+精排),不作为负样本
  • 因为召回的任务是区分用户感兴趣和不感兴趣的物品,而不是可能感兴趣和非常感兴趣的物品

image-20250209224608597

能曝光就说明很感兴趣了(已经很匹配了,理论上是正样本),只是相比其他的没有那么有兴趣

image-20250209224948254

总结

image-20250209225041406

召回08:双塔模型——线上服务、模型更新

线上召回

模型训练好之后,可以部署到线上做召回,让用户迅速找到感兴趣的200篇笔记

将物品存入数据库,方便最近邻查找;而对用户线上计算向量a,作为query在数据库找出k个最相近的笔记(最近邻查找)

image-20250211154737769

image-20250211154920984

建索引:把向量划成很多区域,每个区域用一个向量表示

image-20250211155111460

建好索引后,可以开始做线上召回

image-20250211155159455

用户现算的开销少,虽然也可以离线计算,但工程效果一般,也因为用户兴趣动态变化。相比之下,物品特征相对稳定,短期内不变化。

image-20250211155302895

模型更新

全量更新:用前一天的数据更新神经网络和向量数据库(更新索引),对速度要求不高,不需要实时数据流,延迟1/2h也没关系,员工只需要每天凌晨把数据落表、批处理、打包成TFRecord即可

image-20250211180014890

增量更新:每隔几十分钟就把模型发布出去,需要实时数据

  • 早上刷xhs感兴趣的内容,中午就要重新做推荐
  • 全连接层的参数是锁住的,不作更新,只更新embedding层参数(应该指特征变换层对用户ID的处理,出于工程实践的考量)
  • 最新的用户ID Embedding会考虑到最新的兴趣,注意用户向量包括ID embedding和离散/连续的用户特征,所以还是要线上计算用户向量

image-20250211180654716

全量:shuffle打乱(为了消除偏差)、随机梯度下降、1 epoch

  • 完成新一天的全量更新后,增量更新就可以不要了
  • 只做增量更新效果不好,有偏差,从早到晚并不好;而且全量更新全参数

image-20250211224421798

image-20250211224544590

总结

image-20250211224630502

image-20250211224703264

image-20250211224729091

召回09:双塔模型+自监督学习

自监督学习可以改善双塔模型的业务指标(让物品塔做得更好)

image-20250215180517351

点击数据是正样本,长尾物品的曝光和点击少,所以表征学习的不好

  • 自监督改良的方法来自谷歌,可以复现

image-20250215180637066

(用户-点击过的物品)是正样本,和没点击过的物品组成负样本

image-20250215180755311

让模型给正样本打分尽量高,给负样本打分尽量低

image-20250215180841750

n个概率值pi,1-n,正样本的概率值应该接近1。希望pi尽量接近yi,通过和标签对比获得交叉熵

  • 以下是ListWIse的损失函数,希望损失尽可能小

image-20250215181133908

纠偏:让热门物品稍被打压。训练结束,线上召回时,用原本的相似度cos,说明只在模型训练时做纠偏

image-20250215181415578

加入纠偏后的损失函数:batch中有n个用户,所以会求平均

image-20250215181627034

自监督学习训练物品塔

对比学习进行数据增强,对于同一个物品的两个变换,应该相近,和不同变换的相似度应该小

image-20250215182143737

image-20250215182218146

特征变换

random mask:正常是对数码和摄影分别做embedding,mask以后替换为默认值或掩码值,作用是数据增强、防止过拟合、模拟缺失数据image-20250215214021359dropout:仅对多值离散特征,随机丢弃一些而不是全部(与mask区分)

  • mask:把全部类目特征都丢掉

image-20250215214242551

互补:正常是4种分别做embedding,然后一起放入物品塔。这里分组后得到表征。由于是对同一个物品的表征,这两个物品表征应该很相似,训练时要鼓励cos相似度尽量大。

image-20250215214601807

第四种:随机遮住一组关联的特征

  • 受众性别是一种特征,物品类目又是一种特征,但UV不是独立的而是存在关联,某些p(u,v)的概率会大
  • 两个特征关联越强,p(u,v)越大,互信息MI越大

image-20250216141114876

image-20250216141239106

比如如果选择受众性别作为种子,那最相关的特征里面就有类目特征,把种子和相关特征都mask掉

image-20250216142959824

该种变换的推荐指标更好,但复杂:需要计算两两之间的MI,如果新加了一个特征需要算所有特征的MI,在工业界考虑投入产出比,这样开发了也不好维护,不太划算。

image-20250216143132730

总结:用其中任何一种变换方法都可以。

image-20250216143438813

训练模型

这里只抽物品,冷门物品和热门物品被抽到的概率是相同的

  • 和双塔区别,双塔根据点击行为抽样,正样本为用户点击的物品,热门物品抽中的概率大

image-20250216143911394

损失函数如何得到的?把第i个物品和m个物品的特征作比较,经过softmax得到m个概率值。如果物品塔足够好,正样本cos应该大,概率值接近1,其他m-1个概率值接近0。让si接近yi,交叉熵计算时把si,i替换为softmax的输出。训练时需要最小化损失函数

Softmax 函数将输入向量转换为概率分布。假设有一个输入向量
$$
\mathbf{z} = [z_1, z_2, \dots, z_n]
$$
,Softmax 函数的输出
$$
\ \mathbf{p} = [p_1, p_2, \dots, p_n]
$$
定义为:

$$

p_i = \frac{e^{z_i}}{\sum_{j=1}^n e^{z_j}}

$$
其中:

  • ( z_i ) 是输入向量的第 ( i ) 个元素。
  • ( p_i ) 是输出概率分布的第 ( i ) 个元素,表示类别 ( i ) 的概率。
  • 分母是所有 ( e^{z_j} ) 的和,确保输出的概率分布总和为 1。

交叉熵的标准公式用于衡量两个概率分布 ( P ) 和 ( Q ) 之间的差异,公式如下:
$$

H(P, Q) = -\sum_{i} P(i) \log Q(i)

$$
其中:

  • ( P(i) ) 是真实分布 ( P ) 中第 ( i ) 个事件的概率。
  • ( Q(i) ) 是模型预测分布 ( Q ) 中第 ( i ) 个事件的概率。

在分类任务中,( P ) 通常是真实标签的 one-hot 编码,( Q ) 是模型的预测概率分布。交叉熵越小,表示预测分布 ( Q ) 越接近真实分布 ( P )。

image-20250216145202739

一个batch有m个物品,所以取平均,训练时梯度下降使损失最小

image-20250216145255641

总结

数据存在低曝光的问题(头部效应),谷歌提出自监督学习改善物品数据本身的问题,对比双塔物品的item embedding学的更好了,点击率等指标得到提升

image-20250216145429348

双塔和自监督用的是一个物品塔(神经网络),训练时两个损失会同时被计算(α控制比例),然后更新用户塔和物品塔的参数。

image-20250216145621515

召回10:Deep Retrieval 召回

idea是把物品表示为路径,然后查找用户最匹配的路径

image-20250216152159004

image-20250216152242797

索引

每层有k个节点,路径之间可以有重合节点

image-20250216152418092

item->List:训练神经网络时用到这个索引

  • 如果有3层,就用3个节点表示路径

path->List:线上作召回时用到这个索引

image-20250216152613307

预估模型

预估用户对路径的兴趣,可以召回多条路径

p1/p2/p3都是神经网络输出的预估结果,相乘即为预估的兴趣

image-20250216152809734

向量p1对应L1层,k个元素是神经网络给L1层打的分数,分数越高则越有可能被选中。根据分数用beam search选出小a。

对x和a的embedding作拼接(concatenation),输入给新的神经网络

p1/p2/p3对应L1/L2/L3,选择abc后组成了一条路径

  • 三层神经网络不共享参数

image-20250216153228897

线上召回

image-20250216153402295

beam size越大,计算量越大,search结果越好。

image-20250216154214965

第一层神经网络给节点打分,得到k个分数,size=1则只选一个节点(比如选分数最高的节点)

用第二层神经网络给k条路径打分(5到1-k),仍然只选一条路径

再用第三层神经网络给k条路径打分(5到4到1-k)

image-20250216153818702

p1/p2/p3是三层的输出,刚才beam size=1时分别最大化了p1/p2/p3,但这种贪心不保证总概率最大,所以size越大越可能达到最优(最优的路径数量是k*3,但每条路径都打分计算量太大了,size可以让最大计算量是size*size*k)

image-20250216153956649

size=4时,最终得到的路径数为4(也有可能超过4,但路径数一定小于size*3)

image-20250216154440263

image-20250216154521041

两个例子分别召回1/4条路径、线上已经有索引了,可以得到很多物品,可能会超过推荐的配额,所以需要再排序选出分数最高的子集,作为召回的物品

  • 排序模型没有限制,可以用双塔模型

image-20250216155538442

训练

image-20250216161054742

如果用户点击过物品,则用户对物品对应的所有j条路径都感兴趣。依然用交叉熵作损失函数。

  • 神经网络的作用是判断用户是否对某条路径感兴趣,所以点击过的分数应该更高

image-20250216161603224

把用户作为物品和路径的中介,即可得到相关性分数,如果关联高就可以把路径作为item的表征

  • 物品表征和神经网络的兴趣分数没有先后之分,是同时学习的。最开始的物品路径表征应该是随机的。

image-20250216161936313

image-20250216162056907

score是相关性分数,理论上选分数高的j条路径,但会出现少数路径上有很多物品。为了平衡,用正则项约束path。

  • 如果某条路径的物品过多,会用正则项惩罚。

image-20250216162545491

假设已经有了j条路径表示物品,会选出新的路径l(满足损失函数+正则项符合要求)

  • TODO似乎没讲l路径是否会顶替j路径的细节,j是通过相关性获得的,但相关性中的p也会因为j而变化,具体如何交替训练,物品表征该如何更新估计还得看论文

image-20250216162741504

交替做两部分的训练

  • 训练预估模型神经网络时,物品是中介,关联用户和路径
  • 更新物品表征时,用户是中介,关联物品和路径(利用的依然是上面的预估模型,计算相关性)
  • 总之都利用“用户点击过物品”这一客观行为,路径和兴趣都是人为设置的参数来建模这一过程

image-20250216163638065

总结

本质是路径是用户和物品的中介(双塔是用向量表征)

  1. 双塔使用单向量召回,导致召回结果集中在单个topic上。字节做deep retrieval的目的是多兴趣召回(multi-interest)。deep retrieval召回多条路径,每条路径是一个兴趣点,所以属于multi-interest。
  2. 据说抖音已经下掉了deep retrieval,因为有了更好的模型。
  3. 这是抖音实际在用的multi-interest retrieval,建议读一下:Trinity: Syncretizing Multi-/Long-tail/Long-term Interests All in One

image-20250216164053928

image-20250216164304517

召回11:地理位置召回、作者召回、缓存召回

重要性稍低的召回通道

地理位置召回

GeoHash:经纬度编码成二进制哈希码,方便检索。将它作为优质索引,记录地图上一个长方形区域内的优质笔记,最新的笔记在最前面。因为没有个性化,所以要用优质笔记,才有可能通过后面的粗排和精排。

image-20250216164834875

只要用户允许定位,就会取出k篇优质笔记,至于哪些感兴趣后面排序再找。

image-20250216164912104

同城召回:唯一的区别是以城市作为索引(而不是经纬度),城市是现在和曾经生活过的城市。

image-20250216165147693

作者召回

xhs会推送关注作者的笔记

image-20250216223409029

有交互的作者召回:不关注也会推送。交互作者列表会定期更新

image-20250216223601239

相似作者:基于itemCF判断相似,sim(i1, i2)(用户的粉丝相似)

image-20250216224459583

缓存召回

精排的结果被浪费了,只因为随机抽样没被抽中,如何利用?

image-20250216224645521

缓存大小固定,先入先出。被召回10次指的是作为召回通道的结果进入排序,并不是指到了最后曝光的那一步,所以与成功曝光就退场不冲突

  • 还可以有更复杂的规则,如低曝光的笔记(指曝光给其他用户少的笔记)在缓存中停留时间更长

image-20250216224854687

总结

image-20250216225533202

召回12:曝光过滤 & Bloom Filter

召回阶段做曝光过滤,具体的方法是Bloom Filter

实验表明重复曝光同一物品会影响用户体验(但youtube这样的长视频没有)

本来就只召回1个月内的笔记,所以只需要记录1个月内的曝光历史

image-20250217164653797

暴力对比计算量很大,n、r都是千级,所以要用bloom filter过滤(可能会误伤)

image-20250217164953811

image-20250217165142987

有映射的地方为1,就可以把6个物品映射成一个01向量

哈希函数数量为1时,召回的物品映射到0,说明一定没有曝光,不会被误判;但映射到1时可能会被误判,如ID8

image-20250217165400234

k=3,有3个哈希函数时,把映射到的3个位置都设置为1

只要有一个为0,则未曝光,这里不会误判;仍然可能把未曝光误判为已曝光

image-20250217165649880

曝光的物品越多,误伤概率越大

image-20250217165741474

比如设置δ为1%,即可以得到最优参数k和m,m比n大几倍,说明每个物品占用的bit并不多

image-20250217165932720

画红圈的前端部分刷新要足够快,在用户下次刷新时就要处理,写入二进制向量,否则下一刷可能会有重复物品

  • 所以用实时流处理,比如把曝光物品写入kafka消息队列,用flink做实时计算,实时读取消息队列,计算曝光物品的哈希值,把结果写到bloom filter的二进制向量上。曝光发生几秒后,就可以更新向量(实时流处理是很重要的模块,不能轻易挂掉)
    • 根据已曝光物品,完成向量计算
  • 曝光过滤具体用在召回完成之后,召回服务器请求曝光过滤服务,服务将这位用户的二进制向量发送给召回服务器,在召回服务器上计算召回物品的哈希值,再与二进制向量做对比,把已经曝光的物品过滤掉,剩余的都是未曝光的,发送给排序服务器。
    • 完成召回物品计算,与向量对比
    • image-20250217170118351

缺点:不支持删除物品,因为不能把物品对应的1改为0,会误伤其他物品

这导致每天移除年龄大于1个月的物品时,需要重新计算整个集合的二进制向量,不能复用之前的向量。

image-20250217171330543

排序

排序01:多目标模型

召回:通道很多,几亿->几千

粗排、精排:给笔记逐一打分,不截断,带着分数进入重排

重排:多样性抽样,相似内容打散,最后有几十篇笔记展示给用户

排序的依据是对笔记的兴趣,会记录下列交互的行为

image-20250217172617685

点击率差不多有10%-20%,点开才会有后续的点赞、收藏、转发。转发少但是很重要

image-20250217172701336

排序打分的依据:权重是AB测试调出来的,当然很多融合方式比加权和要好

image-20250217172754778

多目标模型

排序模型的输入是各种特征

统计:包括用户和候选物品的各种特征,如在过去30天的统计数据

场景:随着用户请求传过来,包括时间、地点,如同城、周末、节假日都会影响兴趣。

神经网络:可以是简单的全连接,也可以是wide and deep等更复杂的结构

神经网络输出的向量输入4个神经网络,每个有2-3个全连接层,最后是sigmoid介于0-1之间

推荐系统排序主要靠这4个预估值,反映用户对推荐系统的兴趣

image-20250217173530051

训练时,让p1-p4拟合目标,α根据经验设置

image-20250217180527619

困难:负样本很多,影响训练效果和效率。降采样后,样本数量减少,训练时间减少

image-20250217180629182

预估值校准:因为负样本降采样了,模型对正样本更乐观了

image-20250217180736586

使用降采样时的参数α做校准,拿校准之后的点击率p_true作为模型对物品的预估

image-20250217181004572

总结:多目标模型可以预估点击率、点赞率等指标,做了负样本的降采样后,要对预估值做校准。

排序02:Multi-gate Mixture-of-Experts (MMoE)

改进的模型

三个神经网络都有许多全连接层组成,但不共享参数,各输出一个向量,实际中专家通常是4个或者8个。

这些特征又输入到另外两个神经网络,p和q都是后面要用来加权平均的权重

image-20250217200043391

神经网络的输出取决于具体的任务(预估什么业务指标),比如点击率就是0-1的实数

假设多目标模型只有点击率和点赞率两个目标,所以这里只有pq两组权重。如果有10个目标就要10个权重。

image-20250217200343427

专家神经网络的数量是一个超参数,需要手动调,一般是4个或8个。

极化现象和解决方案

只使用某一个专家,而不是融合多专家,那么MMoE就相当于上文只使用一个神经网络的普通多目标模型

image-20250217200855027

dropout:强迫每个任务根据部分专家来预测,一般不会发生极化,不然神经网络的预测结果特别差。

image-20250217201154580

image-20250217201204751

MMoE不一定有提升,如果公司没有用很可能是用了之后没效果。

排序03:预估分数融合

多目标模型输出了对点击率、点赞率等指标的预估,这节课讲如何融合这些指标,得到分数用于排序

分母可以是曝光,两种都很常用

image-20250217203822971

p_time是预估的用户观看时长,超参数w/α需要线上AB测试手动调

image-20250217203944060

预估时长越长,排名越靠前,得分就越高

这里分数不是用p,而是用每个指标的排名r

image-20250217204156377

α1-4需要调,假设都是1,那公式就是实际的营收额,具有实际意义

image-20250217204257425

排序04:视频播放建模

视频播放时长

图文和视频的排序依据不同,时长和完播是视频最重要的指标

回归是预测数值型的目标值,如房价、股价;分类是预测有限的、离散的类别标签

直接回归的效果不好,youtube论文效果最好

image-20250217205028579

神经网络被叫做share bottom,被所有任务共享

对z做sigmoid得到p,让p拟合y(最小化交叉熵CE),t是用户实际观看视频的时长,我们希望用exp(z)作为播放时长的预估

交叉熵的设计是基于概率的,所以要把输出z加sigmoid,同时把y也限制在(0,1),这样损失函数的范围也是好计算的

image-20250217205547426

p只用作训练,线上做推理用的是exp(z)image-20250217205612689

实践中,把分母1+t去掉也没问题,相当于给损失函数做加权,权重是播放时长t

  • 1+t本来就是归一化,去掉后并不会影响模型的训练效果,因为梯度下降算法会自动调整学习率,使得模型能够有效地学习。
  • 加权的意思是当 t 较大时(即播放时长较长),t⋅log(p) 这一项会占据更大的比重,模型会更关注那些播放时长较长的样本。

image-20250217210411051

最后exp(z)会影响视频排序

视频完播

预估完播率会与播放时长、点击率、点赞率等指标一起作为完播依据

image-20250217210538497

image-20250217210633613

直觉上,时长越长,完播率越低,如果直接用完播率对短视频有利

用函数f拟合蓝色曲线,放在分母上像归一化了一样

image-20250217210809126

image-20250217210859668

排序05:排序模型的特征

用户属性记录在用户画像中

ID本身没有有用得信息,但用于作embedding

账号信息:模型需要对新用户和低活用户做优化

image-20250217215409779

物品画像:发表的时间越久,价值越低,尤其是八卦等强时效性信息

笔记内容:包括标题、类目等,通常对这些离散的内容特征作embedding变成向量

字数等笔记自带的属性反映出笔记的质量,笔记的点击和交互指标与这些属性相关

信息量、美学是算法打的分数,事先用人工标注的数据训练cv和nlp模型,当新笔记发布时,用模型给笔记打分,把信息量这些分数写到物品画像中,这些分数可以作为排序模型的特征

image-20250217215752674

统计值:用各种时间粒度反映用户的兴趣

对图文/视频作分桶,对笔记类目分桶

  • 分桶(Binning)是一种将连续数据或类别数据划分为多个离散区间(即“桶”)的技术。

image-20250217220205079

年龄分桶、地域分桶等

作者特征反映了作品的平均质量

image-20250217222630106

场景特征:随着推荐请求传来。

  • 不同时间想看的事情不一样
  • 手机设备:安卓苹果的特征区别很大

image-20250217222742756

特征处理

离散特征embedding比较简单,消耗内存不多

连续特征:

  1. 分桶:年龄等可以one-hot或者embedding
  2. 其他变换:曝光数等指标是长尾分布,大多数都是几百次,极少数才是几百万次。如果直接输入,特别大的数值会让计算异常,如做梯度下降和预估值都很奇怪,这样的特征要用log做变换。或者转换为概率,同时做平滑,去掉偶然性产生的波动(如减少噪声和极端值)。
    1. 注意其他变换的log后的点击数、点击率都可以同时作为特征输入,并不重复

image-20250217223204414

以下特征都有用,只是在特征的选择和处理上会贴近业务场景。

image-20250217223326711

特征覆盖率:特征工程时,要想办法提高特征覆盖率,还要思考缺失时用什么作为默认值。

image-20250217223406334

线上服务

推荐系统拥有三个数据源,都存在内存数据库中。线上服务时,排序服务器会读取数据,然后做特征处理,然后给模型,模型就能预估出点击率、点赞率等指标。

image-20250217223446261

召回结束后,召回服务器会把几十路通道的结果作归并,把几千篇笔记的id返回给主服务器。召回需要调用用户画像(ID、离散、连续)

主服务器传一个用户ID和几千个物品ID,还有场景特征(用户ID和场景特征来自用户请求)给排序服务器,排序服务器从三大数据源中取回特征(用户画像和统计压力小,就1个用户,但物品画像和统计要返回几千篇召回笔记的特征)

  • 用户数据库可以向量可以很多很大,但尽量不要往物品画像塞很大的向量,否则物品画像会承受很大的压力

  • 用户画像较为静态,性别年龄几乎不变,兴趣也基本是以天刷新的

  • 物品画像几乎是完全静态的,物品自身的属性和算法给物品打的标签在很长时间内不会变化

    • 对用户和物品画像,最重要的是读取速度快,而不太需要考虑时效性,有时甚至可以缓存到排序服务器本地,让读取更快
  • 但是统计数据是动态变化的,时效性强,点赞一篇就都会变,要尽快刷新统计数据库,不适合缓存在本地

排序服务器把特征打包传递给TF Serving。tensorflow会给笔记打分,把分数返回给排序服务器。

排序服务器会用融合的分数、多样性分数还有业务规则给笔记排序,把排名最高的几十篇笔记返回给主服务器,就是最终给用户曝光的笔记

image-20250217224504232

排序06:粗排模型

前面的模型主要用于精排,这节看精排怎么做。

image-20250218232754654

精排模型:”Concatenation”(串联、连接),shared bottom的意思是被多个任务共享

精排模型的代价主要在神经网络,因为很大也很复杂

属于前期融合

n次推理的原因是每次物品特征仅针对一篇笔记,所以如果有n篇候选笔记则模型要做n次推理

image-20250218232926460

image-20250218233159667

双塔模型:用于召回,物品的embedding存在数据库,在线上不需要物品塔做计算,线上服务仅用物品塔,每做一次推荐用户塔只做一次推理,计算出一个向量a,所以双塔模型的计算代价很小,适合召回。

image-20250218233428995

image-20250218233502298

三塔模型

image-20250218233519172

训练的方法跟精排差不多,就是端到端

介于前期融合和后期融合之间

image-20250218233601984

每个用户做一次推荐,粗排要给几千个物品打分。输出向量可以缓存在prompt server,由于缓存物品塔在线上几乎不用做推理,只有用到新物品时才需要做推理(相当于一次粗排只需要给几十个新物品打分,计算量还好,所以物品塔的规模可以比较大)

交叉塔的输入会实时变化,所以不应该缓存输出向量,线上推理避免不掉,所以交叉塔需要足够小+计算够快,所以交叉塔通常只有一层,宽度也比较小。

image-20250218234604037

其实还是跟双塔很像,相比精排就是把shared拆开了,针对各自特征的特点做了缓存和层数的设计

image-20250218234740329

总结:无论有多少个候选物品,用户只需要做一次推理;物品塔输出的向量先缓存在prompt server上,没有物品缓存时说明是新物品,才需要物品塔做推理。最坏的情况下,物品塔需要做n次推理,实际上缓存命中率很高。交叉塔必须做n次推理,因为是动态特征。

上层网络必须做n次推理,因为没有缓存,粗排大部分计算量都在上层网络。

image-20250218235136011

特征交叉

在召回和排序中都会用到

特征交叉01:Factorized Machine (FM) 因式分解机

现在已经不太常用了

对d个特征的连加,w是权重。这里p没用线性函数,如果做二分类,可以用sigmoid。b是偏移项

特征之间只有加,没有乘,说明特征没有交叉

image-20250219171356152

有交叉可以让模型更准确,xi*xj是交叉,这样既有交叉也有相乘,如房屋大小和每平米单价是两个特征,相乘的话很有用

大多数参数是交叉特征的权重u,如果d很大,参数数量会太大,容易出现过拟合(因为特征稀疏等)

image-20250219171651217

如何减少参数数量?对矩阵U做低阶近似,k是超参数,k越大V越接近U。用vivj代替uij,作为交叉特征的权重

  • U是d*d,V是d*k,这样U=V*V^T

让推理的代价更小,而且不容易过拟合

image-20250219173139885

image-20250219173342004

FM就是在线性模型后面加上交叉项,所以可以替代

推荐系统中,FM显著比线性模型好。早期的推荐系统通常使用逻辑回归预估点击率,用FM做特征交叉,不过xhs早就下掉了。

image-20250219173648153

特征交叉02:DCN 深度交叉网络

用来代替简单的全连接网络,效果更好,可以用来排序和召回

image-20250219184722425

image-20250219184806259

image-20250219184817009

交叉层

输入是x0,经过i层交叉层输出xi,下面是第i层的结构(前面也经过了这样的层)

哈达玛乘积:逐元素相乘

image-20250219185153126

xi和z分别是输入和输出,两个向量的维度是一样的

最后的相加类似ResNet中的跳跃连接

交叉层的参数全部在全连接层里面,其余的操作是哈达玛乘积和向量加法,没有参数

image-20250219185331347

输入是x0和xi,哈达玛乘积要求左右两边的向量维度相同

把输入与输出相加,就是ResNet中的跳跃连接,深度学习中防止梯度消失的常用技巧

输出xi+1与x0/xi是一样的

image-20250219185931694

交叉网络

不断把x0(最底层向量)输入给每一个交叉层,层数随意设置

image-20250219190134552

第二篇论文是交叉网络的原始版本,现在已经没用了,看第一篇改进版就好

image-20250219190202818

DCN:可以用于召回/排序,双塔中的物品塔和用户塔都可以是DCN,多目标模型中的Shared Bottom,MMoE中的神经网络也可以是DCN

image-20250219190301704

特征交叉03:LHUC (PPNet)

只能用于精排

image-20250219203037445

对语音做表征,然后得到文字。说话人的特征可以帮助语音识别

神经网络包括多个全连接层,最后一个激活函数是sigmoid*2,单独作用在每个元素上,所以蓝色向量的每个元素在(0,2)

最后的特征是语音信号结合了说话者特征的最终表征,有个性化

层数也可以增加(弹幕说是毫无头绪的结构工程还挺贴切)

image-20250219203317358

乘以2可以把说话者的特征放大,让个性化更明显

image-20250219203357616

下面只需要把特征类型替换成推荐系统的,实现精排时的个性化。

image-20250219203509269

特征交叉04:SENet 和 Bilinear 交叉

SENet

image-20250219212431614

对矩阵的行做AvgPool,得到一个行向量,向量的每个元素对应一个离散特征,如第一个元素对应用户id

用一个全连接层和Relu激活函数,把m维向量压缩乘m/r维向量,r是压缩比例,设置为大于1的数

再恢复m维向量

然后row-wise multiply:中间m维向量的作用就是对特征做加权,比如学出物品id特征不重要,就给它降权

image-20250219213513482

上图为了方便把m个离散特征全部映射为k维向量,但是注意m个向量的维度可以不同,不会影响SENet

image-20250219213750820

Field:用户ID是一个离散特征,对应一个向量,算一个Field(一行)

两个FC训练出来的权重向量是m*1的,重要的Field权重高,不重要的Field权重低

Field-Wise就是按域的方式,即针对不同的 field(如这里不同的 Embedding 向量整体作为一个 field)分别进行加权操作,每个 field 内的元素共享相同权重,是在 field 这个维度 / 层面上开展的加权处理方式。

image-20250219215824304

Field间特征交叉

两个field做交叉,得到新的特征

内积得到一个实数,m^2个实数还好,m的量级也就几十,不算很大

m^2向量量级有点大了,哈达玛必须要人工选一些特征做交叉,而不能对所有的field两两交叉

要求每个特征形状一样,都是k维向量,如果形状不一样就不能计算

image-20250219220009340

Bilinear Cross有内积和哈达玛乘积两种方式

  • 内积:xi和xj的形状可以相同也可以不同image-20250219220240036

    image-20250219220249634参数矩阵的参数量可能很大,需要人工指定相关的、重要的特征做交叉。

    • 除以2是因为xi和xj,xj和xi是一样的权重,可以复用
  • 哈达玛乘积:向量数量太大,也需要人工指定做交叉,而不是所有特征都两两交叉。既可以减少参数数量,也可以让contactenation之后的向量变小。

    image-20250219220437746

SENet可以用注意力矩阵理解,就是让重要的特征权重更大

image-20250219220605044

FiBiNet

image-20250219220639598

连接后的高维向量,以前就直接把这个特征和其他特征拼起来,输入排序模型,效果也不错

做Bilinear Cross

做SENet,加权后再Bilinear Cross(xhs没用这个,好像有些多余)

红色部分是FiBiNet的改进,用在精排上确实有提升,但实践中xhs和这个区别挺大

image-20250219222027627

行为序列

行为序列01:用户历史行为序列建模

last-n:用户最近交互过的n个物品

last-n很有效,用到召回和排序中指标都会涨,last-n属于多目标模型中的用户特征

image-20250311184258212

n个物品id映射成多个多个向量然后平均,可以作为用户的一个特征,表示曾经对哪些物品感兴趣

image-20250311184406160

用户还有其他特征,比如用户id、连续特征、离散特征,把特征拼接起来作为用户特征输入神经网络

image-20250311184511709

xhs的召回、粗排、精排都用到了last-n,分为点击/点赞/收藏不一样

现在attention比平均效果更好,但计算量更大

不止用物品id,还有物品种类等其他特征,把不同embedding拼接到一起效果比只用id好

image-20250311184603173

行为序列02:DIN模型(注意力机制)

对last-n序列建模的一种方法,效果比简单平均好

加权平均代替平均

image-20250311184831050

粗排选出500个,精排的候选物品就是这500个

计算相似度的方法有很多,如内积、cosine

权重就是相似度,可以计算出加权和

image-20250311185011080

预估的候选物品指标可以用作后续的排序,一般用于精排

image-20250311185049403

紫色向量:可以看作对用户last-n历史记录的表征,反映出用户的兴趣,作为一个用户特征,跟其他特征一起作为精排模型的输入

召回时的用户塔看不到候选物品,只能看到用户特征,有上亿个物品(太多不可能作为候选),所以din不用于双塔、三塔模型

image-20250311185247857

行为序列03:SIM模型(长序列建模)

目的是保留用户的长期兴趣

din的缺点:计算量大,只适合n小的情况。n大指标肯定会上涨,但计算量代价也大,性价比不高

image-20250311190427309

改进思路:让n变大,能够保留长期行为序列,但这样计算量也大了?用权重接近0的last-n物品去掉也区别不大,可以降低计算量

image-20250311190552361

根据候选物品的类目,快速排除掉绝大多数的last-n物品,只保留最相关的topk

image-20250311190833268

查找:

  1. 根据规则:不需要做训练,如比较类别就行,简单
  2. 根据物品最近邻查找(类比itemcf):对比向量相似度,auc更高,计算代价更高

一般hard就够了,编程实现容易,线上运行速度快

image-20250311191037337

区别在于last-n变成了top-k,紫色向量几乎不变

image-20250311191237370

小trick:记录用户与每个物品交互发生的时刻离现在的时间,把离散的时间变成区间,把时间也作为物品的表征

image-20250311191404691

紫色向量就是对用户兴趣的表征

image-20250311191446627

为什么din不用,sim要用?

  • din几乎都是近期的,sim的last-n的n值比din大(这样才能保留长期行为,以及需要减少到topk),时间可以反映重要性

image-20250311191731828

结论:查找+平均,查找+注意力,后者效果更好。soft search的预估准确率优于hard search,但后者实现更容易,基建够好才能用soft(速度/计算量)

image-20250311191855772

重排

重排01:物品相似性的度量、提升多样性的方法

多样性做的好,可以提高留存等

曝光的物品两两不相似,多样性就高

基于内容的特征最好:如用cv/nlp学到得到图片、文字的特征向量

image-20250311201638509

加权求和可以得到总分,权重要根据经验设置

image-20250311201745573

通过向量表征计算相似度:内积/余弦相似度大

但物品塔处理不好新物品和长尾物品,最终多样性的效果差

image-20250311201907076

该如何训练CNN和BERT?

image-20250311201942804

CLIP:基于图文内容的物品向量表征

图片和文字不同时是负样本

image-20250311202039576

image-20250311202132016

提升多样性的方法

只用打分,不用考虑物品之间的关联。pointwise指每个样本独立评分,而不是混合训练

image-20250311202246154

对于粗排,n等于几千;对于精排,n等于几百

后处理为了保证多样性,如果不考虑多样性,直接对reward进行排序选出topk即可

  • 工业界中后处理可以提升业务指标,所以要加

image-20250311202435081

重排:决定哪k个物品得到曝光,以及曝光的顺序

粗排后的后处理也是有用的,实验可以验证

image-20250311202554089

重排02:MMR 多样性算法(Maximal Marginal Relevance)

MMR从搜索排序中来,Relevance的意思是相关性,搜索的结果根据相关性做排序,后面用作推荐排序,用于精排的后处理阶段。MMR会决定物品最终的曝光顺序,通常会带滑动窗口。

精排中n的大小是几百

sim(i,j)可以是物品标签计算出的,也可以是向量表征计算出的

结合reward和sim对物品做重排

image-20250311203839766

给未选中的物品打分,i是未选中的物品,j是已选中的物品,如果和已选中的物品相似度大,则起反作用,MR的分数会变小小。θ平衡物品的价值与多样性

image-20250311204151199

多次循环,每次选一个R中的物品移到S(局部最优的贪心算法,滑动窗口某种程度上也可以增加灵活性,类比正则化增加泛化能力)image-20250311204346090

滑动窗口

工业界的重排都会使用滑动窗口

就是把S变成了W

解释性:没必要让第30个物品和第1个物品不相似,因为用户已经忘了,离得远的两个物品可以相似,不会影响用户体验

image-20250311204623109

重排03:业务规则约束下的多样性算法

工业界有许多规则,做重排时都要被满足,规则的优先级高于多样性算法

图文和视频要交叉

image-20250311205356091

限制运营推广

image-20250311205440368

限制首屏笔记的广告数量

image-20250311205527997

R是未选中物品的集合

重排既要考虑MR也要考虑规则,方法是排除掉R中的部分物品,如现在选第4篇笔记,而第2篇已经选了电商卡片,此时把R中的电商卡片全部过滤掉,在R’中选择MR最高的物品

image-20250311205757495

重排04:DPP 多样性算法:数学基础

行列式点过程 (determinantal point process, DPP):就是把物品作为向量,在特征空间里面以体积来衡量多样性

从一个集合中选出尽量多样化的物品

image-20250311214329755

3维空间的平行体是平行六面体

image-20250311214424378

v1…vk是超平行体的边

如果让超平行体有意义,则需要线性相关,不然体积为0

image-20250311214656969

image-20250311214726981

image-20250311214808589

image-20250311214845060

平行六面体的体积:

image-20250311214917386

image-20250311215010781

衡量物品多样性:保证d>=k是因为如果向量数大于维度,必然线性相关

image-20250311215301221

行列式=超平行体体积的平方。多样性越好,体积越大

image-20250311215406498

重排05:DPP 多样性算法(下)

DPP是保证重排时多样性的方法

image-20250311215708665

我们把DPP公式应用于推荐系统中,列出从n个物品中选出k个物品的方案

image-20250311215838982

image-20250311220204449

Hulu

贡献在于快速求解这个公式,需要巧妙的算法

S表示从n个物品中选出的k个物品,这里定义A=(V_n^T)(V_n), V是(d,n)维的,为了As方便计算所以先把A计算出来

image-20250311220417256

把未选中的物品i和已选中的物品As比(类比MMR,就是把相似度换成超平面体体积了),计算相似度作为负值作用于价值上,让选出的物品既要有价值,又要有多样性

image-20250311221755501

i有n种选择,S有k种选择,矩阵行列式的计算复杂度为O(n^3)

image-20250311222301134

不懂这里的计算矩阵A是为啥要计算(复杂度的过程倒是在上面有证明),老师说是会不断用到子矩阵,可以理解As∪{i}中会不断用到,但又觉得O(|S|^3)已经包括了原始计算,TODO看证明

n的量级是几百,k和d的量级是几十,不可行,因为系统给重排的时间是10ms左右,太慢了image-20250311223027479

快速算法

必须计算矩阵A,所以有n^2d,因为算法运行过程中不断用到子矩阵

image-20250311230928960

image-20250311231010534

利用了As的特点,降低了计算代价

image-20250311231052973

DPP扩展

跟MMR中的优化一样

image-20250311231126680

image-20250311231346261

用规则过滤

image-20250311231418641

物品冷启动

物品冷启01:优化目标 & 评价指标

推荐系统中最复杂的一环

UGC:user generated content 内容是用户自己上传的 PGC(Platform…):Netflix之类的平台上传内容

UGC更难

image-20250312120733782

新笔记缺失交互,用正常的链路很难得到的曝光

image-20250312120853988

image-20250312120947375

作者侧:反映作者的发布意愿

用户侧:反映推荐是否精准。大盘指标,加入冷启动后的消费指标应该和原来持平

内容侧:反映冷启是否能挖掘优质笔记

作者侧和用户侧都在用,内容侧只有少数的厂用

image-20250312121136852

作者侧的发布渗透率、人均发布量,人均发布量比发布渗透率要大,因为一些作者一天会发好几篇笔记

image-20250312121232136

image-20250312121259352

image-20250312121409672

用户侧:看新笔记的消费,基尼系数是用于衡量不平等程度的指标,通常用于评估收入或财富分配的不平等性。

区分高曝光是为了防止少数影响了指标,低曝光的笔记推荐不容易做好

image-20250312121522390

增加低曝光,用户体验会下降,所以希望大盘的消费指标基本持平,不影响用户体验

image-20250312121815230

内容侧:高热笔记的占比

image-20250312121859812

普通笔记一般只看用户侧指标,而不看其他两个,说明新笔记的处理更复杂

image-20250312121937148

流量向新笔记倾斜

image-20250312122001942

物品冷启02:简单的召回通道

召回的难点:新笔记没有交互的依据,所以ItemCF这种需要like程度的做不了,ID向量也是通过交互学的,是召回和排序中最重要的特征之一,而冷启的id还是刚初始化没经过反向传播的

image-20250312122214377

缺少ID embedding同时影响召回和排序,绿色笔记作为新笔记没有交互

image-20250312122336606

image-20250312122424815

image-20250312122501224

改造双塔模型

ID Embedding通过embedding层,新笔记学的不好

image-20250312122542634

共享default embedding,是学出来的(反向传播?),比随机初始化和全民初始化更好

image-20250312122647153

相似物品的embedding,相似可以用文字、图片、类目来定义,寻找topk的相似高曝光

image-20250312122809344

实践中,用多个召回池,让新笔记得到曝光的概率增大

image-20250312122843768

类目召回

有些是用户填写的,有些是算法推断的(这里不讲用户冷启动,所以默认有知道的类目和关键词)

image-20250312123109778

维护从类目到笔记的索引,最新发布的笔记在最前面,这样取回topk时就包括新笔记

image-20250312123151659

image-20250312123219104

关键词:原理完全一样

image-20250312123315875

缺点:只对新笔记有效,因为刚发的在最前面,但过了几小时后就没有可能召回了,排在几百/几篇了

弱个性化:可能我喜欢鱼,但新发的几百篇都是猫猫狗狗

优点:让新发布的笔记立刻得到曝光,增加作者积极性

image-20250312123415513

物品冷启03:聚类召回

通过新笔记的特征向量,判断和1000个cluster哪个最相似,然后把笔记id添加到索引上

image-20250312125540767

image-20250312125738261

把n中每篇笔记映射到向量,然后得到cluster,然后在cluster的索引中取最新的笔记,就可以让新笔记得到曝光

缺点:只对刚刚发布的新笔记有效,发布1/2小时就不行了

image-20250312130020424

内容相似度模型

提取图文特征:笔记中只有1张图是比较简单的

image-20250312130229279

BERT是预训练好的,也可以做微调;CNN也是预训练好的,比如在ImageNet上做训练,然后微调。全连接层是随机初始化的,需要在数据中学习。

  • 说这里和CLIP的区别是,这里是融合模态样本之间的对比学习,CLIP是跨模态的对比学习,不过都能学笔记的特征向量

image-20250312130302278

训练用三元组(种子笔记,正样本,负样本):种子笔记通常是高质量、代表性样本、

image-20250312130723887

正样本:与种子笔记相似

image-20250312130838767

image-20250312130913565

历史喜欢的笔记是last-n,映射成向量然后找cluster

image-20250312131051871

物品冷启04:Look-Alike 召回

互联网广告的常见方法,也可以用于推荐系统

起源于互联网广告

image-20250313174311393

如何发现目标用户?看相似的用户,找到的相似用户就是Look-Alike用户

image-20250313174351647

如何评估两个用户的相似度

image-20250313174436125

用于新笔记召回

image-20250313174645291

充分利用新笔记的交互行为(因为不多),用双塔模型学到的用户向量求平均,可以反映新笔记的特征

近线更新:不用实时更新,做到分钟级的更新就行了,有新的交互就更新。在线实时更新做不到,也没必要。

image-20250313174731396

image-20250313174917977

把新笔记的特征向量放在向量数据库里(milvus或者face数据库),用双塔模型计算用户的特征向量,把该向量作为query在向量数据库中进行最近邻查找,取回几十篇笔记

image-20250313175236252

总体逻辑就是用交互过的用户表示笔记特征,这样相似用户就能在向量数据库中找到,和广告中原理相同

image-20250313175830193

物品冷启05:流量调控

image-20250313180314571

提升积极性

image-20250313180940152

假设公平竞争,新笔记占比为1/30,但现在有单独的扶持

image-20250313181208577

强插新笔记(落后)、boost(调权重,让新笔记排序分数大点)、保量(也是提权,如保证每篇新笔记在前24小时获得至少100次曝光)、差异化保量(刚发布时根据保量的质量决定目标是多少次曝光,内容质量高保量的目标就定的高,给更多流量倾斜)

image-20250313181445817

链路:如果不用规则干涉,那么新笔记的曝光机会有限

image-20250313181603747

干涉粗排和重排,会过滤掉大量笔记,方法就是提权,让新笔记的排序有优势

image-20250313181657136

image-20250313182517783

保量

差异化对待不同的发布时间(动态提权保量),发布久了会把系数增大,让曝光机会增大

image-20250313182654653

image-20250313182742222

第一个数越大,第二个数越小,提权系数就应该越大

难点:

image-20250313182846676

image-20250313182909402

能否给一个很大的系数?显然质量会比较低,用户体验差。大幅提升笔记,即使不是感兴趣话题,也会被曝光。所以不能用这样粗暴的方法!

image-20250313183105631

image-20250313183200173

保量的目标由算法判定,达到最大值(如500)后就不进行新笔记扶持,正常与老笔记竞争

image-20250313183232914

image-20250313183323501

总结:保量是大厂核心部门才做,坑很多,但做的好指标

image-20250313183404412

物品冷启06:冷启的AB测试

用户侧指标也叫消费侧指标

image-20250314114313419

image-20250314114619793

可以用来考虑大盘指标

image-20250314114708768

image-20250314114810386

实验组的消费指标变差,对照组会变好,所以diff大,但是推全后diff缩小,因为保量是一样的,相当于看到新笔记的用户占总用户的比例相比AB实验变小了,所以diff变小了

image-20250314114846651

作者侧不太好做,AB测试观察到的diff不可信,可能上线后会消失

抢流量:实验组加权后,对照组(也是新笔记)相当于降权了,发布指标就有diff;如果把新策略推全,新笔记的权重都有加权,就不存在两组新笔记抢流量,就没有diff。

image-20250314115156836

image-20250314115324954

第二个缺点是新老笔记也会抢流量,导致AB测试的结果在推全后不一样,新笔记原来抢2份老笔记,现在抢1份老笔记

image-20250314115639755

image-20250314115750900

方案二:用户也被分成两组,避免两组新笔记抢流量,AB测试的结果更可信。问题是内容池减少了,现在待选笔记的可选范围变少了

image-20250314115952335

image-20250314120030697

方案三相当于切成了2个APP,内容池减少一半,用户体验一定会下降

image-20250314120113667

AB测试和推全后是怎么抢的?保量的话,在实验组曝光多了,对照组自然就曝光少了

image-20250314120227199

涨指标的方法

涨指标的方法01:概述

LT的增长一般对应用户体验。LT=总活跃天数/今天活跃的用户数(DAU)

低活减少后,分子减少,但分母减少的更多,LT会增长

image-20250314120613437

长视频导致刷的视频总数减少。曝光数涉及广告收入,时长涉及留存,要对两者做平衡。

image-20250314121024123

image-20250314121106789

DAU和留存是最核心的。前两部分是模型,有很多资料,后三部分是业界的非公开内容。

image-20250314121150855

涨指标的方法02:召回

召回总量不变,添加新的召回模型会挤占其他模型的配额,不会增加计算量

只需要训练一个双塔模型就可以用于多个内容池,如用在3个内容池得到3个召回通道,每条通道有一定的配额。每个内容池需要ANN索引,还需要ANN检索,需要一定的计算量。

  • ANN是近似最近邻,通过牺牲一定的精度来显著提高查询速度。

image-20250314141853316

双塔模型

随机组合大概率不被喜欢

困难是被召回,但排序阶段排名后被淘汰

image-20250314142613212

DCN:深度交叉网络

行为序列建模:最近交互的物品是n,把n个向量的平均作为用户特征输入用户塔

标准的双塔模型是单向量模型,两个塔各输出一个向量,两个向量的形状相同。

image-20250314142906350

物品塔和单向量模型没有区别,用户塔输出很多向量,每个向量和物品向量的形状相同,可以计算内积/cosine相似度,用相似度预估点击率、点赞率等。

如果要预估10个目标,那么用户塔会输出10个向量

单向量模型只是做简单的二分类区分正负样本,多向量模型类似排序中的多目标模型,同时预估很多目标

为什么物品塔只输出1个向量?因为事先算出来,存入向量数据库,如果算10个做10套ANN索引那代价太大了,只输出1个就不需要那么多代价

image-20250314151512729

冷门物品的点击次数少,向量表征学的不好,用自监督学习(预训练时使用未标注数据,微调时用少量标注数据微调)

image-20250314151601932

I2I

image-20250314153353783

靠用户行为判断相似,也可以根据向量表征,内积/余弦相似度,双塔最常用,因为算出的就是对物品兴趣点的表征

image-20250314153423080

image-20250314153459570

其他小众的召回模型:混合使用user/item/author各种信息,类比usercf,相似作者召回

image-20250314154241537

image-20250314154258487

总结:召回总量不变(如所有通道召回5000个进入粗排),召回总量大到一定程度边际效益很低,调整配额会更有用,对不同人群也可以使用不同配额

image-20250314154342461

涨指标的方法03:排序模型

image-20250314160216461

精排模型的改进

蓝色神经网络的输入输出是几百维的向量

全连接网络不会很大,GPU3-6层;上面的全连接网络通常是2层

image-20250314161020604

image-20250314161115885

多目标预估:增加新的指标(增加输出的向量)

image-20250314161405352

2和3很容易无效

image-20250314161457131

粗排模型的改进

粗排需要快,因为打分量大

image-20250314161554383

蒸馏:用教师模型(精排)打软标签,让学生模型(粗排)去学

image-20250314161702200

image-20250314161757323

pointwise简单效果也不错,大厂会做pairwise和listwise

image-20250314162049878

用户行为序列建模

last-n,n个id映射成向量,取平均

image-20250314164255570

image-20250314164314936

长序列取决于工程架构,快手做的好,可以覆盖100w个物品,几乎能覆盖用户历史上的全部行为

image-20250314165442201

筛选目的是降低序列长度,不可能把100w个物品向量全部输入注意力层,计算量会特大。

  1. Bert\CLIP提取内容特征
  2. 层次聚类:无监督学习,将数据点分组为多个簇

image-20250314164916522

加一些id以外的特征,但不能加太多,不然线上推理时通信和计算都会出问题。

image-20250314165405633

业界的提升过程基本都是这样:

image-20250314165507639

在线学习

增量更新是在线学习,分钟级别,隔一段时间发布新模型

image-20250314165641745

每个不同的模型都要做在线学习,更新梯度等

image-20250314171647616

推全一般比holdout新几个版本

4个模型,需要4套资源,只能看2个新模型,召回和粗排的模型小,消耗的资源没有精排多

image-20250314171758188

如M=6,每套机器的成本1w cpu core,测试4个模型

最好在模型相对成熟后再上在线学习,过早上容易把模型锁死在较弱的版本,后续迭代很慢

image-20250314171910964

老汤模型

全量更新:每天对新数据做1epoch训练;老模型积累了很多数据

有些新模型可能结构更好,但训了100天数据后,还是追不上老模型,此时需要判断还有无信心继续训练下去。新模型用了几十天,而线上老模型训练了上百天,追平老模型需要训练挺久

image-20250314172324295

问题1的解决就是随机初始化,让新老模型站在同一起跑线用同样的数据比较模型结构

image-20250314212857424

embedding避免重新初始化;蒸馏可以大幅加速收敛,让新模型追的更快

image-20250314213012883

总结:三塔很流行;SIM

image-20250314213121320

推荐系统涨指标的方法04:多样性

image-20250314214416438

同一个聚类中的图片和文字相似,应该被打散

image-20250314214746552

先不考虑多样性,优先考虑兴趣分数(前200个),后面再选300个物品,保证了多样性

image-20250314214846367

双塔模型是最重要的召回模型。添加随机噪声,兴趣越窄噪声就强,理论上召回会变得不准,但反而会提升多样性

image-20250314215125776

对用户行为序列做随机抽样,让双塔召回的结果有随机性。以前可能n设置100,有了抽样后n可以设置1000,但计算代价不变

image-20250314215326672

U2I2I召回:用户的兴趣不宽泛,也是用随机抽样,让n可以覆盖更大,类目更丰富

image-20250314215451564

image-20250314215517556

跳过排序,强行插入最终的曝光结果。重点是维护精选内容池。

image-20250314215656498

总结:

image-20250314215800788

推荐系统涨指标的方法05:特殊用户人群

对待新用户、低活用户

image-20250314222909712

image-20250314223149073

特殊内容池:

image-20250314223245936

根据交互指标构造特殊内容池

image-20250314223959400

image-20250314224027466

召回:需要单独训练模型,用户塔会少一些用户特征,但无论用在多少内容池上,新用户只要一个自己的双塔模型就够了

image-20250314224102169

image-20250314224624663

额外的推理代价?计算量与内容池正相关

image-20250314225007275

探索是必须要做的,新物品在老用户上进行测试,相当于损害一点老用户的利益帮助新用户(新手保护)

image-20250314225122513

先保证点击,所以把点击率权重提高(只用于低活用户)

image-20250314230230056

排序模型是主流用户主导的,对特殊用户不准

image-20250314233827838

用小模型image-20250314234316878

MMoE:通过权重调整结果,就可以对新老用户分开处理image-20250314234501909

大模型是用全量数据做出来的,相当于1是并行的,3是串行的。小模型可以非常小,小模型再做一次预估,起到校准的作用

image-20250314235346902

会增加维护模型的代价,特殊人群的模型太多,最好只有一个统一的模型,再加几个小模型

image-20250314235440373

image-20250314235744371

总结:

image-20250315122527368

涨指标的方法06:交互行为(关注、转发、评论)

融分公式把各种指标融合,作为依据

image-20250315122905738

关注

关注的作者越多,平台的吸引力更强

image-20250315123015194

如何提高关注量?f很小的时候用排序策略有效(不太懂候选物品的关注率指什么,指关注发布物品作者的概率?)

image-20250315123148693

维护容易被关注作者的物品,如果f少,就从内容池多召回点物品

image-20250315123244546

粉丝数、交互提升作者的发布积极性

image-20250315123557562

看到物品i后,用户u可能关注作者的概率是Pui,如果粉丝少,w大,物品容易被曝光->涨粉

image-20250315123731367

隐式关注关系:应该挖掘(视奸)

image-20250315123925953

转发

最重要的价值是吸引站外流量

直接增大转发的权重会有问题,损害点击等指标,太简单粗暴了

image-20250315124158851

正确的方法是本平台的用户是其他平台的KOL,就容易吸引流量。如何识别?看历史转发得到了多少流量

image-20250315124308228

image-20250315124356564

如何进行排序和召回:添加融分公式,提升大盘指标

image-20250315124439464

构造促转发的内容池,和促关注一样

image-20250315125021292

评论

目前获得的评论数越少,w就应该越大

image-20250315125142854

给喜欢评论的用户添加内容池;鼓励高质量评论

image-20250315125228943

总结:

image-20250315125307803