【下】王树森《小红书推荐系统公开课》- 课程笔记(特征交叉、行为序列、重排/推荐系统多样性、物品冷启动、涨指标的方法)

写在前面

本文为王树森老师《小红书推荐系统公开课》的课程笔记

  • 课程来源:ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com)
  • 课程资料:GitHub - wangshusen/RecommenderSystem

由于篇幅较长,分为【上】【下】两篇文章来记录。其中【上】包括推荐系统基础、召回、排序,文章链接:【上】王树森《小红书推荐系统公开课》- 课程笔记(推荐系统基础、召回、排序)

【下】包括特征交叉、行为序列、重排/推荐系统多样性、物品冷启动、涨指标的方法,内容导航如下: 


 (四)特征交叉

特征交叉在召回和排序中都会用到。在推荐系统的应用中,特征交叉很有必要,可以让模型的预测更准确

1、Factorized Machine(FM)因子分解机

线性模型

  • b:偏移项,bias/intercept
  • wi:每个特征的权重
  • p:对目标的预估(如果是二分类,可以用sigmoid激活函数)

d个特征之间只有相加、没有相乘,也就是说特征之间没有交叉

二阶交叉特征

  • xixj是两个特征的交叉,uij是交叉特征的权重
  • 大多数参数是模型交叉特征的权重u。如果d很大,参数数量太大,计算代价大,且容易出现overfitting

用特征交叉的话,两个特征不仅能相加,还能相乘,这样可以提升模型的表达能力

FM

上面提到,如果d很大,参数数量太大,计算代价大,容易出现overfitting。那如何减少参数数量?

  • 重点关注交叉特征的权重uij

U矩阵有d行d列(d是参数数量),是个对称矩阵,可以对其做低秩近似: 

  • k << d,k是个超参数,由我们自己设置。k越大,矩阵V * V^T 就越接近矩阵U
  • 此时 uij 就可以近似为 vi 和 vj 的内积

由此就得到了FM模型:

