推荐实践之召回算法梳理与优化思考

回复 星标
更多

推荐实践之召回算法梳理与优化思考

本文搬运于个人公众号:推荐实践之召回算法梳理与优化思考

在推荐系统之经典排序模型一文中,我们谈到工业推荐系统一般包含四个环节,分别是召回、粗排、精排和重排。召回阶段根据用户的兴趣和历史行为,从海量的物品库里,快速找回一小部分用户潜在感兴趣的物品。可以看出,召回起到了一个漏斗的作用,从海量的内容池当中筛选出部分内容,这部分内容一般会满足多个维度的要求,比如多样性、时效性、质量、热点、文章冷启动、用户兴趣等等,所以召回通常有很多路,比如高热召回、高质召回、新文章保量、地域召回、个性化召回等等。针对不同类型的用户,召回可能也不同,比如新用户和老用户,一线城市用户和非一线城市用户,高质量用户和易流失用户等等,使用的召回策略也会有差异。从功能性角度来分的话,召回可以分为模型类召回、相关场景类召回、内容和属性类召回、探索性召回、产品运营类召回等等,本文主要从模型角度介绍针对一般用户的常用个性化召回算法。

536716

上图列出了理论和实践当中经典和常见的召回算法,下面我们主要围绕图中模型类召回算法进行介绍,当然不可能每一个算法都面面俱到的介绍,只希望能起一个提纲挈领的作用。

首先我们要明白协同过滤是一种指导思想,说白了就是物以类聚人以群分,U2I、I2I是这种指导思想下面的不同实现思路。参考 如何理解推荐系统中的i2i,u2i,u2u2i,u2i2i和u2tag2i召回[4] 问题下面的高赞回答:

  • i2i:计算item-item相似度,用于相似推荐、相关推荐、关联推荐;
  • u2i:基于矩阵分解、协同过滤的结果,直接给u推荐i;
  • u2u2i:基于用户的协同过滤,先找相似用户,再推荐相似用户喜欢的item;
  • u2i2i:基于物品的协同过滤,先统计用户喜爱的物品,再推荐他喜欢的物品;
  • u2tag2i:基于标签的泛化推荐,先统计用户偏好的tag向量,然后匹配所有的Item,这个tag一般是item的标签、分类、关键词等tag;

UserCF是一种u2u2i方法,ItemCF是一种u2i2i方法,两者分别是从传统的统计学习方法角度来计算用户和用户、物品和物品的相似性,而后面的向量化方法则引入了深度学习方法来表征用户和Item并计算相似性。

Statistic Model-based方法中,矩阵分解是背后的核心。而矩阵分解(Matrix Factorization, MF)的核心假设是用隐语义(隐变量)来表达用户和物品,这里其实就已经包含了向量化(Embedding)的思想。用户和物品的行为(评分/点击…)矩阵 m×n 可以分解成 m×k 和 k×n 的两个小矩阵,这里多出来的 k 维向量,就是隐因子向量(Latent Factor Vector),这个隐因子向量,你可以看成是用户和物品的自有属性。 通过离线计算出用户和物品的隐因子向量并通过Faiss等工具进行存储和在线检索,可以实现近似实时的召回和排序。怎么计算得到用户和物品的隐因子向量,就衍生出了上图中各种具体的算法,比如ALS通过交替优化均方误差来迭代得到目标分解矩阵,SVD++引入了隐式反馈和用户属性的信息,WRMF对训练样本加入权重来表征用户对物品的偏好程度并对权重进行正则化,想深入了解矩阵分解算法的同学可以参考 基于矩阵分解的推荐算法[5] 一文。

Graph-based协同方法将用户和物品二阶交互关系扩展到了高阶交互关系,具体的,将用户和物品表示成两部图关系,有关系的用户和物品之间有路径连接。下面简单介绍一下几种简单的图算法,想深入了解的可以参考 推荐召回策略[6] 一文。

536716

PersonalRank算法从待推荐用户u对应的节点开始游走,每到一个节点都以1−d的概率停止游走并从u重新开始,或者以d的概率继续游走,从当前节点指向的节点中按照均匀分布随机选择一个节点往下游走。这样经过很多轮游走之后,每个顶点被访问到的概率也会收敛趋于稳定,这个时候我们就可以用概率来进行排名了。

Simrank的基本思想是,如果两个实体相似,那么跟它们相关的实体应该也相似。可以通过多种优化方法来迭代得到用户和用户、物品和物品的相似度矩阵,和MF的优化思想类似。

