推荐系统学习(召回)
召回
介绍
召回是推荐系统链路中的第一个流程,目的是从几亿的item中选出几千item。进行召回的模型方法是多种多样,包括但不仅限于基于统计学的、基于规则的和基于神经网络的。
传统方法
协同过滤方法
定义:
通过分析用户或者事物之间的相似性(“协同”),来预测用户可能感兴趣的内容并将此内容推荐给用户。协同过滤有泛化能力弱、热门物品头部效应强的弱点
UserCF
原理:
如果用户 与用户 相似,而且 喜欢某物品 ,那么 很可能也喜欢该物品。根据该思想,UserCF的实现需要基于以下步骤:
- 基于转化流程中的动作得到用户对某物品的兴趣分数 $ like(user_j,item) $ ;
- 离线计算得到的用户之间的相似度 ;
- 线上预估用户对候选物品的兴趣:
用户相似度计算:
主流的方法是Jaccard距离,UserCF认为两个用户喜欢的物品重合度越高,两个用户越相似。所以计算物品相似度的计算方式如下:
- 设用户 喜欢的物品集合为 ,用户 喜欢的物品集合为 ;
- 定义这两个集合的交集 ,那么简单计算两个用户的相似度为 ;
- 该公式表示该用户的相似度计算时并没有区别对待冷门和热门物品,给予了它们同样的权重来影响相似度。由于热门物品只占所有物品的很小部分,而且很容易出现不同用户有相同的热门物品重合度,故越热门的物品越无法反映用户的独特的兴趣,为了降低热门物品的权重,用户的相似度计算公式更新为:其中 是喜欢物品 的用户数量,能够反映物品的热门程度。
除此之外,也可以用其它方法计算用户相似度:
-
首先,利用“用户评价”转化为共现矩阵,用户作为行坐标,商品作为列坐标,喜欢设置为1,不喜欢设置为-1(这样可以得到用户向量,类似生成了用户的embedding space上的映射);
-
通过向量计算一些距离:
-
欧式距离:
-
皮尔逊相关系数:
-
余弦相似度:
-
Tanimoto系数:
-
-
然后对Top n的用户进行加权平均:,其中为相似度,为相似度
缺点:
在工程和效果上都有一些缺陷,总结为以下两点。
-
计算和存储开销。UserCF需要计算和存储用户之间的相似度,在互联网企业,用户规模一般都比较庞大,导致计算和存储的开销非常大。
-
稀疏用户效果不佳。用户的历史行为一般都是比较稀疏的,比如电商场景,有些用户可能一个月就几次购买行为,对于这些用户计算相似度一般都不太准确,因此UserCF不太适合用户行为稀疏的场景。
ItemCF:
定义:
由于UserCF工程和效果上的缺陷,大多数互联网企业都选择ItemCF。ItemCF是基于物品相似度进行推荐的协同过滤算法。具体讲,通过计算Item之间的相似度,得到Item相似度矩阵,然后找到用户历史正反馈物品的相似物品进行排序和推荐。
原理:
ItemCF的基本思想在于:如果用户喜欢物品 ,而物品 与物品 相似,那么用户很可能喜欢物品 。根据该思想,ItemCF的实现需要基于以下步骤:
- 基于转化流程中的动作得到某用户对物品的兴趣分数 ;
- 离线计算得到的物品之间的相似度 ;
- 如下图所示,线上预估用户对候选物品的兴趣 ;
物品相似度计算:
一般来说,ItemCF的思想认为两个物品的受众重合度越高,两个物品越相似。所以计算物品相似度是基于与两个物品交互的用户群体重合度的:
- . 设喜欢物品 的用户群体为集合 ,喜欢物品 的用户群体为集合 ;
- 定义这两个集合的交集 ,那么简单计算两个物品的相似度为 ;
- 考虑到用户对于不同物品的喜欢程度对相似度的影响:,(余弦相似度的表达形式)
相似地,也可以使用共现矩阵的列向量,计算物品之间的相似度
与UserCF对比:
和UserCF相比,由于物品规模一般远远小于用户数,因此ItemCF的计算和存储开销都比UserCF小得多。除了技术实现上的区别,UserCF和ItemCF的应用场景也有所不同。总结为下面两点。
-
UserCF更适合新闻推荐场景。在新闻推荐场景中,新闻的兴趣点一般比较分散,比如虎嗅的新闻一般受众群体是从事IT的人,而UserCF可以快速找到都是从事IT的人群,然后把虎嗅的新闻推荐给自己。
-
ItemCF更适合电商或视频推荐场景。在电商和视频推荐场景中,都有一个共同点,用户的兴趣比较稳定。比如在电商场景,ItemCF可以推荐和兴趣点相似的商品,比如以前经常购买球鞋的人,可以推荐球衣球裤。
矩阵分解方法:
协同过滤具有简单、可解释性强的优点,在推荐系统早期广泛应用。但是协同过滤也有泛化能力弱、热门物品头部效应强的弱点。为了解决上述问题,后来矩阵分解技术被提出来。
SVD算法
SVD是Singlular Value Decomposition的简称,翻译过来就是奇异值分解。SVD的具体原理是假设矩阵 的大小为 ,则可以分解成3个矩阵的乘法 ,其中 是 $ m \times m$ 的正交矩阵, 是 $ n\times n$ 的正交矩阵, ! 是 的对角矩阵。只取对角矩阵 中的前 k 个较大元素,则SVD可以近似的表示为:
SVD应用在推荐系统中,用户矩阵表示为 ,物品矩阵表示为 。这样就可以计算用户和物品的相似度,但是在工程上会有问题,奇异值分解的计算复杂度达到了 ,对于物品上百万的互联网行业是无法接受的。另外,SVD对于稀疏的共现矩阵也不友好,需要人为填充缺失值,而互联行业用户行为大多是比较稀疏的。
针对传统SVD计算复杂度以及用户稀疏行为效果不好的问题,后来提出了改进的版本。用户 u 的向量表示为 ,物品 i 的的向量表示为 ,则用户对物品的评分表示为两个向量的内积 ,真实的评分假设为 ,目标函数表示为:
然后可以用梯度下降求解上面的目标函数。
总结:
传统召回算法有其简单、可解释性强的特点,但是也有自身的局限性。协同过滤和矩阵分解都没有加入用户、物品和上下文相关的特征,也没有考虑用户行为之间的相关性。随着embedding技术的发展,召回技术开始朝着模型化embedding的方向演化。
Embedding 方法
基于embedding的召回框架,主要分为i2i召回和u2i召回。
i2i召回是指我们可以得到item embedding,但是模型没有直接得到user embedding。离线根据用户历史行为训练召回模型,输出item embedding,存储到数据库中,线上用户请求,根据用户历史行为,从数据库从查找对应的embedding,然后检索相似度最高的n个item,最后将Top n召回结果返回给后面的排序模块。

