达观数据:用好学习排序 (LTR) ,资讯信息流推荐效果翻倍

图片描述

序言

达观数据是一家基于文本语义理解为企业提供自动抽取、审核、纠错、推荐、搜索、写做等系统服务的人工智能企业,其中在推荐场景上咱们也服务了不少客户企业,客户在要求推荐服务稳定、需求响应及时的基础上,对系统的效果也提出了愈来愈高的指望,这对算法团队也是一个挑战。本文将从资讯信息流这个场景入手,先简单介绍达观推荐引擎的架构演化,同时尽量详细的介绍学习排序这个核心技术的实践和落地经验。html

达观推荐引擎架构

达观推荐引擎采用在线-近线-离线三层系统架构,能够从性能和算法复杂度两个维度来进行区分。
在线:实时响应客户http api推荐请求,通常须要严格控制在100ms之内,最好在50ms。该模块须要严格保证稳定性,综合考虑各个依赖模块的异常兼容、流量的超时控制等。算法

近线:准实时捕捉用户实时行为并作出反馈,即近线模块的输出须要考虑用户的实时行为反馈。该模块通常处理延迟为秒级。spring

离线:基于分布式平台离线挖掘,输出包括item-base协同过滤结果、基于标签的召回结果、各维度热门结果、用户画像等等。该模块的处理延迟通常为小时级或者天级。api

一个通用的资讯流推荐架构以下:
图片描述
图1:online-nearline-offline三层架构 数组

hot rec模块负责生成各个维度的热门结果,如分类别热门、分地域热门;tagrec生成各个标签的召回结果,如 英超 -> (item1,item2,….);item rec生成每一个资讯item的相关结果;user rec nearline根据用户实时行为和离线画像负责生成用户的推荐结果;reconline响应推荐请求;item cache返回资讯的信息;uhvreceiver负责接收用户对item的行为反馈。关于架构可参考更过以前达观数据发布的推荐技术文章。性能优化

为何须要学习排序

学习排序(LTR:learning to rank)是信息检索领域的经典问题,也是互联网场景中ranking这个核心算法问题。推荐整个流程能够分为召回、排序、重排序这三个阶段,通俗来讲,召回就是找到用户可能喜欢的几百条资讯,排序就是对这几百条资讯利用机器学习的方法预估用户对每条资讯的偏好程度,通常以点击率衡量,因此学习排序在不少状况下等同于点击率预估,都是将用户最可能点击的资讯优先推给用户;重排序更多考虑业务逻辑,如在推荐结果的多样性、时效性、新颖性等方面进行控制。架构

在没有学习排序以前,也能够单纯使用协同过滤算法来进行推荐。列如使用用户最近点击的资讯信息召回这些item的相关结果和偏好类别热门结果组合后进行返回。可是这对于资讯类推荐须要考虑一下问题:资讯类信息流属于用户消费型场景,item时效性要求高,item base cf容易召回较旧的内容,并且容易致使推荐结果收敛。所以能够将item的相关结果保证时效性的基础上,融合类别、标签热门结果,对各个策略的召回结果按照线上整体反馈进行排序,就能够做为用户的推荐结果。可是这一融合过程比较复杂,一种简单的方式就是看哪一种召回策略整体收益越高就扩大这个策略的曝光占比,对于个体而言却显得不是特别个性化,并且在规则调参上也比较困难。并发

LTR架构

咱们迅速在资讯信息流推荐场景上实践ltr算法。Ltr通常分为point wise、pairwise、list wise,通常工程上使用pointwise较多,简单,成本低,收益也可靠。简单来讲,Ltr即预测user对一个未消费item的预估点击率,即:机器学习

图片描述

即这个预估的点击率是和user、item、context相关的。咱们使用逻辑回归(logistic regression,lr)模型来搭建咱们初版的学习排序架构,lr模型简单可解释,缺点在于须要对业务特征有较深理解,特征工程比较费力,但从应用角度出发,不管是lr、ffm亦或是较新的wide& deep等模型,特征挖掘都是极其重要的一环。所以在首先基于lr模型的基础上,核心工做就是基于业务理解并发掘特征。如下是排序模型的总体推荐架构。
图片描述
图2:ltr总体架构分布式

1 日志过滤