Swing算法主要用户计算item-item之间的相似性。如果(u1,u2,i1) 表示用户 u1和 u2都购买过物品 i1 ,则三者构成一个Swing(三角形缺一条边), 用户和物品的二部图中会存在很多这种Swing。这实际上是3阶交互关系, 这种方法的一个直觉来源于,如果多个user在点击了 i1的同时,都只共同点了某一个其他的i2,那么 i1 和 i2 一定是强关联的,这种未知的强关联关系相当于是通过用户来传递的。另一方面,如果两个user pair对之间构成的swing结构越多,则每个结构越弱,在这个pair对上每个节点分到的权重越低。

向量化召回就是我们常说的embedding技术在召回阶段的应用。Embedding是一种对抽象物品的数字化表征,比如足够详细的描述可以确定一个人,同样一个身份证号码也可以表示这个人,可以将身份证号码当作某个人的embedding,当然算法中的embedding没有明确的意义,只是一组稠密向量,来表示一个不方便数字化的内容,这个embedding可以通过某种数学方法学习得到。比如通过神经网络的端到端训练得到输入特征的embedding,或者取神经网络的某一层输出做embedding,这是当前比较常见的两种embedding训练方式。

在推荐系统中,将文章或图片向量化是最基础的工作。比如文章一般从词向量的获取开始,基于词向量的静态表征方法有word2vec、fastText、glove 等,基于词向量的动态表征方法有elmo、GPT1/2/3、bert等。动态词向量相较于静态词向量,更加充分利用了上下文信息,所以可以解决一词多义的问题。所谓动态就是每次都要过模型计算,所谓静态就是用已经训练好的权重,其实bert的embedding层也可以作为静态的词向量。

word2vec将Word映射到固定长度向量,基于Word序列中相邻Word间存在一定的语义关系假设,指定窗口中可以通过中心词预测周围的词(Skip-gram),或通过周围的词预测中心词(CBOW),训练方法有hierarchical softmax、负采样等。Word2vec之后掀起了一切皆可Embedding的浪潮,凡是能组成sequence的东西都可以利用word2vec来学习其Embedding表示,比如用户的商品点击序列、用户视频观看序列等。

BERT是一种基于Transformer Encoder来构建的一种模型,它整个的架构其实是基于DAE(Denoising Autoencoder)的,这部分在BERT文章里叫作Masked Lanauge Model(MLM)。MLM并不是严格意义上的语言模型,因为整个训练过程并不是利用语言模型方式来训练的。BERT随机把一些单词通过MASK标签来代替,并接着去预测被MASK的这个单词,过程其实就是DAE的过程。想详细了解各种Lanauge Model的同学可以参考 Google BERT模型原理详解[15] 和 万字长文解析词向量[16]。

向量化召回当中的U2I、I2I和U2U2I类方法,都是以词向量为基础,通过faiss等进行相似文章的检索。U2I中, Topic2Vec 是训练文章主题的向量,Keyword2Vec 是训练文章主关键词的向量,Item2Vec 是训练文章 ID(did)所对应的向量, Title2Vec 是用 LSTM 训练得到的文章标题向量,Doc2Vec 是用 bert 计算出的文章正文(或者摘要)的向量。U2I中,User2Vec是拿用户的Tag/关键词/Topic 向量和文章的对应向量求相似度,CrossTag 相当于多个 User2Vec, 需要将用户按类别进行统计,每个类取 K 个 Tag, 共获取 m 组 tag,然后各组分别做 User2Vec,最后汇总得到用户的推荐列表。当涉及多个向量时,可以通过等权重相加、加权相加、取平均、取最大等方法进行融合。U2U2I当中主要是分群推荐方法,比如群画像召回是先把用户分群,然后把同一个群里的用户画像全部抽取出来,然后融合为一个群画像,相当于把这一群人合成了一个人,然后对于群画像,再使用和单个用户画像类似的个性化召回。想详细了解各个具体算法同学可以参考 推荐系统 embedding 技术实践总结[7] 一文。

DeepMatch方法中,DSSM最初是为了计算文本语义相似度,比如搜索中的Query和Title。在推荐场景,DSSM可以用来做CTR预估问题,以有监督的方式应用于粗排和召回,一般结构如下图所示。可以参考推荐粗排(召回)工程实践之双塔DNN模型一文 详细了解DSSM的工程化实现方法。DSSM可以采用多塔结构训练多种类型召回,每个塔使用不同的特征就可以得到不同的召回,比如使用长短期用户兴趣特征分别训练长短期兴趣召回模型。