u2i是指模型同时得到了user embedding和item embedding。
在u2i召回框架中,有时考虑到用户规模太大,不方便存储,可以在线上召回的时候,直接通过模型请求获取user embedding,然后再检索相似item。图10是u2i的召回框架,和图9的i2i相比,主要区别在于u2i可以直接基于user embedding进行检索。

基于内容语义的i2i召回
词向量方法
经典的词向量方法如下,不详细展开了,论文都十分经典。
-
Word2vec
Word2vec是Google2013年在论文Efficient Estimation of Word Representations in Vector Space中提出的语言模型,用于生成词的Embedding。Word2vec有两种模型结构,CBOW是给定周围词预测中心词,而Skip-gram是给定中心词预测周围词。比如句子“we soon believe what he desire”,如果中心词是"believe",窗口大小是2,则CBOW是用"we",“soon”,“what”,“he"来预测"believe”;而Skip-gram是用中心词"believe"来预测"we",“soon”,“what”,“he”。
-
FastText
FastText的输入是整个文本的词序列,同时在表示单个词Embeddiing的时候,引入了单个词的n-gram特征,最后词的Embedding就可以用n-gram向量的均值表示。
-
Bert
Bert是动态词向量方法。假设有两个句子"I have an apple", “I have an apple phone”,把这两个句子分别作为Bert的input,由于Bert的每个词会与上下文做复杂的Attention计算,那么两个句子中"apple"对应的Embedding是不一样的,即Bert是动态词向量方法。
Item2vec:
相比Word2vec利用“词序列”生成词的Embedding,Item2vec利用“新闻点击序列”生成新闻的Embedding。假设Item2vec中一个长度为 K 的用户历史点击序列为 ,则Item2vec的优化目标为:
基于Graph Embedding的i2i召回:
列模型有自身的局限性,在互联网场景下,用户的行为数据往往呈现的是图结构。Item2vec等序列模型更多的是捕捉用户行为序列之间的相关性,而图结构中的二度邻居关系没有考虑。。在面对图结构时,传统的序列Embedding方法表达能力有限,由此Graph Embedding成了新的研究方向,在召回中得以广泛应用。
Graph Embedding是一种对图结构中的节点进行Embedding化的方法,最终生成的节点Embedding一般包含图的全局结构信息以及邻居节点的局部相似度信息。常用的Graph Embedding方法:
DeepWalk
DeepWalk是近年来第一个有影响力的大规模Graph Embedding方法,它的本质是在图结构上进行随机游走(它的本质是从一个节点出发,随机选择它的一个邻接点,再从这个邻接点出发到下一个节点,重复这个步骤然后记录下所经过的所有节点),生成Item序列,然后将这些Item序列作为训练样本输入Skip-Gram进行训练,得到Item的Embedding。
EGES
前面的DeepWalk有一个问题,就是单纯使用行为序列构建图结构,虽然可以生成Item的Embedding,但是如果遇到新的Item,或者出现次数少的Item,则Embedding效果会很差,这就是推荐系统常见的冷启动问题。为了使冷启动的Item也有效果不错的Embedding,2018年,阿里巴巴公布了在淘宝应用的Graph Embedding方法EGES,其主要思想就是在DeepWalk生成Embedding过程中引入Item的补充信息。
在阿里巴巴的淘宝场景,Item就是衣服、电器这些物品,可以引入的补充信息包含物品的类别、对应的商店、风格、颜色等。有了物品的多个补充信息,那么问题是如何融合物品的多个Embedding,使之形成物品最后的Embedding。最简单的方法是在Skip-gram网络中加入Avg pooling,比如对于Item v ,假设包含 n 个补充信息,加上自身的Item id,一共有 n+1 个特征,对应的Embedding表示为 ,使用Avg pooling,再加权平均,最后Item v 的Embedding表示为:
(这篇文章感觉挺好的,可以看一下,他给了DeepWalk中的图变为了有权图,然后引入side information,再使用Avg pooling最后进行加权平均)