推荐日志详细打印了每次推荐请求的参数信息和返回信息,如屏数、请求个数、设备信息、位置信息、返回的推荐结果。推荐日志须要尽量的考虑后期可能使用到的特征,并作好充分的记录。将推荐日志与曝光日志进行第一次join,过滤掉未曝光即用户没有看到的推荐item,这部分样本没有参考意义,能够省略;第一个join后的结果与点击日志join,便可以获得每条样本的label(0/1:未点击/点击)。两次join须要根据请求时间、userid、itemid三者进行inner join,确保数据准确。日志过滤后生成的每条样本信息以下:

[请求时间、曝光时间、点击时间(若是有)、userid、最近的点击item列表、最近曝光的item列表、itemid、召回策略、屏数、曝光顺序位置、地理位置、设备信息]
–> 点击label。

2 特征工程

通过1)的样本缺乏足够的特征,咱们须要补充user和item端的特征。该部分特征须要离线挖掘并提早入库。总结后的可以使用特征种类大体以下:

特征种类
User特征:手机型号、地域、图文曝光/点击总数、视频曝光/点击总数、图文点击率、视频点击率,最近一、二、3天图文视频点击数、最近点击时间、最近一次点击是图文仍是视频、一二级类别点击率、标签偏好,类别偏好、最近16次点击的素材分布、最近16次点击item的平均标题向量、曝光时间、点击时间等;

item特征:itemid、类别、整体点击率、最近一周点击率、图片个数、来源、类型(图文仍是视频)、发布时间、标题向量、召回策略、点击反馈ctr等;

context特征:屏数、曝光顺序位置、请求时间段等;

交叉特征:用户对item类别的一二级类别点击率、用户对item标签的偏好、用户对item素材类型的曝光、点击次数和点击率、最近16个点击item与预测item标题向量的余弦类似度、类似度最大值等。

交叉特征对于ranking特别重要,核心在于逻辑回归函数中,若是与预测item无关的特征不会对item的排序产生影响,只有item特征或者与item交叉的特征才会对排序有实质影响,由于其余特征对任何待预测item的打分贡献是同样的。

图片描述

咱们没有使用bagof word模型来表示标题,由于这很是稀疏,而是采用标题中关键词的word2vec向量组合生成标题表示,使用词向量来表示标题极大减小了特征规模,实现上比较方便。标题向量同时须要归一化成单位向量,单位向量的余弦类似度即两个向量的内积,这个优化显著提升了ltr在线模块的性能。

咱们将全部特征按类型划分为离散型、连续型、向量型三种类型。如item类别就是一个离散型特征、item ctr就是一个连续性特征、标题向量就是一个向量型特征。对于每种特征,其处理方式都会不太同样,对于离散型通常直接根据离散值作feature name,对于连续值咱们部分参考youtube wide & deep论文中的等频归一化方法,简单来讲加入ctr特征须要等屏成10个特征,即将ctr值按照分布取其10等分点,这10等分点就定义了10个区间,每一个区间的样本数都占10%。须要注意的是,ltr在线部分须要hardcode写死这10个区间来提升特征离散化的效率。

因为离线和在线都会须要User和item端特征,咱们在hive数仓和ssdb集群总中都存储一份,离线负责join hive表,在线负责读取ssdb。

3 模型训练与评估

通过特征工程后,训练数据按照libsvm格式进行打印。使用一天的训练数据的状况下,整个特征空间规模约为30万维左右。模型训练采用sklearn的logistic regression模型进行训练,方便dump和load模型,咱们采用了lbfgs算法来进行训练,lbfgs是一种拟牛顿法,不一样于随机梯度降低,lbfgs老是朝着最优化梯度方向进行迭代。

简单起见,咱们使用N-2天前的日志作训练,N-1天前的日志作评估,需保证两部分日志的用户群体是一致的,咱们再作ab测试的过程当中,不能训练数据用的是1号桶,评估数据用的是2号桶。

实际过程当中,咱们采用1500万条样本作训练,300万条样本作评估,训练完成后离线auc为0.79-0.8区间内,在线auc为0.75-0.76区间内,存在必定差距。关于auc能够自行参考技术文章,简单来讲auc就是衡量模型将正样本排在负样本前面的几率,即排序能力。

4 在线服务于评估

咱们的最终目的是要在线上流程产生收益,咱们采用rpc搭建了一个ltr在线服务,负责接收online的ltr请求。推荐online在召回各个策略的结果后,会将userid、预测的itemid列表、context等信息传给ltr online,ltr online打分后返回。咱们对ltr online作了充足的优化,包括标题向量的单位化、ssdb性能优化、特征离散化的优化,显著提升了性能,对200-300个item打分的平均响应时间控制在100ms之内。