536716

YoutubeNet召回侧模型结构如下,这里值得注意的是输入端的Item vector是离线通过W2V等向量化方法训练好的,最后一层输出为线上serving时User的Vector,而输出层连接softmax函数之间的权重参数为线上Serving时所有Item的Vectors。这里面比较重要的可能是输入特征的选择、负采样Item的采样方法及处理方法了,比如Youtube自家的特征处理细节就有很多,包括加入example age特征、特征的非线性转换等等,具体工程实现疑点难点可以参考 YouTube深度学习推荐系统的十大工程问题[11] 一文。负样本采样方法很重要,有的业务场景比如搜索,同一刷里面曝光未点击样本与点击样本差别其实并不大,全用这样的样本来当作负例学习显然是不合适的,可以参考一下 负样本为王:评Facebook的向量化召回算法 [10] 一文详细了解负样本采样当中的一些工程实现问题。

536716

FM算法在逻辑斯特回归算法(LR)的基础上引入了特征间的二阶交叉,然后借鉴上文矩阵分解(MF)的思想,将交叉特征参数矩阵分解并转换为求每个特征的隐向量,这样一来增加了模型的泛化能力,因为即使训练数据当中并没有出现两个特征的交叉,在预估的时候仍然可以通过单独训练而来的单特征隐向量计算该交叉特征的权重,二来提升了模型的训练效率,将原始num_feature * num_feature 时间复杂度的问题降到了k * num_feature的时间复杂度,k指隐向量的长度,远小于工业界大规模离散特征动不动就上千万量级的num_feature。想详细了解FM算法原理的同学可以参考 全能FM模型[4] 一文。

536716

FFM算法在FM算法的基础上引入了域(Field)的概念,比如说所有的用户特征看成一个域,所有的文章特征看成另一个域。在FM算法中,不同域内特征交叉时用的是同一个vector,但是如果每一个特征对不同的域学习不同的vector,可以一定程度上减轻梯度耦合问题,特征表达能力会更强,这就是FFM主要解决的问题。FFM的问题是参数量相对于原始的FM增加了一个量级,而且不好简化,召回侧特征相对排序侧没有那么复杂,更新频率可以不用那么实时,所以也有FFM一定的用武之地。想详细了解FFM算法原理及应用的同学可以参考 FFM及DeepFFM模型[12] 一文。

536716

DeepWalk的主要思想是在由物品组成的图结构上进行随机游走,产生大量物品序列,然后将这些物品序列作为训练样本输入word2vec进行训练,得到物品的embedding。下图展现了DeepWalk的训练过程。

536716

Node2Vec在DeepWalk的基础上通过调整随机游走权重的方法使graph embedding的结果在网络的同质性(homophily)和结构性(structural equivalence)中进行权衡权衡。网络的“同质性”指的是距离相近节点的embedding应该尽量近似,“结构性”指的是结构上相似的节点的embedding应该尽量接近。EGES(Enhanced Graph Embedding with Side Information)的基本思想是在DeepWalk生成的graph embedding基础上引入补充信息。想详细了解 DeepWalk、Node2Vec和EGES算法的同学可以参考 Graph Embedding 方法一文[13] 一文。

GCN是引入卷积的Graph Network, GAT是引入attention机制的图网络,GraphSage旨在提升GCN扩展性和改进训练方法缺陷,包括其它的几种方法,都是在DeepWalk之后不断针对新场景引入新思想,关于图神经网络,可以参考 清华大学刘知远老师团队出版的图神经网络书籍《Introduction to Graph Neural Networks》和 图神经网络入门系列[14]等。

Mind结构如下所示,其与传统方法用单一embedding来表达用户兴趣不同,使用了类似胶囊网络的方法将用户行为聚类,最终得出用户的多个兴趣embedding,能更好的捕捉用户的多样兴趣,提升召回的丰富度和准确度。想详细了解想法细节的同学可以参考 阿里MIND网络[17] 一文。

536716

TDM算法是阿里提出的一种结合树结构及深度学习的召回模型,通过利用从粗到精的方式从上到下检索兴趣树的节点为用户生成推荐候选集,该方法检索时间正比于Item数量的对数,是一类高效的检索算法。兴趣树结构和深度学习模型进行交替联合训练,先构造初始化树,再训练深度学习模型直到收敛,从而获得所有节点(即商品)的嵌入表示,基于该嵌入表示又可以获得新的兴趣树,这时又可以开始训练新的深度神经网络模型了,这个过程不断迭代直至收敛。想详细了解TDM原理的同学可以参考 深度树匹配模型[18] 一文。

