有赞个性化推荐能力的演进与实践
日前,由又拍云举办的大数据与 AI 技术实践|Open Talk 杭州站沙龙在杭州西溪科创园顺利举办。本次活动邀请了有赞、个推、方得智能、又拍云等公司核心技术开发者,现场分享各自领域的大数据技术经验和心得。以下内容整理自有赞数据智能团队负责人尹越现场分享:
尹越,有赞数据智能团队负责人,与团队成员一起承担有赞搜索、推荐、客服机器人、智慧零售、风控、会员营销等多场景的数智化建设的职责。
大家好,我是来自有赞的尹越,今天主要和大家分享有赞数据智能团队在个性化推荐能力的演进与实践。我将首先介绍有赞公司和我们团队,其次是分享下我们从事的业务以及遇到的问题,最后聊下有赞推荐技术是如何逐步演进的。
有赞数据智能团队
有赞是一家零售科技服务公司,致力于协助商家经营移动社交电商和全渠道新零售,服务好每一个商家的上门客户。我所在的有赞数据智能团队曾负责线上场景的有赞微商城,现在负责线下零售,包括零售门店网店的有赞零售业务,涉及医美行业的有赞美业和涉及线下教育的有赞教育。
有赞数据智能团队本身是一个直接面向业务的团队,我们的主要职责是负责引领有赞数据智能进程,涉及的业务包括推荐与搜索、风控、精准营销、智能会员以及智慧零售。
有赞推荐业务及场景
业务场景
推荐业务:涉及微商城、零售线上门店、教育、精选、分销、有赞客、爱逛,其中有赞精选是面向 C 端的平台业务,有赞分销是面向 B 端商家选货的平台业务,有赞客是面向网红主播选货的 CPS 平台业务,爱逛则是视频直播平台。
场景:有赞提供帮助商家在自己微页面进行装修的自定义插件,覆盖商详页、购物车、付款成功、营销活动页等核心交易链路。此外,还有商家和消费者进行沟通的提升商品转化率的客服商品推荐场景。
展示形式:可以分为下拉的瀑布流推荐、广告 banner 推荐,以及综合了消费者的历史浏览行为、店铺热销行为和猜你喜欢等多种推荐形式的推荐橱窗。
标的物:涉及商品推荐、优惠券推荐、店铺笔记推荐以及视频推荐。
模式:分只推荐商家店铺内部的店内推荐、涉及其他店铺内商品的跨店推荐,还有前文提到的有赞精选的 2C 平台推荐和有赞分销的 2B 平台推荐。
场景示例
我们可以先通过测试店铺了解有赞的商家是如何经营自己的店铺的。如上图所示,商家可以通过后台管理,从店铺级别、商品级别、订单级别、数据以及资产等不同的维度实现整个核心交易链路的日常经营管理。
装修组件支持个性化推荐插件功能。如上图所示,右侧是一个微页面装修的部分,商家可以通过自己的需求配置如积分商城、知识付费等不同插件,组成自己所需要的微页面;也可以根据自己的需求,选择当前场景所需要适配的推荐规则。
有赞推荐系统的问题与挑战
店内商品丰富度差异大。有赞主要是服务商家运营私域流量,不同的商家店内商品的数量会相差很大。有的商家可能多一点,成百上千;而有的商家商品较少,可能只有几个。当商品数量非常少的时候,或许我们的推荐价值没有那么地明显,这是一个问题。
跨店用户行为比较少。这涉及到当前 SaaS 经营模式的一个限制,即很难产生跨店的行为。它并不像淘宝、京东是一个平台型的产品,消费者可以很容易在不同的店铺之间逛来逛去。
业务场景复杂度高。有赞推荐业务既有面向 C 端的,也有面向 B 端的,还有面向客服场景的。整个业务场景以及团队需要对接的业务方相对较多。
业务需求量大。复杂的业务场景和对接的众多业务方,使得对团队推荐业务接到的需求量比较大。
埋点数据易缺失。我们的日志信息多在业务前端进行埋点,可能业务前端在进行其他功能升级的时候,会造成推荐相关的埋点数据丢失。
有赞推荐技术演进
既然问题出现了,我们总要解决问题,下面我们看一下有赞的推荐技术到底是如何一步一步演进,解决这些问题的。
有赞推荐系统 1.0:竖井式架构
最底层的基础数据主要是业务数据和原始日志数据。业务数据一般是业务写在 MySql 当中的,比如说商品的原始信息、店铺的原始信息;日志数据包括商家在 B 端的操作行为日志以及消费者在 C 端的消费行为日志。
第二层是离线数仓层,这里包括了三部分:数仓 ODS 层大部分是将原始业务的数据在数仓中做一个表的映射,做一些简单的清洗与补全;数仓DW 层会将下面的异构的 ODS 层数据以通用的格例如以星型模型或者以其他的宽表形式,整合成适合上游业务方使用的中间层数据表表;数仓 DM 层更贴近于业务,进行一些指标的聚合等相关的操作。
第三层是推荐相关的一些功能分层,首先看召回与特征这一层:在 1.0 版本不同的业务线会有独立的存储介质以及存储表,比如说像有赞精选和有赞分销都有自己的 HBase 表,还有一些特征可能自己存在在 MySql 当中,彼此之间也没有去通用。
第四层是线上服务层,在 1.0 版本当中,有赞的推荐系统没有单独抽离出一个独立的系统,而是把我们的业务逻辑与业务方的 Java 代码相对紧密地耦合在一起,将不同业务当中的召回、排序都嵌入在业务代码当中。我们当时使用的算法模型是传统的逻辑回归,通过 SparkPi MLlib进行训练,再在通过 Java 在线上动态加载 PM 模型产生的排序效果。再往上是业务的前端跟业务的后端进行对接,前端负责展示和埋点相关的工作。
竖井式架构的缺陷
可用的辅助系统相对较少。例如离线数仓生成不同的 Hive 表会需要有任务调度的有赞 DP 系统,我们需要有赞的 Meta 系统查到不同的 Hive 表,相当于一个数据字典知道有哪些表、哪些表有哪些字段。而为了分区效果以及对比做 AB 试验,在有赞 Bi 当中,数据组和算法组需要自己开发报表分析业务效果。
还有一个明显的缺陷是如果有新业务进来,起码从召回与特征层就要重新进行特征的制作。我可能需要单独抽出一个服务和业务方、前端进行对接。整个开发周期非常长,重复工作非常多。例如同样的商品,可能近 7 天销量、近 7 天退款率等一些数据很有可能在不同业务方会存多份,这个造成数据使用上的冗余。
有赞推荐系统 2.0:集中式架构
2.0 时期将之前 1.0 的竖井模式转变为了集中模式,架构上带来了很多变化:
基础数据层引入实时数据
基础数据中除了离线数据外新引入了实时数据。引入实时数据的好处在于当消费者搜索、浏览或者购买以后,基本上能在秒级别捕获到他的行为日志。当时我们是通过 Druid 做实时数仓,将行为日志落在 Druid 当中,提供上游的推荐引擎进行调用。
召回与特征层
为减少不同业务对于同样特征数据使用的冗余的开发,我们尽量将不同业务方都可以使用到的特征,统一地存储在同样的 HBase 表当中。在模型选择上,我们也从传统的机器学习模型迁移到了TensorFlow 架构下的模型服务,然后通过 TFServing 向线上提供模型的推理服务。
Java 版本推荐引擎
在新的架构中,我们抽象出了专门的 Java 版本的推荐引擎,并按照不同的功能进行分层,即触发——召回——粗排——精排——干预。精排过程中会调用前文提到的TFServing 的服务,进行商品等其他标的物的精排打分,最后的干预更偏向于业务,例如将某些店铺内的商品打散或者要对一些条件进行过滤,是一个干预重排层。
业务场景更复杂
相较而言,2.0 版本对接的业务场景会更多,除了之前的有赞精选,像有赞微商城、有赞零售、有赞教育以及有赞客等,各个业务场景会通过新的系统接入。
辅助系统更完善
新增更标准化的记录埋点方案的埋点平台,专门用来做算法实现好坏的 ABTest 系统以及帮助我们管理实时调度任务的有赞 RP 平台。
有赞推荐系统 2.5:半开放式架构
虽然 2.0 版本比 1.0 好了很多,很多开发工作做到了资源复用,但仍有一些问题是没有解决的。Java 版本的推荐引擎中主要是提供一个对外的接口,而前端的展示以及埋点依然要业务方的前端进行开发,这会给后续追踪业务效果以及 ABTest 实验所必须强依赖的日志信息的埋点准确性带来很大程度的挑战。
我们之前遭遇过埋点和上线测试都验好了,但因为业务方其他功能升级引起埋点某些字段丢失,最终导致后期效果没有办法跟踪,不得不推动业务方反向把埋点再补全的事情。在实际开发的过程当中,这非常影响开发效率和对接效率。
为了解决这些问题,我们在推荐引擎与具体业务场景对接之间,新增加了一个推荐的前端服务化组件。这样就把推荐各展示位的展示形式、如何埋点、和后面的推荐引擎以什么样的参数去交互等问题,和业务方的前端完全隔离。只要前端告知是哪一个业务(所需要的是瀑布流模式、横排滑动模式还是其他模式的展示形式)、场景 ID 以及必要的参数信息就行了。这里可能通过七八行代码就可以快速对接一个推荐业务场景,一天对接、一天测试,第三天就上线了。事实上,我们已经成功通过有赞云开放平台向很多商家用户提供了该版本推荐引擎服务,帮助商家可以在非有赞域内的页面展示自己的商品。
此外,2.5 版本中辅助系统同步启用了有赞的算法平台,包含训练板块的 Sunfish 以及管理线上 TFServing 的分流与高可用的小盒子。
有赞推荐系统 3.0:开放式架构
上图呈现的 3.0 版本是有赞推荐团队希望当前推荐架构的方向。目前有赞对接的商家从中等体量到大体量都有,而大商家对在各个场景都有定制化需求:教育类的商家希望自己的商品可以按照教育课程、上课人群的年龄或者课程的级别要求进行关联推荐,而有一些商家又希望一定要自己设定的某几个商品出现在某些展位前。面对这种定制化需求多样的问题,如果是单靠有赞推荐团队自己去开发、不断的迭代,成本是非常高的,而且也不太现实。所以我们希望能够通过不同的环节开放出更多的组件与插件,满足商家自己在不同场景的个性化需求,从而达到一个有赞推荐系统整体的开放式效果。
目前整个推荐业务迭代过程中需要在多个平台之间来回切换,我们也希望后续能够有统一的推荐管理平台的方式,整合多个管理系统的功能,一站式解决整个推荐业务的对接。
召回、排序演进
召回和排序是推荐系统当中比较关键的两个环节,我们详细展开介绍。
召回演进
目前召回部分的召回源大概分为四大类:I2I、U2I、T2I、兜底。
I2I:商品找商品的召回模式
-
FPGrowth,挖掘不同商品之间的关联性
-
Item-CF ,Item-base 协同过滤的算法
-
I2T2I,通过标签将不同的商品之间建立关系
-
GraphSAGE,基于图卷积的标的物进行向量化的召回模式
-
标题相似,将标题通过 Bert 产生标题向量,在标题向量之上基于局部敏感哈希做向量相似进行的召回
-
头图相似,将商品的头图通过图片分类模型抽取出图片对应的向量,在头图的向量上进行头图相似的一些召回
U2I:人找商品的召回模式
-
DMP 召回源,指的是通过消费者的性别、年龄等一些用户维度的属性和商品进行关联
-
U2T2I,和 I2T2I 类似,也是通过标签建立用户跟商品之间的关系
-
User-CF,基于用户和用户之间相似的协同过滤
T2I:通过标签去找商品的召回模式
我们有基于商品的类目分类模型,基于产品词、标题产品词的抽取模型,以及用户在搜索过程当中搜索词和商品之间的点击购买关系所产生的关系模型。这一类召回源主要会用在前文提到的实时召回以及此前没有用户行为的场景
兜底的策略
当上述所有模式都失效且无法获得任何上下文的时候,不能什么也不推荐,总得有一个兜底的策略,所以会有热销、爆款。
排序演进
最后跟大家分享一下有赞排序算法的演进过程。1.0 版本采用的是相对比较传统的基于逻辑回归的一个排序算法,2.0 版本初期在使用深度学习框架之后,引入了相对比较简单的入门级的 Wide & Deep 的模型。在经历了多版本的迭代、对比多个多任务学习框架后,我们最后选用了阿里巴巴在 2018 年提出的 ESMM 模型,它可以把 CTCVR 以及 CTR 同时作为训练目标去训练。
当然在这些模型的尝试过程当中,我们也在不同业务场景使用了其他的一些模型方式去做尝试。比如我们在有赞分销业务中曾经尝试过基于 ListWise 的 Learning to rank 的 LambdaMart 模型;而客服对话场景可能会更偏搜索,我们为了捕获两个搜索问句以及答案标题之间的语句相关性,我们使用了 PairCNN 相关的深度学习模型,最后发现 ESMM 模型可能是现阶段比较适用的。