Node2vec
该模型通过调整random walk权重的方法使得节点的Embedding向量更倾向于体现网络的同质性或结构性。
同质性指的是距离相近的节点的Embedding向量应接近,如图6所示,与节点 u 相连的节点 s1,s2,s3,s4 的Embedding向量应相似。为了使Embedding向量能够表达网络的同质性,需要让随机游走倾向于DFS,因为DFS更有可能通过多次跳转,到达远方的节点上,使游走序列集中在一个较大的集合内部,这就使得在一个集合内部的节点具有更高的相似性,从而表达图的同质性。
结构性指的是结构相似的节点的Embedding向量应相似。为了表达结构性,需要随机游走更倾向于BFS,因为BFS会更多的在当前节点的邻域中游走,相当于对当前节点的网络结构进行扫描,从而使得Embedding向量能够刻画当前节点邻域的结构信息。
相较于DeepWalk,Node2vec通过设计biased-random walk策略,能对图中节点的结构相似和同质性相似进行权衡,使得模型生成的Embedding更加灵活,实用性更强。Node2vec应用于新闻推荐场景,同质性相同的新闻很可能是同类别的新闻,比如都是娱乐类新闻,而结构性相同的新闻很可能是一些热点新闻。
GCN
近年来,研究人员尝试将深度图模型和神经网络相结合,直接在图中提取拓扑图的空间特征,这一类方法统称为GNN(Graph Neural Networks)。GCN是一种能够直接作用于图并且利用其结构信息的卷积神经网络。
GraphSAGE
GraphSAGE(Graph SAmple and aggreGatE)是基于空间域的方法,其思想与基于谱域的方法相反,是直接在图上定义卷积操作,对空间上相邻的节点进行运算。GraphSAGE学习当前节点的Embedding是通过其邻居节点的特征聚合得到,这样就可以通过邻居节点很方便的表示一个新节点。
双塔模型
双塔模型广泛应用在各种领域,就是NLP领域的 query 和 document,推荐领域的 user 和 item,多模态检索领域的CLIP等,都可以用双塔表示,分别把两个领域的特征编码成一个向量,然后向量相似度进行召回。
通过大量实践证明,适用于召回的双塔模型是先分别通过神经网络生成表征,再计算两个表征之间的相似度(兴趣分数),称之为后期融合,;而在精排和粗排中,则需要使用前期融合,也就是先融合物品和用户的特征向量,再通过神经网络输出兴趣分数。
其它公司都有各自提出的双塔模型,在此仅仅介绍两种。
DSSM:
DSSM(Deep Structured Semantic Models ,深度语义模型)是2013年微软发表的一篇论文,本用于语义匹配,后被移植到推荐系统等各个场景,成为经典的双塔模型。广告推荐领域中使用的 DSSM 双塔模型是从广告维度为广告主推荐一定数量的人群,从数量上看是从数亿级别人群中找出百万级人群用于投放广告,所以是召回模型。
原理:
DSSM 从下往上可以分为三层结构:输入层、表示层、匹配层,先将用户和物品各自输入输入层,然后二者通过各自的表示层,最后在匹配层进行匹配。
输入层
模型训练分成两座不同的“塔”分别进行,其实也就是两个不同的神经网络。其中一座塔是用于生成 user embedding。输入用户特征训练数据,用户特征包括用户稠密特征和用户稀疏特征,其中用户稠密特征进行 one-hot 编码操作,用户稀疏特征进行 embedding 降维到低维空间(64 或者 32 维),然后进行特征拼接操作。广告侧和用户侧类似。
最复杂的就是这块的特征工作。
表示层