模型不只须要离线评估,还须要在线评估,在线评估即评估在线样本的auc,recommend log中记录了ltr score,所以能够方便的计算在线auc。计算在线auc的目的是为了验证离线效果提高和在线效果提高的同步性。

5 业务效果的提高

咱们在测试组上线ltr逻辑后,在点击率指标上相比原算法取得了明显的提高。以下图所示:

图片描述

能够明显看出上线后,基于点击率目标的ltr对于天级点击率的提高是很是明显的。

问题探讨

1 单机训练大规模样本

因为选取的样本数较大,1000-2000万的规模,简单增大样本数能够显著提升auc,在咱们的场景上在往上增长auc就彷佛增长不明显了。这么大的训练样本单机训练的话显然只能用稀疏矩阵的方式来存储样本。Scipy的cs_matrix就是很是好的选择,因为sklearn的转载cs_matrix时数组下表采用int,故最大空间只能到20亿,显然2000万样本* 每一个样本的平均特征数远远大于20亿,所以咱们探讨了cs_matrix如何加载大规模数据的方法,最终咱们参考liblinner工具包中加载libsvm格式数据的代码,固然libliner加载方式也存在问题,通过修改调试后,成功的完成了训练数据的加载,具体问题和解决方式能够参考https://blog.csdn.net/wh_spri...

2 样本和特征的时间正交

样本和特征数据的时间正交即二者在时间上不该该有交叉。举个例子,前期咱们在join用户端特征时,用的是1号的训练样本数据,用户离线特征用的也是1号的数据,这样二者就会存在交叉,即user点击了一篇英超新闻,同时user 画像中也偏好英超标签(由1号的点击生成),这样就会致使auc偏高,固然这种偏高就是虚假偏高,模型的泛化能力是不好的。在实际过程当中,遇到过几回auc忽然偏高的状况,发现大部分都是因为没有保证数据正交性致使的。

在整个流程中,数据的时间正交老是被不断强调。不管是user、item特征仍是样本数据,好比训练样本中一个特定user的样本按照时间排序是(s1,s2,s3,s4,s5,s6,s7,s8,s9,s10),使用s1-s8训练,s9,s10评估是合理的,而使用s3-s10训练,s1,s2则显然是不合理的。

3 预估点击率和实际点击率的一致性

点击率预估基本要求就是预估的点击率要精准,若是只考虑位置的ranking,能够不用过度关心预估的绝对值,但实际状况下仍是须要尽可能保证预估分数的合理性,每每预估精准的ctr具备很大的参考价值。

前期咱们预估的点击率一直偏高,平均打分甚至达到了0.5,通过排查在于训练模型的参数设置不合理,错误的将LogisticRegression的class_weight参数设置成balanced,致使损失函数中正样本预测错误的代价增大,致使模型偏向正样本,从而致使预估的点击率极度偏高,修复成默认值预估点击率降低明显,接近实际值。具体参考:https://scikitlearn.org/stabl...

同时为了保证训练数据和在线服务彻底一致性,咱们调整了推荐的总体架构,更多的直接在推荐online模块负责召回和排序,这样又能够进一步保证预估点击率和实际点击率的一致。

4 重要特征和 case排查

lr模型能够方便debug每一个样本的各个特征和权重,权重高的特征显然更加剧要。若是你以为重要的特征权重太低了或者不重要的特征权重太高了,也许就要思考为何了。如下是一个样本的debug信息。
图片描述
例如咱们发现ctr特征权重特别高,假设一个新item曝光了一次点击了一次,点击率是1.0,乘上ctr的权重上这个item极易被排到最前面,所以咱们考虑ctr的置信度,考虑对ctr类特征作了平滑。

图片描述

图片描述值根据实际状况设定。

总结

本文详细介绍了达观数据的推荐引擎架构和在资讯信息流推荐场景中利用ltr排序显著提升业务指标的实践和经验。因为篇幅有限,关于非线性的ffm、wide & deep没有作详细介绍,而这也是算法团队一直继续投入研究的重点。

关于做者

文辉:达观数据联合创始人,主要负责达观数据推荐系统、爬虫系统等主要系统的研究和开发。同济大学计算机应用技术专业硕士,曾就任于盛大文学数据中心部门,负责爬虫系统、推荐系统、数据挖掘和分析等大数据系统的研发工做,在爬虫系统、Hadoop/Hive、数据挖掘等方面具有充足的研发和实践经验。

相关文章
相关标签/搜索