兴盛优选推荐系统召回算法实践
1.召回决定了推荐效果的上限为什么要做推荐系统?从用户的角度,推荐系统能在“信息过载”的情况下帮助用户高效地获得感兴趣信息;从公司的角度,推荐系统能帮助产品最大限度地吸引用户,留存用户,增加用户黏性,提高用户转化率,从而达到公司商业目标的增长。对于电商平台业务而言,商品推荐是为了帮助用户更容易发现其感兴趣的商品,让用户多看多买多停留,提升商品的点击率,加购率,和转化率,促进平台销量提升。目前我们已经在兴盛优选的多个业务场景下接入了商品推荐功能,例如“首页瀑布流“,“十点爆款“,“感恩回馈”首页橱窗,猜你喜欢,搜索“为你推荐”等。
推荐系统简单来说由数据,模型两个重要部分组成,其中数据部分包括离线和实时数据流,主要服务于召回排序所需数据特征,模型训练所需的样本数据,以及系统监控和推荐效果统计等方面。模型分为召回和排序两个重要组成部分,其中召回是从海量的候选集中快速选出用户感兴趣的商品集合进行排序,排序就是把召回的商品按排序模型预估的点击率或者转化率进行排序,选出top N个商品推送到业务层展示给用户。从这三部分的作用来看,如果召回的商品完全不是用户感兴趣的,那排序模型结果再准确,也不会有很好的推荐效果,所以说“召回决定了推荐效果的上限”。本次分享的“主角”就是目前兴盛优选线上推荐系统召回环节的相关算法和策略。
2.多路召回
召回在推荐系统中的作用主要是两个方面,一方面它是一个信息漏斗,负责快速从海量信息中筛选出有价值的信息,缩小排序算法的输入集合(既解决了信息过载的问题,同时也减少了排序压力,方便线上排序模型快速预测)。另一方面,它是一个融合器,通常召回的结果是多种召回策略和模型算法结果的融合,为什么要做多路召回呢?有如下几个理由:
用户侧:满足用户兴趣的多元化,用户需求与场景的多元化,同时还要扩展用户的偏好,削弱“信息茧房”效应,避免推荐内容覆盖越来越窄,例如用户自身的兴趣偏好,需要用户偏好召回,用户即时浏览的商品偏好,需要实时的相似商品召回,用户具有从众心理,需要热门商品召回。简单来说多路召回就是不同来源的用户兴趣的聚合。
系统侧:增强系统的鲁棒性;部分召回失效,还会其余召回结果,不会导致整个召回层失效;并且如果排序层失效,有召回层的结果也不会导致整个推荐系统失效。
可解释性:有的推荐召回是有明确推荐理由的,可以很好地解决产品策略的引入,增强推荐系统的可运营性,例如一些需要强曝光推广的商品就可以单独作为一路召回推荐给用户。
2.1 相关召回
通常用户购物时的常见行为就是会对相似的商品之间从价格,规格,品质,品牌等角度进行比较,另外用户还会存在关联购买的行为,例如买过猪肉之后,可能会考虑买辣椒,买过手机之后,可能会考虑买手机壳,对用户的相似或者关联行为的召回统称为相关召回,这路召回的商品集合就是为了满足用户比较和关联的购物需求。
ItemCF or Item2Item
ItemCF又称为基于物品的协同过滤算法,是利用用户历史选择物品的行为,计算物品间的相似度,给用户推荐其他相似物品。例如:喜欢A商品的用户通常还喜欢买B商品,如果某个用户买了A,则把B推荐给该用户。这个算法需要解决的核心问题就是计算物品之间的相似度,通常有如下几种实现方式:
◇统计思路
假设喜欢物品a的用户数为N(a),喜欢物品b的用户数为N(b),那么a与b的相似度为:
上述公式可以理解为喜欢A物品的用户中,有多少比例的用户也喜欢B,比例越高,说明A与B的相似度越高。
但是这样计算有一个问题,如果物品B很热门,很多人都喜欢,那么相似度就会无限接近1,这样就会造成所有的物品拿出来,都与B有极高的相似度,这样就没有办法证明物品之间的相似度是可靠的了。
为了避免出现类似的情况,可以通过以下公式进行改进:
获得了物品的相似度后,则根据以下公式来计算用户u对物品b的兴趣:
其中,N(u)是用户喜欢物品的集合,S(b,K)是和物品b最相似的K个物品的集合,Wab是物品a和b的相似度,Rua是用户u对物品a的兴趣。
item2vec
item2vec的原型是word2vec。item2vec利用word2vec生成embedding的思想,构造各个item之间的相似度矩阵之后,利用用户有过交互行为的item找到其他相似的item推荐给该用户,类似itemCF,详细的计算过程如下:
从埋点日志中提取用户行为序列。按“天”粒度将用户行为序列构成一个完整的语句,这里的行为根据不同的推荐系统所指的不同。比如:在信息流场景下,用户点击就可以认为是行为,在电商场景下,用户点击加购下单都认为是行为,但是加购和下单行为更为准确,因此在使用过程中我们往往重点选择加购下单行为构成的语句作为模型训练的语料,例如用户某天加购下单的商品序列为['A','A','B','C','D'],这个就是模型训练的一条语料。
训练word2vec得到item embedding。将每个用户“天”级别的行为序列当作语料,调用word2vec模型,然后计算出每个item的embedding vector。
计算item sim关系用于推荐。根据item embedding向量,可以计算每一个item最相似的top k个,然后将相似度离线写入到KV当中,当用户访问我们的推荐系统的时候,根据用户点击了的item,推出这些item所最相似的top k个给用户,就完成了推荐。
因此在兴盛优选商品推荐的场景下,我们利用item2vec的方法分别计算sku的embedding和二级品类的embedding,利用用户当天加购下单的sku序列和二级品类序列作为语料,分别重新训练sku的embedding,和二级品类的embedding,然后就可以计算每个sku对应的最相似的top k个sku,和每个二级品类对应的最相似的top k个二级品类,分别作为sku_itemcf和 category_itemcf召回。
语义相似
Item2vec的思路是将用户行为序列作为语料,训练word2vec模型,是根据用户行为来计算item之间的相关关系,但是还有一类相似,则是需要通过字面上(标题,描述,一级二级品类)的语义相似来判断,类比item2vec的思路,语义上的相似性计算则需要把商品的标题,描述,一级品类,二级品类分词后当作语料,调用word2vec模型进行训练,生成商品标题,描述,品类的embedding vector,然后分别计算商品之间的标题,描述,品类的相似度,再将各个维度的相似度加权求和,得到最终的商品之间的相似度,最后用户如果看过A商品,则可以把与A在语义上相似的其他商品推荐给用户。尽管语义相似只是一路召回,但是在某些简单的推荐场景下,它就可以直接作为推荐结果,例如搜索"为你推荐"就是根据搜索商品结果和关键词意图,推荐语义相似召回的商品,目前每天能覆盖百万GMV。
2.2 个性化召回
相关召回主要关注点在用户当前兴趣商品的相似或者是关联商品,既然是多路召回,仅仅依靠相关召回是覆盖不了用户全部兴趣点。用户通常都会有自己的购物偏好,尤其是那些习惯在我们的电商平台购物的成熟用户,例如一些习惯在我们平台购买生鲜水果的用户,他们就会对生鲜水果感兴趣。针对这些用户,就可以根据他们的历史行为计算他们个性化的兴趣点,从而进行商品的个性化召回。成熟用户由于历史行为丰富可以如此进行个性化召回,如果是新用户怎么初始化个性化兴趣呢,我们目前是选取不同区域最近一个月新注册的用户,根据他们的初次下单的top品类,作为该区域新用户的初始化品类召回,这也是召回冷启动的一部分。
ALS(Alternating Least Square)
推荐系统经典算法中提到最多的就是协同过滤,其中有基于item的协同过滤,也有基于user的协同过滤,但是这两类协同过滤各有优劣,ALS算法则是属于User-Item协同过滤,也叫做混合协同过滤,它同时考虑了User和Item两个方面。在早期的推荐系统或者简单的推荐场景中,通常会直接把协同过滤的结果推荐给用户,但在复杂的推荐场景下,ALS算法由于简单高效,仍然也被广泛应用,但是仅仅作为一路召回对不同用户召回其感兴趣的商品。
ALS的全称是交替最小二乘法(Alternating Least Squares),基本思想是对稀疏矩阵进行模型分解,评估出缺失项的值,以此来得到一个基本的训练模型。然后依照此模型可以针对新的用户和物品数据进行评估。对于兴盛优选的推荐ALS召回而言,利用所有用户对品类的兴趣程度构造兴趣矩阵,但是由于用户只是在少部分品类上有行为,所以大部分的品类上兴趣值为空,所以ALS就是在尝试求解这些为空的兴趣值。
具体的计算步骤如下:
1.构造用户和二级品类的兴趣矩阵。这是第一步也是最关键的一步,如果兴趣矩阵构造的不对,后续结果必然也是不对的。目前是根据用户最近一个月在各品类上的点击,加购,下单次数进行加权求和,并且加购和下单的权重要高于点击行为,得到该用户对二级品类的兴趣值。
2.求解兴趣矩阵。矩阵中的打分值表示用户对物品的兴趣值,其中"?"表示用户没有兴趣值打分,这也就是要通过机器学习的方法去预测这个打分值,从而达到推荐的目的。应该如何求解用户没有打分的品类兴趣值呢,ALS就是将兴趣矩阵分解成两个小的矩阵U和V,即用户偏好矩阵和品类的偏好矩阵,把它们都投射到k维空间,也就是说假设有k个隐向量特征,将每个用户和每个品类都用k维的向量来表示,把他们的内积近似为打分值,这样便可以得到近似的评分。
其中:
R为打分矩阵(m*n,m表示用户个数,n表示物品个数)U表示用户对隐含特征的偏好矩阵(m*k)V表示品类对隐含特征的归属矩阵(n*k)
上述模型的参数就是U和V,求得U和V之后,就可以近似的得到用户对未评分品类的评分。
3.选出用户兴趣评分topN个品类。兴趣矩阵求解之后,就能补全用户在所有品类上的兴趣评分,可以依据评分从高到低选出用户兴趣评分topN个品类。当然仅仅这样还不够,还需要根据品类的复购周期,调整用户刚下单的品类。
在"猜你喜欢"这个推荐场景中,初版就是直接利用的ALS结果给用户个性化推荐,根据ALS计算出的用户感兴趣品类,选取其中价格便宜的商品按顺序推荐给用户,尽管做法简单,但是相对于之前老版本有比较明显的效果提升。
长短期兴趣偏好
电商推荐场景下,对用户的偏好通常会分为长短期兴趣偏好,长期兴趣是用户自身长期养成的购物习惯和爱好,短期偏好是受到外界因素的影响产生的短期的购物偏好,例如从某个用户半年或者一年的购物行为来看,每隔一段时间都会买卫生纸,那卫生纸属于用户的长期偏好,最近一个月这个用户才开始买猪肉,而且之前都没有买过猪肉,那猪肉可以理解为用户的短期偏好。
通常计算用户的长短期兴趣偏好会有很多种方式:
一种基于简单的业务规则,例如:用户最近6个月有过复购的品类可以作为用户的长期偏好,最近2个月下单且之前没有买过的品类,并且超过该品类通常的复购周期的品类,则可以作为用户的短期兴趣,这种业务规则最大的优点就是具有很强的可解释性。
另一种是利用TF-IDF模型思想,计算用户对于各个品类的偏好程度,这种计算就不区分用户长短期兴趣偏好,利用偏好程度排序来选取用户感兴趣的品类。TF-IDF的意思是词频-逆文档频率,是自然语言常用的算法,通常用来评价一个词对于某个文件的重要性(可以用于判断文章主题,或者判断用户搜索关键词与待检索文章的相关程度),如何来计算用户的兴趣偏好呢?具体做法是将用户A最近下单的品类序列理解为一篇文档,所有用户下单的品类序列当作所有文档,那每个品类则是文档中的一个词。TF可以衡量用户A对于该品类的兴趣程度,但是只有这一部分还不够,因为还要看一下其他用户购买该品类的情况,如果大部分用户也都买该品类,说明用户普遍对这个品类感兴趣,那用户A对该品类最终计算的兴趣值就应该要降低一些,这就需要应用到IDF,就是衡量这个品类在所有用户的普遍重要性(如果所有用户对于该品类买的多,那么IDF就小,买的少,IDF就大),再利用TF*IDF得到用户A对于该品类真正的偏好程度。但是这里要注意,对于电商场景下,统计一个品类出现次数的时候,需要根据下单时间进行加权,下单时间近的权重高,下单时间久的权重低,这样统计的品类次数更客观准确,并且由于结合了下单距今的时间窗口,可以更准确地捕捉用户的长短期兴趣。
复购及点赞评论
正如开篇提到的,召回是融合器,因为要充分考虑用户不同思路的商品偏好,所以往往除了算法模型之外,需要借助一些简单的业务规则进行召回。比如这一路用户复购及点赞评论的召回,用户买过的商品如果今天仍然在售,则可以推荐给用户,用户历史点赞或者给过好评的商品,如果今天在售也可以作为召回推荐给用户,但是都需要判断该用户对于此商品最近购买时间是否超过了该商品所属品类的平均复购周期,减少刚刚购买过的商品重复推荐的问题。这类召回尽管加工逻辑简单,但是在线上效果往往是直接有效的,并且具备很强的可解释性。
DSSM
作为一个成名很早的双塔深度学习模型,DSSM模型最早发明是用于搜索引擎中,通过构建搜索词和搜索结果独立子网络,计算出搜索词和搜索结果的embedding,最后利用embedding向量,可以快速计算搜索词和搜索结果的相似度,建立搜索词和topN个相似搜索结果的关联。目前这路召回只是在模型训练和调优阶段,还没有上线,但是作为业界常用的召回方法分享一下。
如何将DSSM模型映射到推荐召回场景呢?从本质上说,搜索是搜索词(query)和搜索结果(document)的关联,商品推荐则是用户(userid)和商品(sku)之间的关系,所以可以利用DSSM搭建用户端和商品端构建两个独立的子网络结构,用户端输入用户的特征(历史点击加购下单次数等),用户和商品交互的特征(用户在该商品所属的一级二级品类的行为数据),商品端输入商品的特征(商品价格,所属一级二级品类,总的点击加购下单次数等),最后一层计算两者生成embedding的相似度,并且把用户点击/加购/下单作为正样本标签,其余的曝光未点击加购下单的数据当作负样本标签并适当采样或者随机生成用户与其他商品的负样本数据,让模型进行训练。
最后在线上调用的时候,可以分别把用户端和商品端的embedding结果保存,然后线上应用的时候直接查询对应的embedding结果,计算相似度,召回该用户相似度topN的商品,或者把模型分别存储为user_embedding模型和item_embedding模型,DSSM模型结构如下图所示:
从这样的思路来看,DSSM的结构和原理也天然适合推荐的召回环节,当然生成用户和商品embedding的方式有很多,为什么DSSM会脱颖而出呢,第一个原因是从其选择的特征和模型结构来看,很好地将用户embedding和商品embedding映射到了同一个向量空间,这样就能通过用户向量和商品向量直接计算相似来进行个性化召回,另外这样生成的embedding很好地结合了用户历史行为,同时还可以考虑很多维度的商品特征,比单一地依靠行为序列,或者是语义来计算的商品和用户向量内容会更加丰富,对用户和商品的表征也会更加准确。
2.3 通用召回
多路召回中有了相关召回,个性化召回,对用户兴趣的覆盖也是不完整的,因为仅仅依赖这两路召回,用户推荐的商品往往局限在用户自身的行为中,会陷入推荐系统常见的“信息茧房”的问题,用户在推荐结果中永远只能看到有限品类的商品,因此还需要一些通用召回来扩展用户的兴趣,推荐出一些用户以往不太感兴趣的商品,跳出其惯性购买行为;同时对于刚开始使用产品行为数据少的用户或者是全新用户推荐时,补充推荐的商品。
实时热销,热点,分享
整体用户的购买热门商品往往有时候也会是这个用户感兴趣的商品,例如中秋节的月饼,端午节的粽子,大盘用户都在购买,即使这个人平时可能没有粽子和月饼的需求,也需要把这些热门商品推荐给用户,另外某些爆款商品,之所以成为爆款,有其吸引用户的点,所以这些商品推荐出来也可能吸引用户的兴趣,尤其是对于我们这种商品少,主打季节性强生鲜品类的电商平台而言,这一路召回就会显得尤为重要。因此我们会实时地统计各个商品在平台的销量,按销量top进行召回。
当然仅仅只考虑热销也是不够的,因为一些商品跨天销售或者是未到购买时间的秒杀商品,用户往往会喜欢先加购,或者在购买之前就喜欢看,因此实时热点是对商品的曝光点击加购等行为数据加权,算出整体加权之后的热点商品,对热销商品的补充。
门店老板和用户的分享热门也是通用召回的一部分,因为门店老板往往最了解身边的用户喜好,所以在门店端热门分享的商品大概率从性价比或者品质上说都是比较好的商品,另外小程序端,用户个人的热门分享也往往是其觉得优质值得推荐的商品,这路商品召回也是我们社区电商平台的特色,因为更看重用户之间的分享行为。
门店热销
附近的邻居热销的商品,往往也可能是这个用户的兴趣点,因此在这路召回中,重点统计了用户所属门店的热销商品。
总的来说,通用召回尽管看上去逻辑简单,但是也一定是召回环节不可或缺的重要部分,而且正是由于通用召回的存在,一方面能直接有效地扩展用户兴趣商品,另外一方面通用召回的可解释性强,通常还可以在这路召回中支持运营配置的商品,为一些指定商品增加更多曝光。
3.总结及后续优化方向
推荐系统的召回环节,又称为“matching”,很形象地说明了召回的作用,就是从全量的信息中匹配出用户感兴趣的内容,并且召回作为推荐的基础,如果召回的商品质量不好,排序再准确最终也不会获得很好的结果,所以我们对于召回环节就不能疏忽。对于电商推荐系统而言,召回的作用就是要从海量商品池中快速、正确、全面的匹配出用户感兴趣的商品用于排序,我们利用相似商品和itemCF等相关召回及时捕捉用户当前的关联兴趣商品,利用ALS算法,长短期兴趣偏好,DSSM算法,以及用户历史常买及点赞等个性化召回刻画用户画像,根据用户过往历史行为在相关召回的基础上补充用户个性化兴趣,最后利用热销,热门分享等多个通用召回扩展用户的兴趣点,避免推荐商品陷入“信息茧房”,在这些召回路径中既要满足行为丰富的成熟用户,也要考虑全新用户和历史行为不足的用户。未来我们会不断对现有召回进行优化,同时也会去扩展更多的召回,以保证全面准确的召回结果。
页:
[1]