FM优点:

  • FM是线性模型的替代品,能用线性回归、逻辑回归的场景,都可以用FM(FM本质上就是在线性模型后面加了交叉项
  • FM使用二阶交叉特征,表达能力比线性模型更强
  • FM参数数量更少,二阶交叉权重的数量由 O(d^2) -> O(kd),其中 k<<d,d是特征数量。使得推理的计算量更小,且不容易出现过拟合

Steffen Rendle. Factorization machines. In ICDM, 2010.

以前的应用:用逻辑回归预估点击率,在逻辑回归中用FM做特征交叉,在推荐系统中效果很好

2、DCN(深度交叉网络)

用来代替简单的全连接网络,召回和排序中都可以用

回顾召回、排序模型

召回的双塔模型(是一种框架,而不是具体的神经网络)中,用户塔、物品塔可以用任意的神经网络结构,最简单的就是全连接神经网络,可以换为深度交叉网络DCN,效果更好

多目标排序模型中,输入是用户、物品、统计、场景等特征,输出是对点击率、点赞率等指标的预估。中间的神经网络负责对特征做变换,输出一个特征向量,这个神经网络被所有任务共享,所以叫做shared bottom。它的网络结构可以任意,最简单的实现就是用多个全连接层,如果用更好的神经网络结构如DCN,模型预估的准确性会更高

排序用的MMOE模型,3个专家神经网络(第1号~第3号),用途是把各种输入特征(用户、物品、统计、场景等特征)拼接后映射到新的特征向量,用于顶层的预估任务。这3个专家神经网络也可以用任意的结构,包括全连接网络、深度交叉网络

交叉层(Cross Layer)

DCN的基本组成单元。每个交叉层的输入、输出都是向量,且形状相同

x_0为输入,经过 i层 后神经网络的输出为x_i,下面详细讲解第i个交叉层的结构

  • Skip Connection(把输入和输出相加)是深度学习中的一种常用技巧,可以防止梯度消失

每一步拆解:

  • 第i个交叉层的输入:x_0、x_i。其中x_0是整个神经网络最底层的输入,x_i是神经网络第i层的输入

  • 全连接层输出是个向量,跟输入的 x_i向量 大小一样
  • 参数全在全连接层里,即W和b,需要在训练过程中用梯度去更新;其余操作为向量哈达玛积和向量加法,都没有参数 

  • 哈达玛乘积(Hadamard Product):逐元素相乘,输入输出向量维度一致。因为是逐元素相乘,故要求输入维度一致

  • 第i个交叉层的输出:x_(i+1)

交叉网络(Cross Network)

x_0向量是交叉网络的输入

上面介绍的是Cross Network V2,对应paper:Ruoxi Wang et al. DCN V2: Improved Deep & Cross Network and Practical Lessons for Web-scale Learning to Rank Systems. In WWW, 2021.

老版本(原始版本)的Cross Network 现在已经没用了,对应paper(没必要看):Ruoxi Wang et al. Deep & Cross Network for Ad Click Predictions. In ADKDD, 2017.

深度交叉网络(Deep&Cross Network,DCN)

结合交叉网络和全连接网络,两个网络并联;再加上全连接层,即为DCN

3、LHUC(PPNet)

LHUC与交叉网络的想法类似,在工业界有效,但只能用于精排

标准的多目标排序模型 结构如下,中间的Shared Bottom被多个任务共享,Shared Bottom用全连接网络、深度交叉网络、LHUC都可以

in语音识别

LHUC 全称 Learning Hidden Unit Contributions,起源于语音识别:Pawel Swietojanski, Jinyu Li, & Steve Renals. Learning hidden unit contributions for unsupervised acoustic model adaptation. IEEE/ACM Transactions on Audio, Speech, and Language Processing, 2016.

  • 语音识别的输入是一段语音信号,用神经网络对输入的信号做变换,得到更有效的表征,然后识别出语音中的文字
  • 语音是人说的,不同人的声音会有所区别,所以最好加入一些个性化,即说话者的特征。最简单的特征就是说话者的ID,对其做Embedding

  • 上面输出的两个向量形状完全一致,这样才可以做哈达玛积(逐元素相乘),这样可以把语音信号的特征和说话者的特征相融合,语音信号有的特征被放大,有的特征被缩小,这样做到个性化 

一个简单的例子如下,LHUC重复了两个模块(做了两次哈达玛积),实践中想实现更深的网络也没有问题:

in推荐精排(PPNet)

快手将LHUC应用在推荐精排,称作PPNet:快手落地万亿参数推荐精排模型,2021

4、SENet & Bilinear交叉

这两种方法用在排序模型上都有收益

SENet

Jie Hu, Li Shen, and Gang Sun. Squeeze-and-Excitation Networks. In CVPR, 2018. 其提出是应用在CV(计算机视觉)问题上

把SENet用在推荐系统的一篇Paper:Tongwen Huang, Zhiqi Zhang, and Junlin Zhang. FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction. In RecSys, 2019.

这里只介绍SENet在推荐系统中的应用 

SENet怎样对这些特征做变换?

设一共有m个特征,每个特征都表示成一个k维向量,可以把所有特征表示成一个m*k的矩阵

  • 中间m维向量的作用就是对特征做加权,比如学出物品ID这个特征对任务的重要性不高,就对物品ID的Embedding降权

上面把m个离散特征都映射成k维向量,其实这m个向量的维度可以不同,不会影响SENet(对每个向量做AvgPooling得到一个m维向量,再用两个全连接层FC得到另一个m维向量,用来对一开始的m个向量做加权)。最终SENet输出右边的m个向量,跟左边的m个向量的形状完全相同

总结SENet:

  • SENet 对离散特征做 field-wise 加权
  • 什么是field? ⽤户ID Embedding 是64维向量,那么这64个元素算⼀个field,获得相同的权重
  • 如果有m个离散特征,即m个fields,那么SENet计算出的权重向量就是m维,用这个向量的元素给fields做加权。也就是说,SENet会根据所有特征,自动判断每个fields的特征重要性,重要field的权重高,不重要field的权重低

Field间特征交叉

把两个field做交叉,得到新的特征。比如说,把物品所在地点、用户所在地点这两个特征各自做embedding,然后把两个embedding向量做交叉。怎样交叉两个向量?

内积/哈达玛积

推荐系统中m(离散特征)的数量不是很大,量级也就几十

  • 左侧内积,m^2个实数,可以接受
  • 右侧哈达玛积,m^2个向量,不能接受。故一般人工选择一些pair交叉,不能对所有m fields两两交叉

不论是内积or哈达玛积,都要求每个特征的embedding向量形状一样,都是k维向量;若形状不同,无法计算内积or哈达玛积

Bilinear Cross

包含内积和哈达玛积两种方式

方式1:内积

  • x_i和x_j是两个特征的Embedding,它们的形状可以相同也可以不同
  • f_ij是两个field的交叉。若有m个field,则会产生m^2个交叉特征(实数)
  • W_ij为参数矩阵,若有m个field,则会产生 m^2 / 2 个参数矩阵。假如每个参数矩阵大小都是64*64,有1000个这样的参数矩阵,那么Bilinear Cross的参数量是400w
  • 想要减小参数数量,需要人工指定某些相关且重要的特征做交叉,而不能让所有特征两两交叉

方式2:哈达玛积 

  • 先把参数矩阵W_ij 和 特征向量x_j 相乘,得到一个向量;再求两个向量的哈达玛积(逐元素相乘)
  • 输出向量f_ij。若有m个field,会产生m^2个向量,对m^2个向量做concatenation,得到的向量维度太大,且其中大多数都是无意义的特征
  • 因此在实践中,最好人工指定一部分特征做交叉,而不是让所有m个特征两两交叉,这样既可以减少参数数量,也可以让concatenation之后的向量变小

【小结】

SENet对离散特征做field-wise加权,让重要的特征获得大权重,不重要的特征获得小权重

Field间特征交叉,让两种特征的embedding向量做交叉,有3种方式:

  • 向量内积
  • 哈达玛积
  • Bilinear Cross

结合SENet 和 Bilinear Cross,就得到了FiBiNet

FiBiNet = SENet + Bilinear Cross

Tongwen Huang, Zhiqi Zhang, and Junlin Zhang. FiBiNET: Combining Feature Importance and Bilinear feature Interaction for Click-Through Rate Prediction. In RecSys, 2019.

FiBiNet用SENet加权和Bilinear Cross,用在精排模型上有收益

  • 离散特征:如用户ID、物品ID、物品类目,等等
  • 之前就是把离散特征embedding(用一个向量表示一个特征)concat后的向量,跟连续特征拼起来,作为排序模型的输入
  • FiBiNet还做了其他的特征变换,见红框部分
    • 对这些embedding向量做Bilinear Cross,得到很多交叉特征,拼接成一个向量
    • 用SENet对这些embedding向量做加权,得到同样大小的向量;再对这些向量做Bilinear Cross,得到很多交叉特征,拼接成一个向量(小红书在实践中没做这一步)
  • 把FiBiNet对离散特征变换之后得到的特征向量、变换后的连续特征一起输入上层的神经网络

(五)用户行为序列(last-n)

把用户行为序列叫做 last-n,指用户最近交互过的n个物品的ID。用户的 last-n行为序列 可以反映出用户对什么样的物品感兴趣

召回的双塔模型、粗排的三塔模型、精排模型都可以用 last-n特征(十分有效,用在召回和排序模型中,所有指标都会大涨)

1、用户历史行为序列建模

多目标排序模型:模型的任务是预测点击率、点赞率等指标,根据指标对物品做排序,选出用户最感兴趣的物品

重点关注用户特征中的 last-n行为序列

取平均是早期的做法,现在也很常用;效果更好的做法是Attention,但计算量太大

用户lastN序列特征

Covington, Adams, and Sargin. Deep neural networks for YouTube recommendations. In ACM Conference on Recommender Systems, 2016.

LastN:用户最近n次交互(点击、点赞、收藏、转发等行为)的物品ID

  • 对LastN物品ID做embedding,得到n个向量
  • 把n个向量取平均,作为用户的一种特征
  • 注意,用户还有其他的很多特征,比如用户ID、离散特征、连续特征等,把所有这些特征拼起来,作为用户特征输入神经网络

适用于召回双塔模型、粗排三塔模型、精排模型

小红书的实践

小红书的召回、粗精排都用到了LastN行为序列

  • 同一种行为的向量取平均,得到点击、点赞、收藏等行为的LastN向量表征
  • 把这些向量拼起来,作为一种用户特征
  • 实践中不止用物品ID,还用物品的其他特征,如物品类目。把物品ID Embedding和物品其他特征Embedding拼在一起

2、DIN模型(注意力机制)

DIN模型是对 LastN序列建模 的一种方法,效果优于简单的平均。用于精排

如上图,取平均最简单,但效果不是最好。DIN是一种更好的LastN序列建模方法,由阿里于2018年提出

Zhou et al. Deep interest network for click-through rate prediction. In KDD, 2018.

  • DIN用加权平均代替平均,即注意力机制(Attention)
  • 权重指候选物品与用户LastN物品的相似度(实数α)。哪个LastN物品与候选物品越相似,它的权重就越高
    • 啥是候选物品?比如粗排选出了500个物品,它们就是精排的候选物品。精排模型要给每个候选物品打分,分数表示用户对候选物品的兴趣,最后根据分数的高低给这500个候选物品排序,保留分数最高的几十个展示给用户
  • 计算相似度的方法有很多,比如内积、cos

 【DIN模型-总结】

  • 对于某候选物品,计算它与用户LastN物品的相似度,得到 α_1 ~ α_n
  • 以相似度为权重,求用户LastN物品向量的加权和,结果是一个向量
  • 把得到的向量作为一种用户特征,输入排序模型,预估 (用户, 候选物品) 的点击率、点赞率等指标,它们会决定候选物品的排序
  • 本质是注意力机制

本质:注意力机制

简单平均 vs 注意力机制

简单平均注意力机制 都适用于精排模型

简单平均还适用于召回的双塔模型、粗排的三塔模型

  • 简单平均只需要用到LastN,属于用户自身的特征,跟候选物品无关
  • 把LastN向量的平均作为用户塔的输入

注意力机制不适用于双塔模型、三塔模型

  • 注意力机制需要用到 LastN + 候选物品
  • 用户塔看不到候选物品(比如双塔召回时,有上亿候选物品,用户只能看到用户特征,看不到候选物品特征),故不能把注意力机制用在用户塔

3、SIM模型(长序列建模)

保留用户长期兴趣

回顾DIN

Zhou et al. Deep interest network for click-through rate prediction. In KDD, 2018.

  • 计算用户 LastN向量 的加权平均
  • 权重是候选物品与每个LastN物品的相似度

DIN模型的缺点:

  • 注意力层的计算量 ∝ n(用户行为序列的长度) 
  • 只能记录最近几百个物品(一般一两百个物品),否则计算量太大
  • 缺点:关注短期兴趣,遗忘长期兴趣

如何改进DIN?

  • 目标:保留用户长期行为序列(n很大),而且计算量不会过大
  • 改进DIN:
    • DIN对LastN向量做加权平均,权重是相似度
    • 如果某LastN物品与候选物品差异很大,则权重接近0
    • 如果把不相关的物品从LastN物品中排除掉,几乎不会影响DIN加权平均的结果
    • 只把相关物品输入注意力层,快速排除掉与候选物品无关的LastN物品,降低注意力层的计算量

SIM模型

Qi et al. Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Through Rate Prediction. In CIKM, 2020.

保留用户长期行为记录,n的大小可以是几千

  • 对于每个候选物品,在用户LastN记录中做快速查找,找到k个相似物品(k是个比较小的数,比如k=100)
  • 把LastN变成TopK,然后输入到注意力层
  •  SIM模型减小计算量(从n降到k)

第一步:查找(用哪种取决于公司基建)

  • 方法1:Hard Search(根据规则做筛选)
    • 根据候选物品的类目,保留LastN物品中类目相同的
    • 简单、快速、无需训练
  • 方法2:Soft Search(向量最近邻查找)
    • 把LastN物品和候选物品都做Embedding,变成向量
    • 把候选物品向量作为query,做k近邻查找,保留LastN物品中最接近的k个
    • 效果更好,用于预估点击率等业务指标时AUC更高
    • 编程实现更复杂,计算代价更高

第二步:注意力机制(本质跟DIN一样) 

与DIN的区别在于:是用户TopK交互记录,而不是LastN交互记录

  • 第一步的查找将用户LastN物品缩小到TopK,排除掉的物品大多跟候选物品无关(相似度低,权重接近0),几乎不影响加权平均的结果

一个有用的trick:使用时间信息,即记录用户与每个物品交互发生的时刻

  • 用户与某个LastN物品的交互时刻距今为δ。比如发生在1000h前,δ=1000
  • δ是连续值,对其做离散化(划分为很多区间,比如发生在最近1/7/30天/1年/1年以上),再做embedding,变成向量d
  • 把两个向量做concatenation,表征一个LastN物品
    • 向量x是物品embedding
    • 向量d是时间的embedding
  • 候选物品不需要对其时间做Embedding

为什么SIM使用时间信息?

  • DIN的序列短,记录用户近期行为(只记录用户最近交互过的100~200个物品),无需考虑时间信息
  • SIM的序列长,记录用户长期行为。LastN列表中的物品可能是一年前,或十分钟前的交互,重要性不同(时间越久远,重要性越低)

结论

  • 长序列(长期兴趣) 优于 短序列(近期兴趣)
  • 论文对比了两种机制:先做查找再做平均 or 先做查找再使用注意力
    • 结论:注意力机制 优于 简单平均
  • Soft Search or Hard Search?取决于工程基建
    • Soft Search的预估准确率优于Hard Search
    • 但Hard Search实现起来更容易,用规则做简单的筛选即可
  • 使用时间信息有提升

(六)重排 / 推荐系统中的多样性

若推荐系统多样性做得好,用户留存、APP使用时长等业务指标会显著提升

1、背景知识

若曝光给用户的物品两两之间不相似,说明推荐的结果具有多样性

物品相似性的度量

方法1:基于物品属性标签

  • 类目、品牌、关键词...
  • 两个物品有越多相同的标签,说明两个物品越相似

方法2:基于物品向量表征

  • 两个物品向量余弦值越大,说明两个物品越相似
  • 有很多种方法可以对物品做向量表征,但并不是所有的向量表征方法都适用于多样性问题
    • 用召回的双塔模型学到的物品向量(不适用于多样性问题)
    • 基于内容的向量表征,即用cv和nlp模型提取图片和文字的特征向量(适用于多样性问题,best)
 基于物品属性标签
  • 物品属性标签,如类目、品牌、关键词...
  • 这些标签通常是由cv和nlp算法根据图文内容推断出的,未必准确
  • 例如,根据一级类目、二级类目、品牌计算相似度
    • 物品i:美妆、彩妆、香奈儿
    • 物品j:美妆、香水、香奈儿
    • 相似度:sim1(i, j) = 1,sim2(i, j) = 0,sim3(i, j) = 1
    • 对3个分数求加权和即可得到相似度的总分,权重根据经验设置
双塔模型的物品向量表征

若把双塔模型的物品向量表征用在多样性问题上: 

  • 只需要物品塔的输出。物品塔把每个物品表征成一个向量b,若两个物品相似,则向量表征的内积或余弦相似度比较大
  • 但效果不好,原因:推荐系统中的头部现象很严重,曝光和点击都集中在少数物品,新物品和长尾物品的曝光和点击次数都很少,双塔模型学不好它们的向量表征。如果用物品塔输出的向量计算物品相似度,肯定处理不好新物品和长尾物品,导致多样性算法的效果很差
基于图文内容的物品表征(best)

  • 把CNN和BERT分别得到的向量表征拼起来,就是一篇图文笔记的向量表征
  • CV和NLP模型如何做预训练?
    • 外界公开数据集做训练,迁移到小红书的数据上 —> 效果不好
    • 小红书的数据做训练 —> 需要人工标注
    • CLIP
CLIP(当前公认最有效的预训练方法)
  • 优势:无需人工标注。小红书的笔记天然包含图片+文字,大部分笔记图文相关
  • 思想:对于图片-文本二元组,预测图文是否匹配(做训练时,同一篇笔记的图片和文字作为正样本,图片的向量和文字的向量应该高度相似)

  • 一个batch若有m篇笔记,则该batch内有m对正样本
  • 若图片和文字来自不同的笔记,可以作为负样本(可以采用batch内负样本)
    • 一张图片和m-1条文本组成负样本(假设一篇笔记只有一张图片)
    • 这个batch内一共有m(m-1)对负样本

CLIP:Radford et al. Learning transferable visual models from natural language supervision. In ICML, 2021.

提升多样性的方法

多样性:物品之间两两都不相似

推荐系统的链路

粗排和精排唯一的任务就是做准确的pointwise打分,而不用考虑物品之间的关联,即把每个物品作为独立的个体,尽量准确预估点击、交互、时长

在粗排和精排之后都有后处理,作用是提升多样性

  • 假如不考虑多样性,只需要根据reward(物品对用户的价值)对n个物品(对于粗排,n=几千;对于精排,n=几百)排序,选出topk
  • 在实践中,增加曝光物品的多样性有利于业务指标,所以工业界在后处理阶段使用多样性算法
    • 精排的后处理通常被称为“重排”,它决定n个候选物品中有哪k个最终获得曝光,以及k个物品展示给用户的顺序
    • 粗排后处理也需要多样性算法,也能提升业务指标,而不是简单的从几千物品中选reward最高的几百个(小红书的实践:优化粗排之后的多样性,能显著提升用户使用推荐的时长&留存)

2、MMR多样性算法(Maximal Marginal Relevance)

MMR原用于搜索排序中,之后被沿用到推荐排序(精排的后处理阶段,根据精排分数&多样性分数给候选物品排序,决定了物品的最终曝光顺序)

多样性问题设定

精排给n个候选物品打分,预估点击率、点赞率、完播率、播放时长,等等。融合之后的分数为reward_1 ~ reward_n,表示用户对物品的兴趣(或用户眼中物品的价值)

  • 精排中n的大小通常是几百

把第 i 和 j 个物品的相似度记作sim(i, j)

  • 它可以是物品标签计算出的,也可以是向量表征计算出的

在精排的后处理阶段(即重排),从n个物品中选出k个,既要有高精排分数,也要有多样性,即结合reward和sim两种分数,从n个候选物品中选出k个,作为最终曝光的结果

MMR原理

把n个候选物品分成两部分:

给未选中的物品计算MR分数(i是未选中的物品,j是已选中的物品)

  • reward_i越大,物品i 越应该被选中
  • sim(i, j) 关于 物品j 求最大化,消掉j,即衡量 物品i 与 集合S 的相似度。假如物品i 与某个已经选中的物品j 相似,则sim(i, j)较大,对物品i 起抑制作用,不利于i被选中
  • θ是介于0-1之间的参数,平衡物品的价值(即精排分数)和多样性分数。θ越大则物品价值对排序的影响越大,同时多样性对排序的影响就越小

MMR就是对MR分数求最大化。对于所有未选中的物品i:

  • 每一轮都需要计算集合R中所有物品的MR分数,选出分数最高的物品,从集合R移到集合S

重排阶段想要选出k个物品,就要做k-1轮循环(因为第一轮还没有物品被选中,无需考虑多样性,直接将精排分数reward最高的k个物品从集合R移到集合S即可),每一轮循环都要计算如下公式:

MMR流程

滑动窗口

上述公式中存在的问题及解决方案:

直观解释:给用户曝光的物品应当具有多样性,即物品两两之间不相似,但没有必要让第30个物品跟第1个物品不相似(用户看到第30个物品时,大概率已经忘了第1个物品是啥)。两个离得远的物品可以相似,相似也不会影响用户体验;但若两个物品离得比较近,应当有较大差异,否则用户可以感知到多样性不好。比方说设置一个大小为10的滑动窗口,那么MMR算法会选出一个物品,它跟这10个物品都不相似,但可以与更早之前的物品相似 

3、业务规则约束下的多样性算法

MMR多样性算法综合考虑物品的价值&多样性,工业界中重排的规则如何与MMR多样性算法相结合?

  • 做重排时这些规则必须要被满足(主要是用来保障用户的体验)

重排的规则 

注:以下例子均不是小红书的真实数据

例1:笔记的类型(图文/视频)需要多样化

例2:防止boost影响体验(靠boost排上去的笔记肯定不是用户最感兴趣的)

例3:首屏笔记必须是用户最感兴趣的。带电商卡片笔记的流量有一定几率转换成营收,但需要控制数量,否则会影响用户体验

MMR+重排规则

规则的优先级 高于 多样性算法 

  • MR分数为物品价值与多样性的加权和
  • 公式不变,只需把集合R(未选中的物品)替换成子集R'(未选中且符合规则的物品),在子集R'中选择MR分数最高的物品,这样选出的物品既符合规则,又具有较高的价值和多样性

4、DPP多样性算法

DPP:行列式点过程(Determinantal Point Process)

  • 目标是从一个集合中选出尽量多样化的物品,这与重排的目标非常契合
  • 目前推荐系统领域公认的最好的多样性算法

数学基础

超平行体
  • 二维空间:平行四边形 

  • 三维空间:平行六面体

数学定义:

要想超平行体有意义,v_1 ~ v_k 必须线性独立

平行四边形的面积(二维)
  • 以v1为底,计算高q2

  • 以v2为底,计算高q1 

平行六面体的体积(三维)

衡量物品多样性

k个物品的单位向量(二范数=1)最好是用CLIP学出的图文内容表征,都是d维(d ≥ k)

行列式跟超平行体的体积是等价的,因此可以用行列式衡量向量的多样性。多样性越好,体积和行列式的值都会越大。行列式点过程DPP的基本思想就是用行列式(等价于超平行体的体积)衡量物品向量的多样性

该公式的数学证明见讲义:https://github.com/wangshusen/RecommenderSystem/blob/main/Notes/06_Rerank.pdf 

DPP应用在推荐系统中

回顾多样性问题

 如下图,每个列向量对应一个物品,一共k个向量,每个向量都是d维

行列式点过程DPP

DPP的基本思想:用行列式衡量物品多样性

公式的第一项在MMR中也有

如何求解上述公式?需要巧妙的数值算法:

[1] Hulu的论文:

精确求解DPP是不可能的,因为DPP是个NP-Hard问题,用贪心算法近似求解:

每一轮选择一个物品i,物品i 不能跟集合S中的任何物品相似,否则行列式会接近0

求解DPP
暴力算法

系统留给多样性算法的时间就10ms左右,暴力算法太慢

HULU的快速算法

降低了计算行列式的代价,使得DPP可以被用在推荐系统中,哪怕只给10ms的时间

算法具体细节见讲义:https://github.com/wangshusen/RecommenderSystem/blob/main/Notes/06_Rerank.pdf 

DPP的扩展
滑动窗口

所有n个候选物品分为集合S(选中的物品)和 R(未选中的物品):  

规则约束

DPPMMR都可以用于推荐系统的重排,增加物品的多样性

两种方法都可以与滑动窗口,或规则约束相结合


(七)物品冷启动(UGC)

研究UGC的物品冷启

  • 什么是物品冷启动?如小红书上用户新发布的笔记、B站上用户新上传的视频、今日头条上作者新发布的文章 
  • UGC(User Generated Content,内容都是用户自己上传,如b站、小红书、油管、知乎)
  • PGC(Platform Generated Content,内容主要由平台采购,如腾讯视频、Netflix)

UGC冷启动比PGC更难,因为用户自己上传的内容良莠不齐、量大、很难人工评判、很难由运营做流量调控 

为什么要特殊对待新笔记? 

  • 新笔记刚刚发布,缺少与用户的交互,很难根据用户的行为做推荐,导致推荐的难度大、效果差;如果用正常的推荐链路,新笔记很难得到曝光,即使得到曝光,消费指标也会很差
  • 促进发布。扶持新发布、低曝光的笔记,可以增强作者发布意愿。获得首次曝光和交互的时间越快、新笔记获得的曝光越多,越有利于作者的积极性

1、优化目标&评价指标

优化冷启的目标

  1. 精准推荐:克服冷启的困难,把新笔记推荐给合适的用户,不引起用户反感
  2. 激励发布:流量向低曝光新笔记倾斜,激励作者发布积极性,丰富内容池(扶持低曝光的新笔记,对激励作者发布最有用)
  3. 挖掘高潜:通过初期小流量的试探(给每篇新笔记一两百次的试探曝光),在大量新笔记中找到高质量的笔记,即有较大希望成为热门的笔记,给予流量倾斜

评价指标

作者侧指标:反映用户发布意愿。对低曝光笔记扶持越好,作者侧指标就越高

  • 发布渗透率、人均发布量

用户侧指标:反映推荐是否精准,是否会引起用户反感

  • 新笔记自身的消费指标:新笔记的点击率、交互率(若新笔记的推荐比较准,这些指标会较高)
  • 大盘指标:消费时长、日活、月活(做冷启动,目标不是促进消费指标增长,但冷启的策略也不能显著伤害消费指标,应尽量持平) 

内容侧指标:反映冷启能否挖掘出优质笔记,帮助优质笔记成长为热门

  • 高热笔记占比(高热笔记指30天内点击超过1k的笔记)
作者侧发布指标(工业界通用)
  • 发布渗透率(penetration rate)
    • 衡量作者发布积极性
    • 发布渗透率 = 当日发布人数 / 日活人数。即:在某一天,用户成为作者的比例,就等于渗透率
    • 发布一篇或以上笔记,就算一个发布人数。无论发一篇还是发十篇,都只算一个发布人数
    • 例:当日发布人数=100万,日活人数=2000万,发布渗透率=100/2000=5%
  • 人均发布量
    • 人均发布量 = 当日发布笔记数 / 日活人数
    • 人均发布量 > 发布渗透率,因为一些作者一天会发好几篇笔记
    • 例:每日发布笔记数=200万,日活人数=2000万,人均发布量=200/2000=0.1
  • 发布渗透率、人均发布量反映出作者的发布积极性

冷启的重要优化目标是提高作者积极性,促进发布,增大内容池

新笔记获得的曝光越多,首次曝光和交互出现的越早,作者的发布积极性越高,所以要把流量向新笔记倾斜,使其获得更多曝光;同时也要优化新笔记的链路,让新笔记出现曝光和交互尽量快

用户侧消费指标(工业界通用)
  • 新笔记的消费指标:如果新笔记的推荐做的精准,符合用户兴趣,那么新笔记的消费指标会比较好
    • 新笔记的点击率、交互率
      • 如果新笔记符合用户兴趣,那么消费指标会得到改善
      • 问题:推荐系统往往存在严重的头部效应,曝光的基尼系数很大,少数头部新笔记占据了大部分的曝光。新笔记的整体消费指标主要取决于少量头部新笔记,不能反映出大部分新笔记的情况
    • 分别考察高曝光(比如>1k次曝光)、低曝光(比如<1k次曝光)新笔记
      • 高曝光笔记有充足的用户交互记录,即使不用冷启动技术做特殊处理,推荐也能做的准;更应该关注低曝光的新笔记,它们占比高、且由于交互信息少、推荐不容易做好,提升低曝光新笔记的点击率和交互率
  • 大盘消费指标:不区分新老笔记
    • 包含大盘的消费时长、日活/月活的用户数
    • 目的并非提升大盘指标,而是不显著伤害,即基本持平
    • 大力扶持低曝光新笔记会激励作者发布,使作者侧发布指标变好,但有损用户体验,使用户侧大盘消费指标变差
内容侧指标(工业界非必用)
  • 高热笔记占比
    • 高热笔记:前30天获得1k+次点击(通常质量高、受用户欢迎)
    • 高热笔记占比越高,说明冷启阶段挖掘优质笔记的能力越强

总结

  • 作者侧指标:发布渗透率、人均发布量
  • 用户侧指标:新笔记消费指标、大盘消费指标
  • 内容侧指标:高热笔记占比

普通笔记的推荐通常只考察用户侧指标,冷启的评价体系比普通笔记复杂很多

冷启动的优化点

优化全链路:包括召回&排序

  • 每个环节都针对新笔记做优化,让新笔记有足够多的机会走完链路、被曝光;还要尽可能让新笔记的推荐做的准,不让用户反感

流量调控:流量怎么在新物品、老物品中分配

  • 流量向新笔记倾斜,让新笔记获得更多曝光机会

2、简单的召回通道

召回的难点

召回的依据:

  • √ 自带图片、文字、地点
  • √ 算法或人工标注的标签,比如笔记的类目
  • × 没有用户点击、点赞等信息。这些统计数据可以反映出笔记本身的质量,以及什么样的用户喜欢这篇笔记;而且ItemCF、UserCF这类召回通道需要知道笔记跟哪些用户有过交互。如果一篇笔记跟用户还没有产生交互,就走不了ItemCF这类召回通道
  • × 没有笔记ID Embedding(召回和排序中最重要的特征之一)。这个向量是从用户跟笔记交互的行为中学习出来的。冷启的时候,该向量是刚刚初始化的,还没有用反向传播更新,也就是说,新笔记的ID Embedding反映不出笔记的特点

冷启召回的困难:

  • 缺少用户交互,还没学好笔记ID Embedding,导致双塔模型(最重要的召回通道)效果不好。同时也会影响排序,让排序模型的预估不准确
  • 缺少用户交互,导致ItemCF对新物品不适用。ItemCF做召回的原理是判断两篇笔记的相似度有多高,要根据与笔记交互过的用户来判断两篇笔记的相似度

新物品召回通道

  • 类目、关键词召回是两种弱个性化的召回通道,在笔记刚刚发布时,这两种召回通道是最有用的;但是在笔记发布一段时间后,这两种召回通道会失效
  • 聚类召回、Look-Alike召回是专门针对新物品的召回通道

双塔模型(改造后适用于冷启动)

笔记ID 是物品塔中最重要的特征,神经网络的Embedding层把笔记ID映射成向量。每篇笔记都有一个ID Embedding,需要从用户和笔记的交互中学习。新笔记没有跟几个用户交互过,它的ID Embedding还没学好;如果直接用双塔模型做新笔记的召回,效果会不太好

改造方案1:新笔记使用default embedding

  • 物品塔做ID embedding时,让所有新笔记共享一个ID(值为default),而不是用新笔记自己真正的ID
  • Default Embedding:共享的ID对应的Embedding向量。这个向量是学出来的,不是随机初始化或全0初始化,这样效果更好
  • 新笔记发布后,逐渐会有点击和交互,这些信号可以用来学习笔记的ID Embedding。到下次模型训练时,新笔记才有自己学到的ID Embedding向量

改造方案2:利用相似笔记的Embedding向量

  • 相似可以用图片、文字、类目来定义,用多模态神经网络把一篇笔记的图文内容表征为一个向量。查找 topk内容最相似的高爆笔记,因为高曝光笔记的ID Embedding通常学的比较好
  • 把k个高曝笔记的Embedding向量取平均,作为新笔记的Embedding

多个向量召回池

  • 多个召回池,让新笔记有更多曝光机会,如1h新笔记、6h新笔记、24h新笔记、30天笔记(假如只有一个30天笔记的召回池,新笔记被召回的几率很小,很难得到曝光)
  • 多个召回池共享同一个双塔模型,因而不增加训练模型的代价

类目召回

用户画像中有感兴趣的类目(如美食、科技数码、电影等)和感兴趣的关键词(如纽约、职场、搞笑、程序员、大学等),有的是用户自己填写的,有的是算法自动推断出来的

  • 系统维护类目索引:类目 -> 笔记列表(按时间倒排,最新发布的笔记排在最前面)
  • 用类目索引做召回:用户画像 -> 类目 -> 笔记列表
  • 取回笔记列表上前k篇笔记,即最新的k篇

关键词召回

原理跟类目召回完全一样

  • 系统维护关键词索引:关键词 -> 笔记列表(按时间倒排,最新发布的笔记排在最前面)
  • 根据用户画像上的关键词做召回

类目&关键词召回的缺点:

  • 缺点1:只对刚刚发布的新笔记有效
    • 取回某类目/关键词下最新的k篇笔记
    • 都是按照笔记发布时间倒排,留给每篇笔记的窗口期很短。笔记发布几小时之后,就再没有机会被召回
  • 缺点2:弱个性化,不够精准
    • 用户感兴趣的类目、关键词比较宽泛

类目&关键词召回的优点:

  • 能让刚刚发布的新笔记立刻获得曝光,有利于提升作者的发布积极性

3、聚类召回(基于笔记的图文内容做推荐)

在物品冷启动时特别有用

基本思想

如果用户喜欢一篇笔记,那么他会喜欢内容相似的笔记 

  • 需要判断两篇笔记的内容相似度:事先训练一个神经网络,基于笔记的类目和图文内容,把笔记映射到向量,向量相似度就是笔记内容相似度

对笔记向量做聚类,划分为1000 cluster,记录每个cluster的中心方向

  • k-means聚类,用向量的余弦相似度

聚类索引:

聚类召回通道有一个索引,当新笔记发布时,新笔记就会上索引

索引是如何建立的?

  • 一篇新笔记发布之后,用神经网络把它的图文内容映射到一个特征向量
  • 把新笔记的特征向量跟1000个cluster中心向量作比较,找到最相似的向量作为新笔记的cluster。至此新笔记绑定了一个cluster,把新笔记的ID添加到索引上
  • 索引:cluster -> 笔记ID列表(按时间倒排)

概括一下,一篇新笔记发布之后,要判断它跟1000个cluster中哪个最相似,然后把笔记ID添加到索引上。有了索引就可以在线上做召回

线上召回:

当一个用户刷小红书(给定用户ID),发起线上请求,找到他的 last-n交互笔记列表(包括点赞、收藏、转发的笔记列表),把这些笔记作为种子笔记

把每篇种子笔记映射到向量,与1000个中心向量作比较,寻找最相似的cluster(知道了用户对哪些cluster感兴趣)

从每个cluster的笔记列表中,取回最新的m篇笔记。最多取回m*n篇新笔记

  • n:保留最新n条用户行为记录,包括点赞、收藏、转发等行为,把这n篇笔记作为种子笔记
  • m:每篇种子笔记召回m篇新笔记

聚类召回和类目召回有相同的缺点,都是只对刚刚发布的新笔记有效,一篇笔记被发布一两个小时之后就不太可能被召回了

内容相似度模型

聚类召回需要调用一个神经网络,把笔记图文内容映射为向量。如果两篇笔记的内容相似,那么两篇笔记的向量就应该有较大的余弦相似度

模型结构

只考虑笔记只有一张图的情况

有两篇笔记,各自都有图片和文字。两篇笔记的内容相似度: 

训练

训练方法跟双塔模型比较类似

每个训练样本都是个三元组:正样本笔记、种子笔记、负样本笔记

  • <种子笔记,正样本>
  • <种子笔记,负样本>

(1)训练目标: 

(2)正负样本的选取:

正样本:相似度高的笔记

方法1:人工标注 <种子笔记,正样本>二元组 的相似度

  • 人工标注代价太大

方法2:算法自动选正样本

  • 筛选条件(可以过滤掉完全不相似的笔记):
    • 只用高曝光笔记作为二元组(因为有充足的用户交互信息,算法选的正样本会比较准)
    • 两篇笔记有相同的二级类目,比如都是“菜谱教程”
  • 用 ItemCF 的物品相似度选正样本(ItemCF靠用户和笔记的交互记录判断笔记的相似度,有越多用户同时对两篇笔记感兴趣,就说明两篇笔记越相似)

负样本:从全体笔记中随机选出满足条件的

  • 字数较多:神经网络提取的文本信息有效
  • 笔记质量高,避免图文无关

【聚类召回总结】

基本思想:根据用户的点赞、收藏、转发记录,推荐内容相似的笔记

线下训练:多模态神经网络把图文内容映射到向量。通过比较两个向量的cos相似度,就知道哪两个向量比较相似

线上服务:根据用户历史上喜欢的笔记,召回相似的新笔记(用户喜欢的笔记 -> 特征向量 -> 最近的cluster -> 新笔记)

  • 把用户历史上喜欢的笔记输入神经网络,计算出一个特征向量
  • 把特征向量跟1000个cluster中心向量作比较,找到最相似的中心向量,选择这个cluster
  • 每个cluster都有一个笔记列表,按照时间顺序倒排,选择列表中前几篇笔记,即最新的几篇作为召回结果

4、Look-Alike人群扩散召回

Look-Alike是互联网广告中常用的一类方法,也可以用在推荐系统,特别是召回低曝光笔记

起源于互联网广告 

假设广告主想精准的给目标受众投放广告。满足所有条件的受众被称为种子用户,这样的用户数量一般不多,但潜在的符合条件的用户往往很多(缺少他们的部分信息,无法找到)

  • 跟新笔记有交互行为的用户叫种子用户
  • 寻找跟种子用户相似的用户,把找到的用户称作Look-Alike用户

如何计算两个用户的相似度? 

  • UserCF:两个用户有共同的兴趣点。要是两个用户同时对很多相同的物品感兴趣,说明两个用户的相似度比较大
  • Embedding:两个用户的ID Embedding向量的cosine较大,说明两个用户的相似度比较大

用于新笔记召回

若用户有点击、点赞、收藏、转发等行为,说明用户对笔记可能感兴趣。把有交互的用户作为新笔记的种子用户,即种子用户对新笔记感兴趣

如果一个用户跟种子用户相似,那么他也可能对这篇新笔记感兴趣,可以把新笔记推荐给他。即用Look-Alike在相似用户中扩散

一句话总结Look-Alike人群扩散:根据种子用户找出更多兴趣相似的用户,把新笔记从种子用户扩散到更多Look-Alike用户

对这个新笔记的特征向量需要做近线更新:不用(没有必要)在线实时更新(几秒内),分钟级更新即可(交互发生几分钟后就能更新笔记的特征向量)

  • 特征向量是有交互的用户的向量的平均
  • 每当有用户交互该物品,更新笔记的特征向量 

线上召回:

Look-Alike召回通道专门用于物品冷启动,原理如下:

5、流量调控

背景

冷启动的优化点
  • 优化全链路,包括召回和排序,让新笔记有足够多的机会走完链路被曝光;还要尽量让新笔记的推荐做的准,不要让用户反感
  • 流量调控,即流量怎么在新物品、老物品中分配。工业界常见做法是让流量向新笔记倾斜,帮助新笔记获得更多的曝光机会
为什么给新笔记流量倾斜?

扶持新笔记的目的:

  • 目的1:促进发布,增大内容池
    • 新笔记获得的曝光越多,作者创作积极性越高
    • 反映在发布渗透率、人均发布量(会提升)
  • 目的2:挖掘优质笔记
    • 做探索,让每篇新笔记都能获得足够曝光
    • 挖掘的能力反映在高热笔记占比,比如点击1000次以上笔记的占比会更高
工业界的做法

假设推荐系统只分发年龄<30天的笔记(超过30天的笔记通常不会出现在推荐的结果里,只能通过搜索和其他渠道曝光)

  • 假设采用自然分发,新笔记(年龄<24h)的曝光占比为1/30
  • 扶持新笔记,让新笔记的曝光占比远大于1/30,即新笔记的流量远远大于自然分发的流量
流量调控技术的发展
  1. 在推荐结果中强插新笔记,让新笔记获得额外的曝光机会
  2. 对新笔记的排序分数做提权(boost),如加上或乘以一个系数,这样会让新笔记更占优势,获得更多的曝光机会
  3. 通过提权,对新笔记做保量,比如尽量保证每篇新笔记在前24h获得至少100次曝光。保量也是提权,但策略更精细
  4. 差异化保量。在笔记刚刚发布时,根据内容质量,决定保量的目标是多少次曝光。内容质量高的,保量的目标定的高,给更多的流量倾斜

新笔记提权(boost)

  • 粗排会做截断,从几千物品中选出几百个
  • 重排时会根据精排分数和多样性分数做抽样,从几百个物品中选出几十个,曝光给用户

如果不用规则干涉,而是让新老笔记自由竞争,那么新笔记的曝光机会很有限。假设推荐系统主要分发年龄<30天的笔记,如果纯粹用自然分发,那么曝光的笔记中,年龄<24h的新笔记应该占1/30

如果想让新笔记占到更多曝光,那么就必须做人为干涉,干涉粗排和重排(这两个环节是漏斗,会过滤掉大量笔记)。干涉的方法就是对新笔记提权,让新笔记比老笔记更有优势,有更多的机会通过漏斗;然后让新老笔记自由竞争,谁的分数高,谁就有更大几率通过漏斗,最终获得曝光

  • 新笔记提权目标:让新笔记有更多机会曝光
    • 如果只做自然分发,不干涉新笔记的权重,那么24h新笔记的曝光占比为1/30
    • 做人为干涉,给新笔记提权,让新笔记占比大幅提升,远远大于1/30
  • 干涉粗排、重排环节,给新笔记提权,可以给新笔记的分数乘以一个>1的系数(人为设置提权系数,乘到排序模型打的分数上)
  • 优点:容易实现,投入产出比好
  • 缺点:曝光量对提权系数(要乘到排序模型打的分数上)很敏感。系数大一点,可能会把很多低质量的新笔记排在前面;系数小一点,给新笔记的曝光可能不足。因此,很难精确控制曝光量,容易过度曝光和不充分曝光

新笔记保量

保量:不论笔记质量高低、笔记内容,都保证前24h获得100次曝光

要差异化对待不同发布时间、不同曝光次数的笔记:

  • 24h获得100次曝光是保量的目标,离100次曝光差的越多,提权的系数就越大,争取给笔记更多的曝光机会
  • 举个例子,等比例来算,12h应该获得50次曝光。如果12h达到50次曝光了,那么提权系数就是1,不给额外扶持;如果12h只达到20次曝光,就应该加大扶持力度,比如乘以提权系数1.2
动态提权保量 (!)

用函数动态计算调权系数:第一个数越大,第二个数越小,提权系数就应该越大

保量的难点

(1)保量成功率远低于100%,即很多笔记在24h达不到100次曝光。原因:

  • 召回、排序存在不足。比如有些类型的新笔记很难被召回,就算提权系数再高,这样的新笔记也很难获得曝光;也有可能是排序模型对新笔记的预估做的不准
  • 新笔记的提权系数没有调好,导致曝光不足

(2)线上环境变化会导致保量失败

  • 线上环境变化:新增召回通道、升级排序模型、改变重排打散规则...
  • 线上环境变化后,需要调整提权系数
思考题

给所有新笔记一个很大的提权系数(比如4倍),直到达成100次曝光为止就不再做提权,跟老笔记同等对待。这样的保量成功率很高,但效果不好。原因分析如下:

给新笔记分数boost越多,对新笔记越有利?   否

  • 在笔记冷启阶段,分数提升越多,对新笔记曝光次数越有利
  • 过了冷启阶段,之前大力度的扶持会起反作用
    • 如果不用人为提升预估分数,只有遇到匹配受众时,预估分数才会高,笔记才能通过最终排序筛选曝光给用户
    • 若人为大幅提升笔记分数,笔记很容易通过排序筛选(哪怕笔记不是用户感兴趣的),导致容易把笔记推荐给不太合适的受众
      • 点击率、点赞率等指标会偏低
      • 长期会受推荐系统打压,难以成长为热门笔记

差异化保量 (!)

保量:不论新笔记质量高低,都做扶持,在前24h给100次曝光

差异化保量:不同笔记有不同保量目标,普通笔记保100次曝光,内容优质的笔记保100~500次曝光。具体的保量目标由算法判定:

  • 每篇笔记都有一个基础保量(如24h获得100次曝光)
  • 差异化保量的依据:
    • 笔记内容质量:用多模态神经网络模型判断笔记图文、视频的质量高低,给予额外保量目标,上限是加200次曝光
    • 作者质量:根据作者以前发布笔记的质量,给予额外保量目标,上限是加200次曝光
  • 新笔记在前24h至少保100次曝光,最多保500次曝光。达到保量目标后停止扶持,让新笔记自然分发,跟老笔记公平竞争

【总结】

  • 流量调控:让策略决定流量怎么在新老笔记之间分配
  • 扶持新笔记:可以促进作者发布。有两个途径:(1)给新笔记增加单独的召回通道;(2)给新笔记在排序阶段提权
  • 保量:帮助新笔记在前24h获得100次曝光。保量的成功率达不到100%
  • 差异化保量:根据内容质量、作者质量,给每篇笔记单独定一个保量目标。差异化保量有助于扶持高质量的新笔记,对整个生态有益

根据业界经验,如果能把保量的技术做好,对发布侧指标有非常大的提升

6、冷启的AB测试

想要上线新的模型或者策略,需要做AB测试。在小红书的场景下,冷启的AB测试既要看作者侧指标(也叫发布侧指标),也要看用户侧指标(也叫消费侧指标)

  • 作者侧指标:可以反映出作者的发布意愿,如果冷启做得好,可以激励作者发布,让渗透率和发布量上涨(用ab测试去考察作者侧指标是比较困难的,原因见后
  • 用户侧指标:
    • 冷启的推荐做的越精准,用户对推荐的新笔记越感兴趣,新笔记的点击率和交互率就会越高;
    • 除此之外,还要看大盘的消费指标(消费时长、日活、月活)。不希望冷启推荐的新笔记引起用户反感,导致用户不活跃、大盘指标下跌
  • 标准的AB测试通常只测大盘指标这种用户侧指标,而冷启的AB测试需要测很多指标

标准的AB测试

标准的AB测试:

  • 把用户随机分成两组,每组有50%用户,即实验组和对照组(也可以分成很多组,这里只是举个最简单的例子) 
  • 全体笔记不分组
  • 给实验组用户做推荐,会从全量的笔记池中选出最合适的笔记。当实验组用户发起推荐请求时,用新策略。对照组同理,只是用旧策略做推荐
  • 在实验过程中,对比两组用户消费指标的diff,比如考察用户消费推荐内容的时长 

冷启的AB测试

要测两类指标:用户侧消费指标 and 作者侧发布指标

用户侧实验(消费指标)

推荐系统标准的AB测试可以用于冷启,考察用户侧消费指标:

但这种AB测试的设计有不足之处:

  • 限定:冷启的流量调控机制要求保量,尽量给新笔记100次曝光
  • 假设:新笔记曝光越多,用户使用APP时长越低(因为新笔记通常推荐的不准,过多新笔记会影响体验)
  • 新策略:排序时给新笔记提权,把新笔记排序时的权重增大两倍。这样会让新笔记有更多机会曝光,但会伤害用户体验,导致消费指标变差
  • 只看消费指标的结果:
    • AB测试的diff是负数(策略组不如对照组)
    • 如果推全(即对所有用户都上新策略),diff会缩小(比如 -2% -> -1%),即新策略对用户体验的伤害没有ab测试观测到的那么严重(为什么?)

提示:

  • 给实验组提权两倍,那么实验组用户看到的新笔记会变多,实验组的消费指标会变差
  • 保量100次的曝光是确定的,既然新笔记从实验组那里得到更多曝光,那么从对照组得到的曝光就会减少,对照组的消费指标会变好
  • 实验组变差,对照组变好,导致AB测试观测到的diff很大
  • 但推全后,消费指标实际跌不了那么多

作者侧实验(发布指标)

没有完美的实验方案

方案一
  • 不对用户做分组
  • 不对老笔记做分组(老笔记完全自然分发,不受新旧策略的影响,从全量老笔记中选出用户最喜欢的,推荐给用户)
  • 但要区别对待新笔记和老笔记。新笔记按作者随机分成两组,这样可以对比作者的发布积极性(对照组和实验组的新笔记都有机会触达全体用户

缺点1:两组新笔记之间抢流量。存在这种可能性,实验观测到diff,比方说作者的发布指标涨了2%,但推全之后,发布指标没有任何变化,即AB测试观测到的diff是不可信的,推全后可能会消失(为什么?)

  • 设定:
    • 新老笔记走各自队列,没有竞争,各自做排序,各自做截断
    • 重排分给新笔记1/3流量,分给老笔记2/3流量,两者的曝光占比是固定不变的
  • 新策略:把新笔记重排时的权重增大两倍
  • 只看发布侧指标的结果:
    • AB测试的diff是正数(策略组优于对照组)
    • 如果推全,diff会消失(比如 2% -> 0)
  • 原因:在设定下,这种新策略不会产生任何影响。新笔记只跟新笔记竞争,其曝光占比还是1/3,所以新策略不会激励发布

因为实验组给新笔记提权,对照组新笔记没有提权。实验组提权的新笔记会抢走对照组的曝光,那么实验组的发布指标会涨,对照组的发布指标会跌,导致产生diff;如果把新策略推全,所有新笔记都提权,就不存在两组新笔记之间抢流量,不会出现diff

缺点2:新笔记跟老笔记之间抢流量(AB测试和推全之后的设定发生了变化,导致AB测试的结果不准确)。如果让新老笔记自由竞争,50%的新笔记提权之后,会抢100%老笔记的流量(平均1份新笔记可以抢走2份老笔记的流量)。如果推全,就是100%新笔记抢100%老笔记的流量(1份新笔记只抢走1份老笔记的流量),也就是说,推全之后新笔记更难抢到流量

  • 设定:新老笔记自由竞争,不控制新老笔记的曝光占比
  • 新策略:把新笔记排序时的权重增大两倍,让新笔记更有优势
  • AB测试时,50%新笔记(带策略,提权系数×2)跟100%老笔记抢流量,一份新笔记可以抢走两份老笔记的流量
  • 推全后,设定发生变化,所有新笔记都带策略,100%新笔记(带策略)跟100%老笔记抢流量,一份新笔记只能抢走一份老笔记的流量
  • 结果:作者侧AB测试结果(如发布渗透率涨了2%)与推全结果(如大盘发布渗透率只涨了1%)有差异
方案二

跟方案一的区别:用户也被分成了两组,实验组用户只能看到实验组新笔记,对照组用户只能看到对照组新笔记

目的:避免两组新笔记抢流量。AB测试结果比方案一更可信

缺点:新笔记内容池减小

  • 原本一个用户在刷小红书时,推荐系统会从全体新笔记中选出100篇最符合用户兴趣的
  • 现在新笔记内容池小了一半,100篇最符合用户兴趣的笔记只剩了50篇,要从差一些的笔记中再选出50篇补上来,这肯定会影响用户体验,造成消费侧指标下跌(为了做个ab测试,导致大盘变差,公司业务受损)

优点:同时隔离用户和新笔记。新笔记的两个桶不抢流量,作者侧实验结果更可信(如果AB测试观测到发布指标有diff,那就说明确实有diff,推全之后diff不会消失

两个方案共同的缺点:新笔记和老笔记抢流量(AB测试时50%新笔记跟100%老笔记抢流量,推全后全量新笔记跟全量老笔记抢流量),导致作者侧AB测试结果与推全结果有些差异

方案2比方案1的缺点:隔离后,每个用户对应的新笔记池都减小了一半,会让推荐结果变差,对用户体验造成负面影响

方案三

把老笔记也分成两个组(这样做相当于把一个APP切成两个)。实验结果最精准,但不实际可行(内容池少了一半,严重损害用户体验,消费指标大跌)

总结

冷启的AB测试需要观测作者发布指标用户消费指标。这是因为冷启至少有两个目标:激励作者发布 & 让用户满意

各种AB测试的方案都有缺陷。设计方案的时候,要思考:

  • 实验组、对照组的新笔记会不会抢流量?
  • 新笔记、老笔记怎么抢流量?AB测试时是怎么抢的?推全之后又是怎么抢的?如果存在变化,那么AB测试的结果会不准
  • 同时隔离笔记和用户,会不会让内容池变小?若变小,肯定会影响推荐效果,让用户体验变差。即为了做AB测试影响了大盘,损害了公司业务
  • 如果对新笔记做保量,比如保100次曝光,会发生什么?实验准确性会不会受保量的影响?如果笔记从实验组获得了很多次曝光,就不容易出现在对照组用户那里(因为保量总数是固定的)

(八)涨指标的方法

1、概述

推荐系统的评价指标

对长线推荐系统来说,日活用户数(DAU)留存最核心的指标(对于信息流推荐系统来说)

  • 若是电商推荐系统,最核心的指标是营收

目前工业界最常用LT7LT30衡量留存

  • 某用户今天 (t0) 登录APP,包括今天在内的未来7天 (t0~t6) 中有4天登录APP,那么该用户今天 (t0) 的LT7等于4
  • 对于今天登录APP的所有用户,取LT7的平均,就是整个APP今天的LT7
  • 显然有 1 ≤ LT7 ≤ 7 和 1 ≤ LT30 ≤ 30
    • LT7=1(min):若用户今天登录,但是之后6天都不再登录
    • LT7=7(max):若用户今天和未来6天全都登录
  • LT增长通常意味着用户体验提升(除非LT增长且DAU下降)
    • LT增长且DAU下降:用户体验没有提升,是策略赶走了不活跃的用户
    • 由于LT存在这种问题,实践中模型或策略导致LT增长时,还需要确保DAU不下降

分析:假设APP禁止低活用户登录,则DAU下降(因为总用户数减小了),LT增长(计算LT,其实就是圈定今天活跃的用户,把他们的数量作为分母, 他们的总活跃天数作为分子,分子/分母就是LT。把低活用户赶走,分子变小,但分母变小的更多,导致LT增加)

其他核心指标:用户使用时长、总阅读数(即总点击数)、总曝光数。这些指标的重要性低于DAU和留存

  • 时长增多,LT(留存)通常会增多
  • 时长增多,阅读数、曝光数可能会下降(时长关系到DAU和留存,曝光数关系到广告收入,需要对两者做平衡)
  • 对于UGC平台(如抖音、快手、小红书),物品都是普通用户创作的,平台会鼓励发布以让平台的内容池更丰富,发布量发布渗透率也是核心指标

分析:用户使用时长,通常跟留存是正相关的,但跟阅读数、曝光数会此消彼长(如抖音推荐的长视频变多、短视频变少,那么用户使用APP的总时长会变多,但曝光数会减小,因为用户看一个长视频要很久,看完之前不刷更多的视频)

非核心指标:点击率、交互率等等(下跌也没关系,只要核心指标上涨就行)

涨指标的方法有哪些?

  • 最重要的指标:DAU、留存
  • 其他核心指标:时长、阅读、曝光、发布

1-2是模型,3-5是工业界的实际经验 

2、召回

召回模型&召回通道

推荐系统有几十条召回通道,它们的召回总量是固定的,比如5000,粗排给这5000个物品打分(分配给这几十条召回通道)。总量越大,指标越好,但粗排计算量也越大

  • 增加召回的总量,推荐系统的核心指标会上涨,但是粗排的计算量也会增加

双塔模型(two-tower) item-to-item(I2I)是最重要的两类召回模型,占据召回的大部分配额

  • 这两类模型各自有很多条召回通道,他们加起来可以占据召回总量的一大半

添加新的召回模型:有很多小众的模型,占据的配额很少。在召回总量不变的前提下,添加某些召回模型可以提升核心指标

添加内容池:有很多内容池,比如年龄<30天物品、1天物品、6小时物品、新用户优质内容池、分人群内容池

  • 只需要训练一个双塔模型,就可以同时用于多个内容池。不会增加训练的计算量,但能得到多条召回通道,每条召回通道都有一定的配额
  • 每个内容池都需要一个ANN索引,在线上做ANN检索,需要增加少量计算成本

改进双塔模型

方向1:优化正负样本

方向1:优化正样本、负样本

  • 简单正样本:有点击的(用户,物品)二元组
    • 用户点击了物品,说明用户对物品感兴趣,所以可以当正样本
  • 简单负样本:随机组合的(用户,物品)二元组
    • 给定一个用户,从全体物品库中均匀抽样一个物品,用户大概率不喜欢这个随机抽到的物品
  • 困难负样本:排序靠后的(用户,物品)二元组
    • 被召回、但在排序阶段排名靠后的。物品能被召回,说明用户或多或少对这个物品有些兴趣,但是物品在排序阶段被淘汰,则说明用户对这个物品的兴趣不大
方向2:改进模型结构

方向2:改进神经网络结构

  • baseline:用户塔、物品塔分别是全连接网络,各输出一个向量,分别作为用户、物品的表征
  • 改进1:用户塔、物品塔分别用DCN(深度交叉网络)代替全连接网络
  • 改进2:在用户塔中使用用户行为序列(last-n)
    • 用户行为序列建模:把用户最近交互过的n个物品表征为向量,把这n个向量的平均作为用户的一种特征输入用户塔
  • 改进3:使用多向量模型代替单向量模型(标准的双塔模型也叫单向量模型)
    • 单向量模型:两个塔各输出一个向量,两个向量的形状相同。根据向量相似度做分类,让模型能够区分正负样本
    • 多向量模型:
      • 物品塔跟单向量模型没有区别,只输出一个向量作为物品表征
      • 用户塔跟单向量模型有区别,输出很多向量,每个向量都跟物品向量的形状相同,可以计算它们的内积或cos相似度,作为对一个目标的预估,如预估点击率。如果一共要预估十个目标,那么用户塔会输出十个向量,但物品塔只输出一个向量,分别计算两两相似度作为对十个目标的预估

单向量模型只是做简单的二分类区分正负样本,而多向量模型类似于排序中的多目标模型,同时预估点击率、点赞率等很多目标 

为什么让用户塔输出多个向量,而物品塔只输出一个向量?

  • 物品塔的输出是物品向量表征,要事先算出来存入向量数据库。如果每个物品都有十个向量表征,那么就需要建十个向量数据库,做十套ANN索引,代价大
  • 让物品塔只输出一个向量,只需要一个向量数据库,代价小
方向3:改进训练方法

方向3:改进模型的训练方法

  • baseline:做二分类,让模型学会区分正样本和负样本
  • 改进1:结合二分类、batch内负采样(对于batch内负采样,需要做纠偏)
    • 对于batch内负采样,热门物品成为负样本的概率会偏高,需要做纠偏

  • 改进2:使用自监督学习方法,让冷门物品的Embedding学得更好
    • 原理:冷门物品的点击次数太少,导致冷门物品的向量表征学得不好,用自监督学习对提升冷门物品的推荐有帮助,从而提升推荐系统整体的指标

Item-to-Item(I2I,寻找相似物品)

I2I是一大类模型的总称,基于相似物品做召回 

U2I2I

最常见的用法是U2I2I(user -> item -> item)

  • 用户u喜欢物品i1(用户历史上交互过的物品)
  • 寻找i1的相似物品i2(即I2I)
  • 将i2推荐给用户u
如何计算物品相似度?

方法1:ItemCF及其变体(靠用户行为判断两个物品有多相似) 

  • 一些用户同时喜欢物品i1和i2,则认为i1和i2相似
  • ItemCF、Online ItemCF、Swing、Online Swing(4种I2I模型)都是基于相同的思想。四种模型召回的结果存在足够大的差异,所以结合起来效果更好
  • 在给I2I总配额固定的情况下,同时用四种模型,比只用一种效果更好。线上同时使用上述4种I2I模型,各分配一定配额

方法2:基于物品向量表征,计算向量相似度(用物品的向量内积或余弦相似度来衡量物品有多相似)

  • 双塔模型、图神经网络均可计算物品向量表征
  • 双塔模型计算出的物品向量,其实就是对物品兴趣点的表征

小众的召回模型

双塔和I2I可以占据召回总量的一大半。小众召回模型占据配额很小,但能提升推荐系统指标

类似I2I的模型

U2U2I(user -> user -> item):已知用户u1与u2相似,且u2喜欢物品i,那么给用户u1推荐物品i

  • 基于相似用户做推荐(UserCF)

U2A2I(user -> author -> item):已知用户u喜欢作者a,且a发布物品i,那么给用户u推荐物品i

  • 基于(隐式)关注关系做推荐(作者召回)

U2A2A2I(user -> author -> author -> item):已知用户u喜欢作者a1,且a1与a2相似,a2发布物品i,那么给用户u推荐物品i

  • 基于作者相似性做推荐(相关作者召回)
更复杂的模型

在召回总量不变的情况下,添加这样的召回通道可以提升大盘指标

  • PDN(Path-based Deep Network):Li et al. Path-based Deep Network for Candidate Item Matching in Recommenders. In SIGIR, 2021.
  • Deep Retrieval:Gao et al. Learning an end-to-end structure for retrieval in large-scale recommendations. In CIKM, 2021.
  • Sparse-Interest Network(SINE):Tan et al. Sparse-interest network for sequential recommendation. In WSDM, 2021.
  • Multi-task Multi-view Graph Representation Learning(M2GRL):Wang et al. M2GRL: A multitask multi-view graph representation learning framework for web-scale recommender systems. In KDD, 2020.

总结:改进召回模型

双塔模型:优化正负样本、改进神经网络结构、改进训练方法

I2I模型:同时使用ItemCF及其变体(ItemCF和Swing)、使用物品向量表征计算物品相似度

  • 用很多种方法计算物品相似度,会得到很多条I2I召回通道,同时使用它们有利于提升指标

添加小众的召回模型,比如PDN、Deep Retrieval、SINE、M2GRL等模型。这些模型占据的召回配额都很小,但它们都可以涨指标

  • 增加召回总量显然可以提升推荐系统的核心指标,但是召回的物品越多,粗排的计算量就越大。召回总量大到一定程度的时候,继续增加召回总量的边际效益会很小,投入产出比不划算

在召回总量不变的前提下,调整各召回通道的配额

  • 可以让各用户群体用不同的配额,比如新用户和普通用户这两个群体,给各条召回通道设置的配额不同

后续:通过添加新的内容池来提升推荐系统的核心指标

3、排序模型

  1. 精排模型的改进
  2. 粗排模型的改进
  3. 用户行为序列建模
  4. 在线学习
  5. 老汤模型

精排模型的改进

(1)基座:

  • 神经网络用Embedding层把离散特征映射到数值向量,把得到的数值向量拼接起来,得到一个几千维的向量,再经过几个全连接层,输出一个几百维的向量(左边的绿色向量)
  • 连续特征(几百个)输入到另一个全连接网络,输出是一个几百维的向量(右边的蓝色向量)

由于算力限制,这两个全连接网络都不会很大。用CPU推理的话,算力不够,通常只有1~2层;用GPU推理的话,可以有3~6层

(2)多目标预估: 

左边的绿色向量和右边的蓝色向量concat后输入多个全连接网络(通常只有2层),输出都是0~1的数值,作为对各种目标(如点击率、点赞率、转发率、评论率)的预估

精排模型下面的基座和上面的多目标预估都有很多可以改进的点,下面各自阐述

(下) 基座

下面的两个神经网络叫基座,作用是把原始特征映射到数值向量

基座的输入包括离散特征和连续数值特征,输出一个向量(即左右两边向量的Concatenation),作为多目标预估的输入

改进1:基座加宽加深,计算量更大,预测更准确 

  • 精排模型的全连接网络不够大,通常会underfit;推荐系统的参数量很大,有几千亿甚至万亿,但99%以上的参数都在Embedding层,全连接网络的参数量很小。数据量大,但全连接网络不够大,所以加宽加深全连接网络可以让预测变得更准,但计算量会加大
  • 工业界通常是1~6层全连接层,取决于模型训练和推理的工程架构水平

改进2:做自动的特征交叉,比如 bilinear 和 LHUC

  • Huang et al. FiBiNET: combining feature importance and bilinear feature interaction for click-through rate prediction. In RecSys, 2019.
  • Swietojanski et al. Learning hidden unit contributions for unsupervised acoustic model adaptation. In WSDM, 2016.

改进3:特征工程,比如添加统计特征、多模态内容特征

  • 根据经验设计特征,判断哪些特征对预估有用、哪些特征可以做交叉
(上) 多目标预估

基于基座输出的向量,同时预估点击率等多个目标

改进1:增加新的预估目标,并把预估结果加入融合公式

  • 最标准的目标包括点击率、点赞率、收藏率、转发率、评论率、关注率、完播率...
  • 寻找更多目标,比如进入评论区、给他人写的评论点赞...
  • 把新的预估目标加入融合公式,排序时会用到新的目标(寻找跟用户兴趣相关的目标,添加这样的目标可以提升留存等指标)

改进2:MMoE、PLE等结构可能有效,但往往无效

  • Ma et al. Modeling task relationships in multi-task learning with multi-gate mixture-of-experts. In KDD, 2018.
  • Tang et al. Progressive layered extraction (PLE): A novel multi-task learning (MTL) model for personalized recommendations. In RecSys, 2020.

改进3:纠正 position bias 可能有效,也可能无效,即debais

  • Zhou et al. Recommending what video to watch next: a multitask ranking system. In RecSys, 2019.

粗排模型的改进

上述精排中提到的,自动特征交叉、人工特征工程、增加新的预估目标,也能用于粗排。下面是专门针对粗排的优化

粗排模型结构

粗排的打分量(5000个)比精排(500个)大10倍,形成漏斗,那么单个物品的计算量需要减小十倍,避免线上推理消耗太大算力,因此粗排模型必须够快

粗排不需要跟精排一样准确,所以可以用简单模型:多向量双塔模型,同时预估点击率等多个目标

复杂模型:三塔模型效果好,但工程实现难度较大

Wang et al. COLD: towards the next generation of pre-ranking system. arXiv, 2020. (三塔模型)

粗精排一致性建模(蒸馏精排 -> 训练粗排)

蒸馏精排训练粗排,让粗排的分数和序与精排更一致

方法1:pointwise蒸馏

  • 设y是用户真实行为,p是精排的预估,用 (y+p)/2 作为粗排拟合的目标
  • 如果不做蒸馏,训练时会直接用y作为目标。蒸馏用y和p的均值实际效果会比只用y更好
  • 例:对于点击率目标,用户有点击(y=1),精排预估p=0.6。用 (y+p)/2 = 0.8 作为粗排拟合的点击率目标

方法2:pairwise或listwise蒸馏

  • 给定k个候选物品,按照精排预估的某个目标做排序,比如根据精排预估的点击率做排序
  • 做LTR(Learning to Rank)训练粗排模型,让粗排拟合精排模型给物品排的序,而非具体预估的点击率数值
  • 例:对于物品i和j,精排预估点击率为pi>pj。LTR鼓励粗排预估点击率满足qi>qj,否则有惩罚
  • LTR通常用pairwise logistic loss:LTR(Learning to Rank)概述 | 小火箭的博客

优点:粗精排一致性建模可以提升核心指标

缺点:推荐系统的数据流、特征服务、模型推理,很多地方都可能出bug。如果精排出bug,精排预估值p有偏,做蒸馏会污染粗排训练数据,让粗排也逐渐变差

用户行为序列建模

用户最近交互过的n个物品(Last-n),对物品ID做embedding,把n个物品ID映射成n个向量,最后对向量取平均得到用户特征向量,表示用户曾经对什么样的物品感兴趣

最简单的方法是对物品向量取平均,作为一种用户特征

  • Covington, Adams, and Sargin. Deep neural networks for YouTube recommendations. In RecSys, 2016.

DIN使用注意力机制,对物品向量做加权平均

  • Zhou et al. Deep interest network for click-through rate prediction. In KDD, 2018.

工业界目前沿着SIM的方向发展。先用类目等属性筛选物品,然后用DIN对物品向量做加权平均

  • Qi et al. Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Through Rate Prediction. In CIKM, 2020.
改进方向

改进1:增加序列长度,让预测更准确,但是会增加计算成本和推理时间

  • 最大难点是工程架构

改进2:筛选的方法,比如用类目、物品向量表征聚类。目的是降低序列长度

  • 离线用多模态神经网络提取物品内容特征,将物品表征为向量。具体会用BERT或者CLIP这样的模型提取内容特征

  • 离线将物品向量聚为1000类,每个物品有一个聚类序号。通常用层次聚类
  • 线上排序时,用户行为序列中有n=100w个物品。某候选物品的聚类序号是70,对n个物品做筛选,只保留聚类序号为70的物品。n个物品中只有数千个被保留下来
  • 线上同时有好几种筛选方法,包括候选物品的类目、向量聚类,取筛选结果的并集
  • 降低到几千或者1w这个量级,可能还要再做进一步筛选,让用户序列变得更短,然后再输入到注意力层

改进3:对用户行为序列中的物品,使用ID以外的一些特征

  • 最简单的方法:对物品ID做Embedding,作为物品的向量表征
  • 还可以再加一些别的物品特征,但不能加太多,否则线上推理时通信和计算会出问题

总结:沿着SIM的方向发展,让原始的序列尽量长(超过100w),然后做筛选(类目/向量聚类)降低序列长度(几千/1w),最后将筛选结果输入DIN,对物品向量做加权平均

在线学习(即增量更新)

全量更新 vs 增量更新

模型训练的方式分为全量更新增量更新(即在线学习,Online Learning)

  • 在昨天凌晨的时候,用前天积累的数据训练模型。模型不是随机初始化的,而是基于前天凌晨训练好的ckpt继续训练;要把前天的数据做random shuffle打乱,然后做随机梯度下降,只训练1 epoch(每条数据只过一遍)
  • 昨天凌晨做好全量训练后,就要基于这个模型做分钟级别的增量更新。从昨天凌晨到今天凌晨,不间断地做Online Learning,隔一段时间发布一次模型,拿最新发布的模型在线上做推理
  • 昨天又积累了一天数据,到了今天凌晨,又要做一次全量更新。今天凌晨的全量更新,是基于昨天凌晨全量训练出的模型,而不是下面增量训练出的模型。在完成这次全量训练后,下面增量训练出的模型就可以扔掉了
  • 然后基于今天凌晨全量训练出的模型,再做分钟级别的增量更新,从今天凌晨到明天凌晨,不停做Online Learning,隔一段时间发布一次模型

在线学习对推荐系统指标的提升非常显著,但会消耗更多的算力 

在线学习的资源消耗

既需要在凌晨做全量更新(原先只需要这个),也需要全天不间断做增量更新(额外算力)。设在线学习需要10000 CPU core的算力增量更新一个精排模型,推荐系统一共需要多少额外的算力给在线学习?

  • 为了做AB测试,线上同时运行多个不同的模型。每个模型都需要做在线学习,全天24h计算梯度、更新模型
  • 如果线上有m个模型,则需要m套在线学习的机器,就需要 m*10000 CPU core的算力
  • 线上有m个模型,其中1个是holdout,1个是推全的模型,m-2个AB测试的新模型
  • 同样的道理,召回和粗排也需要在线学习,每个模型都需要一套在线资源。但好在召回和粗排的模型小,在线学习消耗的资源没有精排那么多
  • 每套在线学习的机器成本都很大,因此m数量很小,制约模型开发迭代的效率

  • 10%用户用于holdout,90%用户用于AB测试
  • 推全模型与holdout组模型可能相同,也可能不同(多数情况下,推全模型比holdout组模型要新几个版本)

在线学习对指标的提升巨大,但是会制约模型开发迭代的效率。最好在模型相对成熟之后再考虑在线学习,过早上在线学习很容易把模型锁死在较弱的版本,后续迭代会很慢

老汤模型问题

老汤模型是如何产生的?

无论做不做在线学习,都会用每天新产生的数据对模型做1 epoch的训练,久而久之,老模型训练的非常好,很难被超过。对模型做改进,重新训练,很难追上老模型

问题1:新是否优于老?

如何快速判断新模型结构是否优于老模型?(不需要追上线上的老模型,只需要判断新老模型谁的结构更优)

  • 对于新、老模型结构,都随机初始化模型全连接层
  • Embedding层可以是随机初始化,也可以是复用老模型训练好的参数 

这样处理全连接层和Embedding层,新老模型的区别只是模型结构而已,老模型并没有训练更久的优势

  • 用n天(n很小,十天左右)的数据同时训练新老模型(从旧到新,训练1 epoch)
  • 如果新模型显著优于老模型,新模型很可能更优。这样就有把握继续训练新模型,有希望追平和超过老模型

只是比较新老模型结构谁更好,而非真正追平线上的老模型。只用十天的数据训练新模型,不可能追平持续训练上百天的老模型

问题2:新如何追平老?

如何更快追平、超过线上的老模型?(只有几十天的数据,新模型就能追上训练上百天的老模型)

  • 假设已经得出初步结论,认为新模型很可能优于老模型。用几十天的数据训练新模型,早日追平老模型
  • 方法1:尽可能多地复用老模型训练好的Embedding层,避免随机初始化Embedding层(Embedding层是对用户、物品兴趣点的记忆,比全连接层学得慢。全连接层随机初始化没有关系)
  • 方法2:老模型做teacher,蒸馏新模型(在训练新模型的初期做蒸馏,可以大幅加速收敛,让新模型追的更快)
    • 用户真实行为是y,老模型的预测是p,用 (y+p)/2 作为训练新模型的目标

总结:改进排序模型

4、提升多样性

在召回和排序(包括粗排、精排)阶段都有很多技巧,提升其多样性

排序的多样性

精排多样性

精排阶段,结合兴趣分数多样性分数对 物品i 排序,这个排序几乎决定了用户最后看到的推荐结果

  • si:兴趣分数,即融合点击率等多个预估目标
  • di:多样性分数,即物品i 与 已经选中的物品 的差异
  • 用 si+di 对物品做排序

常用MMR、DPP等方法计算多样性分数,精排使用滑动窗口,粗排不使用滑动窗口

  • 精排决定最终的曝光,曝光页面上邻近的物品相似度应该小,不然两个相似的物品离得太近会影响用户体验。所以计算精排多样性要使用滑动窗口,保证同一个滑动窗口中的物品有足够大的差异
  • 粗排要考虑整体的多样性,而非一个滑动窗口中的多样性。因为粗排不决定最后的曝光,只是给精排提供候选

除了多样性分数,精排还使用打散策略增加多样性

  • 类目:当前选中物品i,之后5个位置不允许跟 i 的二级类目相同
  • 多模态:事先计算物品多模态内容向量表征,将全库物品聚为1000类;在精排阶段,如果当前选中物品i,之后10个位置不允许跟i 同属一个聚类,因为同一个聚类中的物品的图片和文字相似,应该被打散
粗排多样性

粗排给5000个物品打分,选出500个物品(200+300)送入精排。提升粗排和精排多样性都可以提升推荐系统核心指标

根据 si(粗排模型预估的兴趣分数)对5000个物品排序,分数最高的200个物品送入精排

  • 这里暂且不考虑多样性分数,优先考虑兴趣分数,保证用户最感兴趣的物品能够进入精排

对于剩余的4800个物品,对每个物品i 计算 兴趣分数si多样性分数di(物品i 跟已经选中的200个物品的差异。差异越大,多样性分数di 就越大)

  • 根据 si+di 对剩余4800个物品排序,分数最高的300个物品送入精排

召回的多样性

双塔模型:添加噪声

双塔模型一般来说占的召回配额最多。用户塔将用户特征作为输入,输出用户的向量表征;在向量数据库中做ANN检索,召回向量相似度高的物品

线上做召回时(在计算出用户向量之后,在做ANN检索之前),往用户向量中添加随机噪声,如随机高斯噪声。用户的兴趣越窄(比如用户最近交互的n个物品只覆盖少数几个类目),就越需要提升多样性,添加的噪声越强(添加噪声使得召回的物品更多样,可以提升推荐系统核心指标)

双塔模型:抽样用户行为序列

用户最近交互的n个物品(用户行为序列)是用户塔的输入,保留最近交互过的 r<<n 个物品,从剩余的 n-r 个物品中随机抽样 t<<n 个物品(可以是均匀抽样,也可以用非均匀抽样让类目平衡)。将得到的 r+t 个物品作为用户行为序列,而不是用全部n个物品,输入用户塔

抽样用户行为序列为什么能涨指标?

  • 一方面,注入随机性,召回结果更多样化
  • 另一方面,n可以非常大,可以利用到用户很久之前的兴趣(出于计算和通信的考虑,用户行为序列不能超过100个物品,因此只能覆盖用户最近很短一段时间的兴趣点。现在可以让n=1000,然后做随机抽样选出100个物品,这样用户行为序列就能覆盖住用户更久以前的兴趣点,但是召回的计算代价不变)
U2I2I:抽样用户行为序列

U2I2I(user -> item -> item)中的第一个item是指用户最近交互的n个物品之一,即用户行为序列中的物品,在U2I2I中叫做种子物品

n个物品覆盖的类目数较少,且类目不平衡

  • 系统共有200个类目,某用户的n个物品只覆盖15个类目,这说明用户的兴趣不是很宽泛
  • 这n个物品的类目非常不平衡,15个类目中足球类目的物品有0.4n个,电视剧类目的物品有0.2n个,其余类目的物品数均少于0.05n个
  • 假如直接用这n个物品作为种子,召回的物品会集中在足球和电视剧,召回的多样性很差

做非均匀随机抽样,从n个物品中选出t个,让类目平衡(想法和效果与双塔中的用户行为序列抽样相似)。用抽样得到的t个物品(代替原本的n个物品)作为U2I2I的种子物品。一方面,类目更平衡,多样性更好;另一方面,n可以更大,然后再从n个抽样出一个子集(几千->几十),覆盖的类目更多

2%探索流量

每个用户曝光的物品中有2%是非个性化的,用作兴趣探索。具体做法:

维护一个精选内容池,其中物品均为交互率指标高的优质物品(内容池可以分人群,比如30~40岁男性用户交互率高的物品构成内容池,只推荐给30~40岁男性用户)

  • 既然没有了个性化,就要提高物品质量来吸引用户,用高质量来弥补缺少个性化造成的损失

从精选内容池中随机抽样几个物品,跳过排序,直接插入最终排序结果 

  • 原因:没办法对这样的物品做公平的排序,这样的物品不匹配用户过去的兴趣点,大概率会被排序模型淘汰掉,所以只能做提权或者强插

兴趣探索在短期内负向影响核心指标(非个性化推荐会导致点击率偏低),但长期会产生正向影响,可以发掘用户更多兴趣点,更好地吸引用户留存

总结:提升多样性

精排:

  • 结合兴趣分数和多样性分数做排序,可以让曝光物品更多样化;
  • 做规则打散,强行提升多样性

粗排:

  • 只用兴趣分数选出部分物品,保送精排;
  • 结合兴趣分数和多样性分数选出另外一部分物品送入精排

召回:

  • 双塔和I2I是最重要的两类召回模型,占据召回大部分配额
  • 往双塔模型的用户向量添加噪声,让双塔召回的物品更加多样化
  • 对用户行为序列做非均匀随机抽样(对双塔和U2I2I都适用),目的也是提升多样性

兴趣探索:

  • 保留少部分的流量给非个性化推荐,这在长期是有好处的

5、特殊对待特殊用户人群(新用户、低活用户)

为什么要特殊对待特殊人群

  1. 新用户、低活用户的行为很少,个性化推荐不准确,或者用非个性化推荐做弥补(个性化召回和排序都要基于用户的历史行为)
  2. 新用户、低活用户容易流失,要想办法促使他们留存(对于全体用户,推荐系统要提升很多指标,包括留存、时长、阅读、消费;但对于新用户和低活用户,只需要考虑留存)
  3. 特殊用户的行为(比如点击率、交互率)不同于主流用户,基于全体用户行为训练出的模型在特殊用户人群上预估有偏(要给特殊用户人群使用特殊的模型来消除偏差)

涨指标的方法

  1. 构造特殊内容池,用于特殊用户人群的召回
  2. 使用特殊排序策略,保护特殊用户
  3. 使用特殊的排序模型,消除模型预估的偏差

法1:构造特殊的内容池:特殊用户人群召回

为什么需要特殊内容池?
  • 新用户、低活用户的历史行为很少,个性化召回不准确(既然个性化不好,那么就保证内容质量好,用优质内容来弥补个性化的缺失)
  • 针对特定人群的特点构造特殊内容池,提升用户满意度(例如,对于喜欢留评论的中年女性,构造促评论内容池,满足这些用户的互动需求)
如何构造特殊内容池?

方法1:根据物品获得的交互次数、交互率选择优质物品

  • 圈定目标人群:只考虑特定人群提升他们的满意度,例如18~25岁一二线城市男性
  • 构造内容池:用该人群对物品的交互次数、交互率给物品打分,选出分数最高的物品进入内容池(选中物品的交互次数和交互率高,说明这些物品质量好,容易吸引用户)。这些交互指标是在圈定的人群中算出来的,说明这个人群对物品比较感兴趣
  • 内容池有弱个性化的效果
  • 内容池定期更新,加入新物品,排除交互率低和失去时效性的老物品
  • 该内容池只对该用户人群生效,即这部分用户人群的推荐结果,会有一部分来自这个内容池

方法2:做因果推断,判断物品对人群留存率的贡献,根据贡献值选优质物品

特殊内容池的召回

通常使用双塔模型从特殊内容池中做召回

  • 双塔模型是个性化的。个性化做的好不好,取决于用户历史行为是否丰富
  • 对于新用户,双塔模型的个性化做不准
  • 特殊内容池靠高质量内容、弱个性化做弥补

推荐系统有很多特殊内容池,每个内容池都需要双塔模型做召回。每多增加一个内容池,会增加多少额外的训练代价?不会增加训练模型的代价

  • 对于正常用户,不论有多少内容池,只训练一个双塔模型(在所有内容池上都使用相同的双塔模型,不会增加训练模型的代价)
  • 对于新用户,由于历史交互记录很少,需要单独训练双塔模型(用户塔会少一些特征)。但无论用在多少个内容池上,新用户只需要一个自己的双塔模型就够了

额外的推理代价?每多一个内容池,就多一份推理代价。增加的计算量跟内容池的大小正相关)

  • 双塔模型的向量召回需要用ANN索引(事先计算好的)
  • 内容池定期更新,然后要更新向量数据库的ANN索引
  • 线上做向量召回时,需要在向量数据库中做ANN检索
  • 无论是离线更新ANN索引,还是线上做ANN检索,都需要额外的算力
  • 特殊内容池都很小(比全量内容池小10~100倍),所以需要的额外算力不大

法2:特殊的排序策略:保护特殊用户

排除低质量物品

对于新用户、低活用户这样的特殊人群,业务上只关注留存,不在乎消费(指标:总曝光量、广告收入、电商收入)

  • 平台可以靠活跃的老用户来消费,至于新用户、低活用户,他的消费无关紧要,只要能留住这些用户就行

对于新用户、低活用户,少出广告甚至不出广告

新发布的物品(冷启动)不在新用户、低活用户上做探索,比如不推荐刚刚发布的新物品、排序时不对新物品做提权

  • 物品新发布时,推荐做的不准,会损害用户体验
  • 只在活跃的老用户上做探索,对新物品提权(boost)
  • 不在新用户、低活用户上做探索,避免伤害用户体验
差异化的融分公式

新用户、低活用户的点击、交互行为不同于正常用户

  • 低活用户的人均点击量很小,没有点击就不会有进一步的交互
  • 融分公式对预估点击率、交互率等指标做融合。低活用户的融分公式中,提高预估点击率的权重(相较于普通用户),促使低活用户点击物品

保留几个曝光坑位给预估点击率最高的几个物品

  • 例:精排从500个物品中选50个作为推荐结果,其中3个坑位给点击率最高的物品,剩余47个坑位由融分公式(对预估点击率和交互率取加权和)决定。这3个坑位存在的目的是吸引用户点击,用户点击了物品进去看看才更有可能留存
  • 甚至可以把点击率最高的物品排在第一,确保用户一定能看到,这确实能提升低活用户的留存

法3:特殊的排序模型:消除模型预估偏差

特殊用户人群的行为不同于普通用户。新用户、低活用户的点击率、交互率偏高或偏低

排序模型是用所有用户的行为训练出来的,被主流用户主导,对特殊用户做不准预估

  • 用全体用户数据训练出的模型,给新用户做的预估有严重偏差
  • 如果一个APP的用户90%是女性,用全体用户数据训练出的模型,对男性用户做的预估有偏差

问题:对于特殊用户,如何让排序模型预估做的准?

差异化的排序模型

方法1:大模型+小模型(并行)

  • 用全体用户行为训练大模型,大模型的预估p 拟合用户真实行为y,y=1表示用户实际有点击推荐的物品,y=0表示用户实际没点击
  • 用特殊用户的行为训练小模型,比方说大模型的全连接网络有6层,小模型的全连接网络只有2层,小模型的预估q 拟合大模型的残差y-p,残差y-p是大模型犯的错误(希望小模型能够纠正大模型犯的错误)
  • 对主流用户只用大模型做预估p,是比较准确的
  • 对特殊用户,结合大模型和小模型的预估p+q(小模型起到纠偏的作用)

方法2:融合多个experts,类似MMoE

  • 只用一个模型做预估,模型有多个experts,各输出一个向量
  • 对experts的输出做加权平均,得到一个向量
  • 根据用户特征计算experts的权重(跟MMoE的区别)
  • 以新用户为例,模型将用户的新老、活跃度等特征作为输入,输出权重,用于对experts做加权平均

MMoE计算experts权重:用一个小神经网络,把全部特征作为输入,输出是experts的权重

这里计算权重:只用用户特征,不用其他特征

比方说有两个experts,分别对应新用户和老用户。如果用户刚刚注册,那么新用户experts的权重为1,老用户experts的权重为0;如果用户介于新老之间,那么两个experts都有一定的权重。也就是说,无论用户是新/老/介于新老之间,用这种类似MMoE的模型都可以解决

方法3:大模型预估之后,用小模型做校准(串行)

  • 用大模型预估点击率、交互率。大模型是用全量数据训练出来的,对于大多数用户可以做出比较准确的预估,但对特殊用户的预估不准确
  • 将用户特征(是否为新用户、有多活跃)、大模型预估点击率和交互率作为小模型(例如GBDT树模型)的输入
  • 在特殊用户人群的数据上训练小模型,小模型的输出拟合用户真实行为
  • 大模型(在全体用户数据上训练)要预估点击率和交互率,小模型(只在特殊用户人群数据上训练)再预估一次点击率和交互率
错误的做法

每个用户人群使用一个独立的排序模型,推荐系统同时维护多个大模型

  • 系统有一个主模型,每个用户人群有自己的一个模型
  • 每天凌晨,用全体用户数据更新主模型,训练1 epoch
  • 基于训练好的主模型,在某特殊用户人群的数据上再训练1 epoch,作为该用户人群的模型

短期可以提升指标;维护代价大,长期有害

  • 起初,低活男性用户模型比主模型的AUC高0.2%
  • 主模型迭代几个版本后,AUC累计提升0.5%
  • 特殊人群模型太多,长期没有人维护和更新
  • 如果把低活男性用户模型下线,换成主模型,在低活男性用户上的AUC反倒提升0.3%

最好只有一个统一的模型,最多再加几个小模型,给主模型做纠偏和校准

总结:特殊对待特殊用户人群

召回:针对特殊用户人群,构造特殊的内容池,增加相应的召回通道

排序策略:

  • 排除低质量物品,保护新用户和低活用户
  • 特殊用户人群使用特殊的融分公式,而非让所有用户都用相同的融分公式

排序模型:

  • 结合大模型和小模型,小模型拟合大模型的残差;
  • 只用一个模型,类似MMoE,模型有多个experts,对多个experts做加权平均;
  • 大模型预估之后,用小模型如GBDT做校准

6、利用交互行为(关注、转发、评论)

用户的交互行为

交互行为:点赞、收藏、转发、关注、评论、完播...(意味着用户对物品感兴趣)。推荐系统如何利用交互行为?

  • 最简单的方法:将模型预估的交互率用于排序
    • 模型将交互行为当做预估的目标,输出基于0-1之间的数值,作为对各种交互率的预估
    • 融合公式将预估的点击率、交互率做融合,作为排序的依据

交互行为有没有其他用途?

关注

关注量对留存的价值

信息流APP都有这样一条规律:对于一位用户,他关注的作者越多,则平台对他的吸引力越强

用户留存率r(rentention rate)与 他关注的作者数量f(follow) 正相关(但不是线性关系)

  • 某个用户,如果他的f 比较小,那么他的留存率r 对f 会比较敏感
  • 如果某用户的f 较小,此时增加f 对留存率提升比较大,则推荐系统要促使该用户关注更多作者

如何利用关注关系提升用户留存?

方法1:用排序策略提升关注量

  • 对于用户u,若点击了物品i,如果他对物品特别感兴趣,就有可能关注物品的作者。假设模型预估 候选物品i 的关注率为pi
  • 设用户u 已经关注了 f个作者
  • 定义单调递减函数w(f)(具体啥样要自己调)。f比较小时,这一项起到了促关注的作用,w(f)会比较大;用户已经关注的作者f 越多,则w(f)越小
  • 在排序融分公式中添加 w(f) * pi,w(f)是权重,用于促关注
    • 如果 f小 且 pi大(即模型认为推荐物品i 有可能带来关注),则 w(f) * pi 给物品i 带来很大加分,物品i 的排序会很靠前
    • 反之,如果f很大,那么w(f)就会接近0,添加这一项乘积不起作用

方法2:构造促关注内容池和召回通道

  • 这个内容池中物品的关注率高,可以促关注
  • 促关注内容池并不会给所有用户都使用。如果用户关注的作者数f 较小,则对该用户使用该内容池
  • 召回时,这个内容池的召回配额可以固定,也可以与f 负相关(用户关注作者f 越少,就从这个内容池召回越多物品)
粉丝量对促发布的价值

UGC平台将作者发布量、发布率作为核心指标,希望作者多发布。作者发布的物品被平台推送给用户,会产生点赞、评论、关注等交互。交互(尤其是关注、评论)可以提升作者发布积极性

涨粉起到的激励效果和边际效益递减。作者的粉丝数越少,则每增加一个粉丝对发布积极性的提升越大。用排序策略帮助低粉新作者涨粉,从而激发他的创作积极性:

  • 某作者a 的粉丝数(被关注数)为fa
  • 作者a 发布的 物品i 可能被推荐给 用户u,模型预估关注率为Pui。Pui越高,意味着用户u 对物品i 的兴趣就越大
  • 定义单调递减函数w(fa) 作为权重,给预估关注率做加权。作者a 的粉丝fa 越多,则w(fa) 越小
  • 在排序融分公式中添加 w(fa) * Pui,给预估关注率做加权,帮助低粉作者涨粉
    • 作者粉丝数越小,每获得一个新的粉丝,对作者积极性都有很大提升;但如果作者粉丝数已经很大,获得一个新的粉丝不会给作者带来多少激励
    • 如果fa很小,且Pui较高,那么w(fa) * Pui就会很大,让物品i的排序很靠前(当用户看到物品i之后,有较大概率会关注作者)
隐式关注关系

召回通道U2A2I:user -> author -> item

  • 显式关注关系:用户u 关注了 作者a,将a 发布的物品推荐给 u(跟其他召回通道相比,关注关系召回的物品有更高的点击率和交互率)
  • 隐式关注关系:用户u 喜欢看 作者a 发布的物品,但是u没有关注a

隐式关注的作者数量远大于显式关注。挖掘隐式关注关系,构造U2A2I召回通道,可以提升推荐系统核心指标

转发(分享)

促转发(分享回流)

A平台用户将物品转发到B平台,可以为A吸引站外流量。推荐系统做促转发(也叫分享回流)可以提升DAU和消费指标

简单提升转发次数是否有效呢?(否)

  • 模型预估转发率为p(用户点击进入物品后有p的概率把物品转发到其他平台),融分公式中有一项w*p,让转发率大的物品更容易获得曝光机会
  • 增大权重w 可以促转发,吸引站外流量,但是会负面影响点击率和其他交互率,是行不通的
KOL建模

目标:在不损害点击和其他交互的前提下,尽量多吸引站外流量

什么样的用户的转发可以吸引大量站外流量?(其他平台的KOL)

  • 如果本平台的用户是其他平台的KOL(所谓大V,Key Opinion Leader),则他们的转发最容易带来流量
  • 用户u 是我们站内的KOL,但他不是其他平台的KOL,他的转发价值大吗?(不大)
  • 用户v 在我们站内没有粉丝,但他是其他平台的KOL,他的转发价值大吗?(大)

如何判断本平台的用户是不是其他平台的KOL?(该用户历史上的转发平均能带来多少站外流量)  

促转发的策略

识别出站外KOL之后,如何用于排序和召回?

方法1:排序融分公式中添加额外的一项 ku * Pui 

  • ku:KOL分数,平台根据u转发平均带来多少站外流量来确定ku的值。如果用户u 是站外KOL,则ku大
  • Pui:为用户u 推荐 物品i,模型预估的转发率
  • 作用:如果u 是站外KOL,则多给他曝光他可能转发的物品。如果用户u不是其他平台的KOL,那么权重ku接近0,不会干扰排序融分公式。即:促转发的策略只影响少数用户,对绝大数用户没有影响

方法2:构造促转发内容池和召回通道,仅对站外KOL生效

  • 召回配额可以固定,也可以与 KOL分数ku 挂钩

总之,只要识别出某个用户是站外KOL,推荐系统就会给他用特殊的排序策略和召回通道

评论

评论促发布

UGC平台将作者发布量、发布率作为核心指标,希望作者多发布,丰富平台内容池。关注/涨粉、评论等交互可以提升作者发布积极性

如果新发布物品尚未获得很多评论,则给预估评论率提权,让物品尽快获得评论。排序融分公式中添加额外一项 wi * pi,可以在评论数很少的时候促评论,而在评论数较多时这一项几乎等于0,不起作用

  • wi:权重,与物品i 已有的评论数量负相关
  • pi:为用户推荐物品i,模型预估的评论率
评论的其他价值

有的用户喜欢留评论,喜欢跟作者、评论区用户互动

  • 给这样的用户添加促评论的内容池,让他们有更多机会参与讨论
  • 有利于提升这些用户的留存

有的用户常留高质量评论(评论的点赞量高)

  • 高质量评论对作者、其他用户的留存有贡献(作者、其他用户觉得这样的评论有趣或有帮助)
  • 用排序和召回策略鼓励这些用户多留评论

总结:利用交互行为

关注:

  • 留存价值:让新用户关注更多作者,提升新用户留存
  • 促发布价值:帮助新作者获得更多粉丝,提升作者发布积极性
  • 利用隐式关注关系做召回

转发:

  • 促转发(也叫分享回流)
  • 判断哪些本平台用户是站外的KOL,利用他们转发的价值,吸引站外的流量

评论:

  • 促发布价值:促使新物品获得评论,提升作者发布积极性
  • 留存价值:给喜欢讨论的用户创造更多留评和讨论机会
  • 鼓励高质量评论的用户多留评论,对整个平台的留存都有好处

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[C++]C++工具之对异常情况的处理(throw、catch、try)以及用命名空间避免同名冲突

一、C 异常处理&#x1f60a; 1.1 定义 C 中的异常处理用于应对程序运行中的异常情况&#xff08;如除零、数组越界等&#xff09;&#xff0c;通过 try-catch 机制捕获和处理错误&#xff0c;防止程序崩溃。 异常是程序运行时意外发生的事件&#xff0c;可以通过抛出&#xf…

Dynamics 365 CRM- 后端

Dynamics 365 CRM 后端插件语法示例 public IPluginExecutionContext context null;//上下文 public IOrganizationServiceFactory serviceFactory null;//组织服务工厂对象 public IOrganizationService service null;//Org服务对象//创建执行上下文 context (IPluginExe…

C语言——实现并求出两个数的最大公约数

问题描述&#xff1a;求出两个数的最大公约数 //求两个数的最大公约数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<time.h>int main() {int a,b;printf("请您输入两个数 a 和 b\n");scanf…

采用qL-MPC技术进行小型固定翼无人机的路径跟随控制

来自论文"Predictive Path-Following Control for Fixed-Wing UAVs Using the qLMPC Framework in the Presence of Wind Disturbances" 控制架构 采用的是 ULTRA-Extra无人机&#xff0c;相关参数如下&#xff1a; 这里用于guidance law的无人机运动学模型为&#…

三维无人机航迹算法的目标函数如何确定

一、定义目标函数 在三维无人机航迹算法中,目标函数的确定通常基于具体的任务需求和飞行约束。以下是一个简单的例子,展示了如何为三维无人机航迹规划定义一个目标函数。 例子:最小化飞行时间和避障的三维无人机航迹规划 1.任务描述:无人机需要从起点飞到终点,同时避开一些…

《Java核心技术I》Swing用户界面组件

Swing和模型-视图-控制器设计模式 用户界面组件各个组成部分&#xff0c;如按钮&#xff0c;复选框&#xff0c;文本框或复杂的树控件&#xff0c;每个组件都有三个特征&#xff1a; 内容&#xff0c;如按钮的状态&#xff0c;文本域中的文本。外观&#xff0c;颜色&#xff0c…

【Office】Office实现shift+鼠标滚轮左右滑动

Office实现shift鼠标滚轮左右滑动 windows系统安装office之后发现&#xff0c;使用shift鼠标滚轮不能够实现左右滑动&#xff0c;我记得以前的office好像是可以的&#xff0c;然后在网上找了一下&#xff0c;找到了一个插件可以实现这个功能 OfficeScroll插件 下载地址&…

vlan和vlanif

文章目录 1、为什么会有vlan的存在2、vlan(虚拟局域网)1、vlan原理1. 为什么这样划分了2、如何实现不同交换机相同的vlan实现互访呢3、最优化的解决方法&#xff0c;vlan不同交换机4、vlan标签和vlan数据帧 5、vlan实现2、基于vlan的划分方式1、基于接口的vlan划分方式2、基于m…

Web项目图片视频加载缓慢/首屏加载白屏

Web项目图片视频加载缓慢/首屏加载白屏 文章目录 Web项目图片视频加载缓慢/首屏加载白屏一、原因二、 解决方案2.1、 图片和视频的优化2.1.1、压缩图片或视频2.1.2、 选择合适的图片或视频格式2.1.3、 使用图片或视频 CDN 加速2.1.4、Nginx中开启gzip 三、压缩工具推荐 一、原因…

【CAN模块】介绍一种检查CAN模块芯片好坏的方法(SN65HVD230)

文章目录 前言一、以SN65HVD230为例介绍端口特性二、代码实现总结 前言 CAN总线收发器&#xff0c;是CAN控制器和物理总线间的接口器件&#xff0c;通常工程师会按照底层协议对其控制&#xff0c;近日笔者仔细了解了CAN总线收发器的物理原理&#xff0c;找到了一种通过观察端口…

RTMP推流平台EasyDSS在无人机推流直播安防监控中的创新应用

无人机与低空经济的关系密切&#xff0c;并且正在快速发展。2024年中国低空经济行业市场规模达到5800亿元&#xff0c;其中低空制造产业占整个低空经济产业的88%。预计未来五年复合增速将达到16.03%。 随着科技的飞速发展&#xff0c;公共安防关乎每一个市民的生命财产安全。在…

[win10] win10系统的下载及在虚拟机中详细安装过程(附有下载文件)

前言 win10 下载&#xff1a;https://pan.quark.cn/s/eb40e8ca57fb 提取码&#xff1a;VTZq 失效&#xff08;可能被官方和谐&#xff09;可评论或私信我重发 下载压缩包后解压 &#xff01;&#xff01;安装路径不要有中文 解压下载的.zip文件&#xff0c;得到.iso文件 打开…

lightRAG 论文阅读笔记

论文原文 https://arxiv.org/pdf/2410.05779v1 这里我先说一下自己的感受&#xff0c;这篇论文整体看下来&#xff0c;没有太多惊艳的地方。核心就是利用知识图谱&#xff0c;通过模型对文档抽取实体和关系。 然后基于此来构建查询。核心问题还是在解决知识之间的连接问题。 论…

[代码随想录17]二叉树之最大二叉树、合并二叉树、二搜索树中的搜索、验证二叉搜索树。

前言 二叉树的题目还是要会一流程构造函数之类的。其中还有回溯的思想 题目链接 654. 最大二叉树 - 力扣&#xff08;LeetCode&#xff09; 一、最大二叉树 思路&#xff1a;还是考察构造二叉树&#xff0c;简单来说就是给你一个数组去构建一个二叉树&#xff0c;递归来解决就…

Docker概述与基础入门

1. 什么是Docker&#xff1f; Docker 是一个开源的平台&#xff0c;用于自动化应用程序的构建、部署和管理。它允许开发人员通过将应用程序及其依赖项打包成容器镜像&#xff0c;从而确保应用可以在任何环境中一致地运行。Docker 容器是轻量级的、可移植的、且具有高度隔离性的…

C# 探险之旅:第三十六节 - 类型class之密封类Sealed Classes

嗨&#xff0c;探险家们&#xff01;欢迎再次搭乘我们的C#魔法列车&#xff0c;今天我们要去一个神秘又有点“傲娇”的地方——密封类&#xff08;Sealed Classes&#xff09;领地。系好安全带&#xff0c;咱们要深入“密封”的奇妙世界啦&#xff01; 什么是密封类&#xff1…

QTreeView 与 QTreeWidget 例子

1. 先举个例子 1班有3个学生&#xff1a;张三、李四、王五 4个学生属性&#xff1a;语文 数学 英语 性别。 语文 数学 英语使用QDoubleSpinBox* 编辑&#xff0c;范围为0到100,1位小数 性别使用QComboBox* 编辑&#xff0c;选项为&#xff1a;男、女 实现效果&#xff1a; 2…

UE5 C++ Subsystem 和 多线程

一.Subsystem先做一个简单的介绍&#xff0c;其实可以去看大钊的文章有一篇专门讲这个的。 GamePlay框架基础上的一个增强功能&#xff0c;属于GamePlay架构的范围。Subsystems是一套可以定义自动实例化和释放的类的框架。这个框架允许你从5类里选择一个来定义子类(只能在C定义…

Linux 添加spi-nor flash支持

1. spi-nor flash简介 在嵌入式ARM开发过程中通常会使用到spi-nor flash&#xff0c;主要用于固化u-boot镜像以支持spi方式启动系统。目前常用的spi-nor flash有gd25wq128e、w25q128等flash芯片&#xff0c;下述以gd25wq128e为例进行讲解。 2.调试通常遇到的问题 无法识别到…

C# 探险之旅:第三十七节 - 类型class之Object:万物之源的奇妙冒险

嘿&#xff0c;勇敢的探险家们&#xff01;欢迎再次踏上C#的神秘之旅。今天&#xff0c;我们将深入探索一个极其强大又无处不在的“大佬”——Object 类型。想象一下&#xff0c;它就像是C#世界里的“超级英雄祖先”&#xff0c;几乎所有的类型都得叫它一声“老祖宗”。 Objec…