有赞推荐系统关键技术
个性化推荐是随着移动互联网发展不断发展起来的,它是建立在海量数据挖掘基础上的一种高级商务智能平台,以帮助电子商务网站为其顾客购物提供完全个性化的决策支持和信息服务。有赞微商城使用个性化推荐系统,尤其是在关键节点增加推荐入口,进行场景化推荐,帮助商家进一步提高用户的付款转化率,最大化流量变现。
一、场景介绍
目前接入个性化推荐的入口有微商城商详页、购物车、订单列表、物流信息等7个系统固定页面,除此之外,我们也封装了插件用于店铺装修接入个性化推荐,如微页面、个人中心、日历签到,也用于店铺活动页面,如砍价、秒杀、好评有礼等,如下图部分示例:
二、整体架构
有赞个性化推荐系统可以分为数据、存储、服务和应用四个层级,如下图所示。其中数据层又分为离线和实时两部分,离线会根据三个维度生成召回商品集合,离线也会对接 DMP 画像数据用于模型构建,同时根据用户的实时行为进行实时推荐;存储层用于存储数据层的数据,离线召回主要是用 hbase 存储,实时用 druid ,另外也设置了 redis 缓存,来解决部分线上性能问题;服务层是对外提供接口的部分,根据不同场景配置的召回策略,依次进行召回、排序,实时过滤三部分操作;应用层直接对接服务层,发起请求得到推荐反馈,进行商品展示。后面章节介绍该推荐系统的关键技术点。
三、召回
主要在数据层产出,是对用户的浏览、加购、购买、搜索、咨询等多维度行为进行分析,产出不同召回源,用于实时召回、离线召回和冷启动召回。
3.1 实时召回
根据实时浏览和咨询的商品从离线相似度表获取相似商品后,对所有相似商品计算分值进行排序,根据得分做推荐。目前一些用于实时召回的其他模型也正在研发中,另外针对用户的实时行为分析更多的维度,如收藏、加购等行为,结合对用户实时意图的分析进行推荐,应该效果会更好些。
3.2 离线召回
3.2.1 CF(基于协同过滤)
协同过滤是比较经典也是使用最广泛的召回算法,其中 Item-CF 其原理是根据两个商品被同时浏览/加购/购买的频率来分别计算两个商品之间的相似度分,得到三个商品相似度表;然后通过用户的请求触发去分别查询商品相似度表,扩展用户感兴趣的商品。User-CF 是根据用户浏览/加购/购买商品的共现情况,计算两个用户之间的相似度;假设 A 是与用户 a 最相似的 topK 个用户集合,就可以将相似用户浏览/加购/购买的商品推荐给用户 a。协同过滤的基本算法虽然简单,但是要获得更好的效果,往往需要根据实际的业务场景进行调优。合理选择计算商品之间相似度的数据的时间窗口,引入时间衰减,归一化、打散等策略对优化 Item-CF 的效果都有很大的帮助。
3.2.2 ClassPrefrence(基于类目偏好)
基于类目偏好的召回,利用全网数据分析用户的类目喜好,同时结合类目热销商品,召回商品集合,这个算法原理比较简单,实现上难度也不是很大。
3.2.3 FPgrowth(基于频繁项挖掘)
利用 FPGrowth 算法挖掘商品之间的频繁项,频繁项挖掘的一个典型例子是购物篮分析。频繁项研究有助于发现交易数据库中不同商品之间的联系,找出顾客购买行为模式,分析哪些商品会被一同购买,还有一同购买的频次是多少,经常被一同购买的商品就可以放到一起做推荐了。我们实际使用过程中,扩展到了浏览和加购行为,即总是在同一个会话中被浏览或者总是被同时加购,也作为了可推荐候选集的一部分。
3.2.4 Produce&Word2Vec(基于产品词的Word2Vec)
这个算法结合了产品词和语义分析,首先基于 Word2Vec 召回候选集,利用商品标题信息进行 embedding,然后计算余弦相似度,这一步召回的候选集量往往很大,所以引入产品词目的是将相似度计算范围缩小,因为只有产品相似的商品才有计算的必要。
3.2.5 QueryWords(基于查询词)
这个算法比较直接的获取用户喜欢的商品,首先需要根据搜索词和搜索后点击的商品建立搜索词及商品的联系,结合用户对搜索词的喜好,进行相关商品推荐。简单说就是通过搜索词将商品和用户联系起来,进行个性化推荐。不过需要考虑实效问题,用户对商品的需求一段时间内可能有一定兴趣,才会进行搜索,达到购买需求后一般都会进行其他需求的搜寻,这样当建立用户与搜索词的偏好联系时,分析的搜索行为数据时间窗口不宜过长。
3.2.6 Seq&Word2Vec(基于用户行为序列的Word2Vec)
计算所有用户一定时间窗口范围内对每个商品的浏览次数,同时考虑浏览顺序,挖掘得到商品直接的关联模式,如商品 A 和商品 B 在 M 个用户浏览行为中都有先后的浏览顺序,则模式商品 A -> B 的权重是 M ,挖掘更多这样的模式可以得到一个有向图,然后用随机游走在有向图上采集到商品序列,作为 Word2Vec 的输入样本,embedding 后得到商品的向量,从而可以进一步计算商品相似度用于推荐。除了浏览行为外,也可以从点击、购买等行为中挖掘这样的序列模式,可以使用 Word2Vec 生成商品向量,也可以根据用户序列预测用户的下一步行动,如下一个浏览、点击或购买等的商品,最终实现个性化推荐。
3.2.7 其他
除了考虑用户的浏览、点击、购买、搜索、咨询等行为生成了对应的召回算法外,也考虑了地域、年龄、性别等维度的信息,在对这些维度深入分析的基础上,设计了相应的召回算法。
3.3 冷启动召回
3.3.1 shopHot(基于店铺热销)
跟店铺销量相关的推荐源分别有根据店铺热销和店铺内不同类目热销,后者还做了类目的打散,考虑到只根据整体销量的话,每天推出的商品多样性会较差,加入类目打散,可以缓解这个问题。
3.3.2 linUCB(基于linUCB算法)
linUCB 算法是 UCB 算法( Upper Confidence Bounds 的首字母缩写)的扩展,对于 UCB 主要是为了解决 Multi-armed bandit 这个问题,思路就是使用置信区间,即不确定程度,区间越宽越不确定。每个商品的回报均值都有个置信区间,随着实验次数增加,置信区间会变窄,每次选择前都根据已经试验的结果重新估计每个商品的均值和置信区间,选择置信区间上限最大的那个商品。不过在推荐领域,一个选择的回报是由用户和商品共同决定的,完全可以用特征来刻画两者,选择前如果能使用特征预估每个商品的期望回报即置信区间会更合理些,这也是 UCB 需要解决的一个问题,所以 linUCB 就诞生了。linUCB 算法做了一个假设,一个商品被选择推荐给一个用户,其回报和相关特征成线性关系,用用户和商品特征预估回报和置信区间,选择置信区间上界最大的商品推荐,观察回报后更新线性关系的参数,从而进行迭代学习。之前的冷启动只有店铺销量相关的召回算法,且在推荐曝光商品中占比较高,没有做商品和用户的个性化,对于新品流量也很少,对于实时上架的新品也是无法及时推荐的。linUCB 就是针对新品的冷启动方案,新品给予一定机会进行曝光展示来验证商品的效果,逐渐迭代参数,使得效果好的商品曝光越多,效果差的商品曝光越少。
四、排序
排序模块已经做了一些工作且还在不断持续优化中。线上已经运行的主要是基准版本和 Wide&Deep 版本。基准版本是简单的融合策略,根据召回策略将同一商品来自不同召回源的打分直接加和,类似于投票法,虽然简单粗暴但是有一定效果。基于 Wide&Deep 的排序也是经验验证有效果的,所以优先使用此算法来优化效果。Wide&Deep 由两部分组成,分别是 Wide 和 Deep,如下图所示。传统的 Wide 类型的特征可以对确定性的推荐很好的建模, 如果考虑到多样性,就需要对稀疏数据和”没有直接观测到”的行为数据建模,Deep 部分可以对多阶的行为传导更好的表达。
上图参考论文《Wide & Deep Learning for Recommender Systems》 Wide&Deep 最后一层中 Deep 和 Wide 部分是合并到一起的,将 Wide 部分的特征和 Deep 部分的最后一层的特征对齐,然后统一送入到一个逻辑回归模型中,模型公式如下:
五、存储表设计
离线召回是基于 HBase 存储,对于三类离线召回源用户-商品、商品-商品、店铺-商品分别设计了三类存储 RowKey,这样便于管理不同召回算法产出的结果,同时只需要个位数的存储表就可以满足大部分的常规接入场景。另外,这三个表上层的不同召回算法是并行导入的,而不是所有结果汇总后一起导表,是为了避免一个算法的结果导入失败时还得全部结果重导的悲剧。
六、场景策略配置
不同场景接入推荐时,会有实时、离线、冷启动三部分召回策略,即对于每个场景,都会有针对实时、离线、冷启动三部分的配置,便于线上服务读取解析。配置的策略内容是经实验验证效果较好的召回源,如商详页场景,实时需要兼顾考虑时效性和当前推荐的场景性质,配置商品相似度相关的召回源是可以满足场景需求的;离线如果推荐与主商品有关联的商品效果不错,就会配置频繁项挖掘这个召回源;冷启动作为兜底方案,使用店铺热销方案也是可以满足需求的,于是配置店铺热销相关的召回源。
上述举例对应配置格式如下(仅供参考):
{
实时:
商详页:Item-CF
离线:
商详页:FPGrowth
冷启动:
商详页:ShopHot
}
另外,我们也配置了分流策略,当前策略是根据用户唯一标识进行配置,并且不同场景均可配置;还有排序算法的相关参数,如使用特征名称、算法版本、对应场景、对应场景的分流等均可配置。
七、现状及展望
- 分流测试策略还有待优化,随着业务的增长,越来越多的推荐场景接入,需要设计更为复杂的分流测试实验,只基于用户唯一标识的方式肯定不能满足需求;
- 排序阶段需要进一步优化,尝试更多的主流前沿算法,并结合业务实际情况进行相应调整;
- 当前接入个推系统最多的是有赞微商城业务,未来我们期望可以接入更多的推荐场景,包括微商城其他场景、有赞其他业务如零售、精选、分销等;
- 从各个环节提高推荐系统的性能,更快速的离线召回产出,更大规模的召回商品参与到重序模块,更及时的排序后结果返回及展示。
最后,本文没有做过多的技术细节介绍,感兴趣的话敬请关注后续文章。
-The End-
- 苹果就“降速门”致歉;央行批扫码支付不正当竞争;王健林旗下公司遭集体裁员
- 姚期智教授:量子计算是千亿万亿级别的产业,或成为科技创新的引擎
- Powershell中禁止执行脚本解决办法
- 使用AsyncTask异步更新UI界面及原理分析
- 商家为何要做小程序?
- Android中关于dip和px以及转换的总结
- Python介绍
- python案例-用户登录
- 推荐个找代码示例的VS 插件 All-In-One Code Framework Sample Browser
- 明星推出定制AI形象,虚拟形象有何优势
- apache工作模式梳理
- Mysql的二进制日志binlog的模式说明
- Git版本控制器使用总结性梳理
- “黑科技”人脸识别 TA和你的距离不是一般的近
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Jenkins配置SSH Key下载代码
- 详解kubeadm安装k8s集群常见问题
- Python 3.7 + Django 2.2.5 Web项目搭建
- Flink集成数据湖之实时数据写入iceberg
- unittest简单应用
- 假如 Web 当初不支持动态化
- Spring Boot使用OpenAPI规范
- 图论-单源最短路径(Dijskal算法)
- Mysql系列第二十五讲 mysql如何确保数据不丢失?有几点值得我们借鉴
- 使用Jsch进行安全的文件上传及下载
- 你见过最烂的代码长什么样子?
- 集智智能课程表项目 实战指南
- ZeroLogon(CVE-2020-1472) 分析与狩猎
- 什么是数字资产?
- 我要偷偷的学Python,然后惊呆所有人(第一天)