**用 tanh 作为隐层和输出层的激活函数,**最终输出一个 128 维的低纬语义向量。
匹配层:
Query 和 Doc 的语义相似性可以用这两个语义向量(128 维) 的 cosine 距离(即余弦相似度) 来表示: 通过 softmax 函数可以把 Query 与正样本 Doc 的语义相似性转化为一个后验概率。
在推荐领域的应用:
DSSM双塔结构,两侧分别输入user特征和ad特征,经过DNN变换后分别产出user向量和ad向量。DSSM最大的特点是user侧和ad侧是独立的两个子网络,可以离线产出user embedding和ad embedding,召回时只需要计算二者的相似度。
SENet双塔结构
SENet模块由自动驾驶公司Momenta在2017年提出,在当时,是一种应用于图像处理的新型网络结构。它基于CNN结构,通过对特征通道间的相关性进行建模,对重要特征进行强化来提升模型准确率,本质上就是针对CNN中间层卷积核特征的Attention操作。
用户侧塔和Item侧塔在特征Embedding层上,各自加入一个SENet模块,两个SENet各自对User侧和Item侧的特征,进行动态权重调整:
- 动态抑制User或者Item内的部分低频无效特征,甚至清除掉(如果权重为0的话)不重要甚至是噪音的特征
- 突显那些对高层User Embedding和Item Embedding的特征交叉起重要作用的特征
通过SENet更有利于表达两侧的特征交互,避免单侧无效特征经过DNN双塔非线性融合时带来的噪声,同时又带有非线性的作用。
总结:
但是双塔模型也存在严重的头部效应,不能很好地处理长尾数据,只对高点击物品的表征学的好。所以之后也引入了自监督学习的思想,使用多种不同的特征变换(Mask、Dropout、互补等),更好地处理长尾数据、更充分地学习用户和物品的表征信息。
其它知识
特征变换方法:
在召回中也常用到深度学习中的多种特征变换方法,如下表所示:
特征变换 | 基本思想 | 示例 |
---|---|---|
Random Mask | 随机挑选一些离散特征,把它们遮住。 | 处理前物品的特征集合u={ID、类目};处理后u={default}。 |
Dropout | 随机丢弃特征中50%的值(仅对多值离散特征生效)。 | 处理前某特征的向量a=[1, 2];处理后a=[1, 0] 。 |
互补特征 | 将若干个特征随机分为两组,两组都是物品表征且特征互不重复。因为表示的都是同一物品,所以鼓励这两个特征向量相似。 | 某物品具有ID、类目、关键词、城市4个特征,随机分成 {ID,default,关键词,default} 和 {default,类目,default,城市} 这两种物品表征。 |
Mask一组关联的特征 | 1. 使用互信息(MI,mutual information)衡量关联度,离线计算特征两两之间的关联矩阵,根据关联矩阵进行特征的随机Mask。 2. 它比以上三种方法效果都要好,但是比较复杂,实现难度大且不容易维护。 | 1. 设一共有k种特征,离线计算特征两两之间的MI,得到k×k的矩阵; 2. 随机选一个特征作为seed,找到该seed最相关的k/2种特征; 3. Mask该seed及其最相关的k/2种特征,保留其余k/2种特征。 |
其它召回通道:
召回通道 | 原理 | 索引 | 召回流程 |
---|---|---|---|
GeoHash召回 | 用户可能对附近发生的事感兴趣,根据用户定位的GeoHash取回该地点最新的若干篇笔记。 | GeoHash→优质笔记列表(按时间倒排) | 无个性化召回(所以选择推荐优质笔记) |
同城召回 | 用户可能对同城发生的事情感兴趣。 | 城市→优质笔记列表(按时间倒排) | 无个性化召回 |
作者召回 | 用户对关注的作者发布的笔记感兴趣。 | 用户→关注的作者 作者→发布的笔记(按时间倒排) | 用户→关注的作者→最新的笔记 |
有交互的作者召回 | 如果用户对某笔记感兴趣(点赞、收藏、转发),那么用户可能对该作者的其他笔记也感兴趣。 | 1. 用户→有交互的作者 2. 作者→发布的笔记(按时间倒排) | 用户→有交互的作者→最新的笔记 |
相似作者召回 | 如果用户喜欢(关注、交互)某作者,那么用户喜欢相似的作者(类似ItemCF)。 | 1. 用户→感兴趣的作者 2. 作者→相似作者 3. 作者→发布的笔记(按时间倒排) | 用户→感兴趣的作者→相似作者→最新的笔记 |
除此之外,还有一种被称为缓存召回的召回方法。在精排到重排的过程中,从几百篇笔记中只筛选了几十篇作为推荐结果,大部分精排结果并没有被曝光。因此,缓存召回希望复用前 n 次推荐精排但没有曝光的结果,将它们缓存起来,作为一条召回通道。
曝光过滤
在小红书和抖音的推荐系统中,为了避免重复推荐物品,如果用户看过某个物品,则系统不再把该物品曝光给该用户,这个思想称之为曝光过滤。一般来说,曝光过滤是在召回层实现的,它的基本流程如下:
-
每个用户,记录已经曝光给他的物品。(小红书只召回1个月以内的笔记,因此只需要记录每个用户最近1个月的曝光历史)
-
对于每个召回的物品,判断它是否已经给该用户曝光过,排除掉曾经曝光过的物品。
Bloom Filter
如果一位用户看过 n 个物品,本次召回 r 个物品。如果暴力对比需要的时间复杂度为 o(nr) ,计算过于巨大。所以在实践中使用 Bloom Filter 来判断一个物品ID是否在已经曝光的物品集合中:
- 如果判断为no,那么该物品一定不在集合中;
- 如果判断为yes,那么该物品很可能在集合中(可能误伤,错误判断未曝光物品为已曝光,将其过滤掉)。
如下所示是Bloom Filter 的实现原理:
- Bloom Filter 把物品集合表征为一个 m 维的二进制向量;
- 每个用户有一个曝光物品的集合,表征为一个向量,需要 m bit的存储空间;
- Bloom filter 有 k 个哈希函数,每个哈希函数把物品ID映射成介于 0 和 m−1 之间的整数;
- 已曝光物品ID通过哈希函数映射进了二进制向量中对应的位置,如果该位置为0则调整为1,若为1无需调整;
- 对于召回的物品ID,通过哈希函数映射,若对应位置全为1,则说明该物品已曝光,否则未曝光。
总结:
召回的目的在于快速从几亿的物品中初步筛选出几千物品。无论是基于统计学、基于规则还是基于神经网络的召回方法都是行之有效的手段。协同过滤就是一种基础和经典的模型思想。
ItemCF和UserCF这两种协同过滤的介绍,它们使用物品和用户的ID计算相似度,结合用户对物品的交互信息,来计算用户对物品的兴趣分数进行排序作为召回结果。但在工业实践中初始物品数量都以亿为单位,协同过滤使用的稀疏向量过于庞大和稀疏,计算复杂度过高。
因此,引入了使用embedding处理离散特征(比如物品类别)的矩阵补全模型。但是矩阵补全模型仅使用ID做embedding、负样本选取错误而且求内积做训练的方式(回归任务)不对,在实际应用中效果不佳。
针对这些问题,前人在矩阵补全的基础上改进得到了双塔模型。双塔模型使用用户和物品的多维特征属性进行embedding后,通过特征变化再输入神经网络(后期融合)通过计算得到余弦相似度;在负样本选取上,考虑到对简单负样本和困难负样本的混合选取;并将训练任务转化为分类问题,根据不同的训练方式推理了对应的交叉熵损失或合页损失。
但是双塔模型也存在严重的头部效应,不能很好地处理长尾数据,只对高点击物品的表征学的好。所以引入自监督学习的思想,使用多种不同的特征变换(Mask、Dropout、互补等),更好地处理长尾数据、更充分地学习用户和物品的表征信息。
参考:
[1] 【总结】推荐系统——召回篇【1】 [2] 推荐系统|个人学习笔记 - 知乎
[3] DSSM:深度语义匹配模型(及其变体CLSM、LSTM-DSSM)-腾讯云开发者社区-腾讯云
[4] SENet双塔模型在推荐领域召回粗排的应用及其它
以及所有架构的原始论文