召回算法效果评估

从我有限的工作经验来看,召回算法很多时候不好进行离线评估,一般都是简单粗暴直接线上看效果,当然线下也会简单确定模型与预期没有太大出入,比如Word2Vec这类召回算法,就会通过离线肉眼验证一下召回的词向量是不是靠谱,DSSM在特征充分的情况下,甚至会跟精排模型的auc进行比较。缺乏离线评估工具,算法的迭代工作当然就会慢很多,我觉得通用的召回的离线评估工具有必要完善也有条件完善,比如我们的特征系统当中一般都会维护用户的行为序列,如用户阅读过的100个文章id,我们在评估召回的效果的时候,就可以通过比较从内容池当中召回的文章和历史阅读文章的相似性,这个相似性可以通过别的可信度更高的方法来评估,比如简单的统计交集的文章数量、关键词数量等等。当然,这是我个人不成熟的想法,同学们如果有召回评估经验或者其它想法的话,可以文末留言,分享一下召回算法的评估方法。

召回算法上线流程

上线一个策略(包括召回、排序、重排)一般都会经过提出想法、可行性分析、开发测试、离线评估、分桶测试、全量上线几个流程,中间的开发测试评估可能会因为各种原因会不断的反复,直到达到预期效果而结束。算法工程师的日常就是在干这些事情,优秀的算法工程师一般会对每一个环节都会有自己的一套方法论,比如从各种离线指标当中大致就能知道线上效果怎么样,比如对哪些点的优化有效哪些无效会有一个大差不差的判断,比如会对一个策略的优化知根知底尽善尽美,不会做了个baseline就换个方向,同时优秀的算法工程师总是对业务敏感的,因为我们最终要解决的就是业务上存在的问题。

召回优化的一些不成熟的建议

  • 1) 思考你做过的算法是否还有很大的优化空间
  • 2) 思考业务上的痛点是什么
  • 3) 关注关注其它领域的算法发展,CV、NLP、广告、精排,可以相互借鉴的东西很多
  • 4) 一段时间回顾回顾自己之前的工作
  • 5) 梳理一下其它同事的工作,你会发现去掉当初有效果的召回现在也有收益
  • 6) 注意与精排协同,至少你个人可以关注
  • 7) 方便的离线评估工具会让你事半功倍

几个小问题

  • 1) 召回结果排序模型没有用?如何协同优化召回和排序?
  • 2) 召回曝光高但是点击并不是很高,是否应该将后验点击高的召回条数增大?如何调整各路召回数量?
  • 3) 有尝试过强化学习来优化各路召回条数吗?是否值得尝试?

水平有限,欢迎各位拍砖,感兴趣的同学可以关注下个人公众号,不定时更新个人对工作和生活的总结和思考,知乎上的文章都是从上面搬运的:推荐实践之召回算法梳理与优化思考

[1] 推荐排序模型:推荐精排模型之经典排序模型

[2] 召回算法实践总结:腾讯技术工程:召回算法实践总结

[3] 全能的FM模型:zhuanlan.zhihu.com/p/58

[4]如何理解推荐系统中的i2i,u2u2i,u2i2i和u2tag2i召回?

[5]基于矩阵分解的推荐算法 | 卢明冬的博客

[6] 推荐召回策略:zhuanlan.zhihu.com/p/14

[7] 推荐系统 embedding 技术实践总结:zhuanlan.zhihu.com/p/14

[8] Fackbook EBR:arxiv.org/abs/2006.1163

[9] YoutubeNet:research.google.com/pub

[10] 负样本为王:zhuanlan.zhihu.com/p/16

[11] YoutubeNet工程问题:zhuanlan.zhihu.com/p/52

[12] FFM及DeepFFM模型:zhuanlan.zhihu.com/p/67

[13] GraphEmbedding方法:zhuanlan.zhihu.com/p/64

[14] 图神经网络入门:zhuanlan.zhihu.com/p/12

[15] Google BERT模型原理详解:zhuanlan.zhihu.com/p/46

[16] 万字长文解析词向:zhuanlan.zhihu.com/p/16

[17] 阿里MIND网络:zhuanlan.zhihu.com/p/14

[18] 深度树匹配模型:github.com/alibaba/x-de

新窗口打开 关闭