<div id="cnblogs_post_body" class="blogpost-body ">
<blockquote>
<p>58同城作为中国最大的分类信息网站,向用户提供找房子、找工作、二手车和黄页等多种生活信息。在这样的场景下,推荐系统能够帮助用户发现对自己有价值的信息,提升用户体验,本文将介绍58同城智能推荐系统的技术演进和实践。</p>
</blockquote>
<p>58同城智能推荐系统大约诞生于2014年(C++实现),该套系统先后经历了招聘、房产、二手车、黄页和二手物品等产品线的推荐业务迭代,但该系统耦合性高,难以适应推荐策略的快速迭代。58同城APP猜你喜欢推荐和推送项目在2016年快速迭代,产出了一套基于微服务架构的推荐系统(Java实现),该系统稳定、高性能且耦合性低,支持推荐策略的快速迭代,大大提高了推荐业务的迭代效率。此后,我们对旧的推荐系统进行了重构,将所有业务接入至新的推荐系统,最终成功打造了统一的58同城智能推荐系统。下面我们将对58同城智能推荐系统展开介绍,首先会概览整体架构,然后从算法、系统和数据三方面做详细介绍。</p>
<p>整体架构首先看一下58同城推荐系统整体架构,一共分数据层、策略层和应用层三层,基于58平台产生的各类业务数据和用户积累的丰富的行为数据,我们采用各类策略对数据进行挖掘分析,最终将结果应用于各类推荐场景。</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/4149def774474b348cf0539a07c5a0a5_th.jpg" alt=""></p>
<ul>
<li>
<p>数据层:主要包括业务数据和用户行为日志数据。业务数据主要包含用户数据和帖子数据,用户数据即58平台上注册用户的基础数据,这里包括C端用户和企业用户的信息,帖子数据即用户在58平台上发布的帖子的基础属性数据。这里的帖子是指用户发布的房源、车源、职位、黄页等信息,为方便表达,后文将这些信息统称为帖子。用户行为日志数据来源于在前端和后台的埋点,例如用户在APP上的筛选、点击、收藏、打电话、微聊等各类操作日志。这些数据都存在两种存储方式,一种是批量存储在HDFS上以用作离线分析,一种是实时流向Kafka以用作实时计算。</p>
</li>
<li>
<p>策略层:基于离线和实时数据,首先会开展各类基础数据计算,例如用户画像、帖子画像和各类数据分析,在这些基础数据之上便是推荐系统中最重要的两个环节:召回和排序。召回环节包括多种召回源的计算,例如热门召回、用户兴趣召回、关联规则、协同过滤、矩阵分解和DNN等。我们采用机器学习模型来做推荐排序,先后迭代了LR、FM、GBDT、融合模型以及DNN,基于这些基础机器学习模型,我们开展了点击率、转化率和停留时长多指标的排序。这一层的数据处理使用了多种计算工具,例如使用MapReduce和Hive做离线计算,使用Kylin做多维数据分析,使用Spark、DMLC做大规模分布式机器学习模型训练,使用theano和tensorflow做深度模型训练。</p>
</li>
<li>
<p>再往上就是应用层,我们通过对外提供rpc和http接口来实现推荐业务的接入。58同城的推荐应用大多是向用户展示一个推荐结果列表,属于topN推荐模式,这里介绍下58同城的几个重要的推荐产品:</p>
</li>
<ul>
<li>
<p>猜你喜欢:58同城最重要的推荐产品,推荐场景包括APP首页和不同品类的大类页,目标是让用户打开APP或进入大类页时可以快速找到他们想要的帖子信息,这主要根据用户的个人偏好进行推荐。</p>
</li>
<li>
<p>详情页相关推荐:用户进入帖子详情页,会向用户推荐与当前帖子相关的帖子。该场景下用户意图较明显,会采用以当前帖子信息为主用户偏好信息为辅的方式进行推荐。</p>
</li>
<li>
<p>搜索少无结果推荐:用户会通过品类列表页上的筛选项或搜索框进入品类列表页获取信息,若当前筛选项或搜索条件搜索出的结果较少或者没有结果,便会触发推荐逻辑进行信息推荐。此时会结合当前搜索条件的扩展以及用户偏好信息进行推荐。</p>
</li>
<li>
<p>个性化推送(Push):在用户打开APP前,将用户感兴趣的信息推送给他们,促使用户点击,提高用户活跃度。这里包含推送通知的生成和推送落地页上帖子列表的生成两个推荐逻辑。值得一提的是推送是强制性的推荐,会对用户形成骚扰,因此如何降低用户骚扰并给用户推荐真正感兴趣的信息尤为重要。</p>
</li>
<li>
<p>Feed流推荐:我们的推荐产品在某些推荐场景下是以Feed流的形式展现的,例如APP消息中心的今日推荐场景、推送落地页场景。用户可以在这些页面中不断下拉刷新消费信息,类似时下火热的各大资讯Feed流推荐。</p>
</li>
</ul>
</ul>
<p>推荐系统是一个复杂的工程,涉及算法策略、工程架构和效果数据评估三方面的技术,后文将分别从这三方面介绍58同城推荐系统。</p>
<p>算法</p>
<p>推荐涉及了前端页面到后台算法策略间的各个流程,我们将推荐流程抽象成如下图所示的召回、排序、规则和展示四个主要环节:</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/5c305bdea624404f9e742c4a559a21c4_th.jpg" alt=""></p>
<ul>
<li>
<p>召回环节即使用各种算法逻辑从海量的帖子中筛选出用户感兴趣的帖子候选集合,一般集合大小是几十到上百。</p>
</li>
<li>
<p>排序即对候选集合中的帖子进行打分排序,这里一般会使用机器学习排序模型,排序环节会生成一个排序列表。</p>
</li>
<li>
<p>规则环节即我们可能对排序列表采取一定的规则策略,最终生成一个包含N条结果的列表。例如在规则环节我们可能会采取不同的去重策略,如文本去重、图片去重、混合去重等,可能会采取不同的列表打散策略,可能会迭代产品经理提出的各种规则逻辑。由于推荐系统的最终评价是看统计效果,因此各种人为的规则都会影响最终结果,我们抽象出规则环节后便可以对任何逻辑做线上ABTest,最终评价相关逻辑是否合理。</p>
</li>
<li>
<p>生成N条推荐结果列表后,不同的前端展示方式也会影响最终的推荐效果,例如不同的UI设计,采用大图模式还是小图模式,页面上展示哪些字段都会影响用户在推荐列表页上的点击,因此在推荐产品迭代过程中不同的展示样式迭代也很重要。</p>
</li>
</ul>
<p>在上述的四个环节中,召回和排序是推荐系统最重要的两个环节。规则和展示样式一般变化周期较长,而召回和排序有很大的挖掘空间,会被不断的迭代,我们的推荐算法工作也主要是围绕召回和排序进行。下图是我们推荐算法的整体框架,主要包括基础数据的计算以及上层的召回策略和排序模型的迭代。</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/91bf2ae157064238952706c86f5e2473_th.jpg" alt=""></p>
<p>基础数据计算主要包括用户标签和帖子标签的挖掘,这部分工作由用户画像、搜索和推荐多个团队共同完成,最终各团队共享数据。基于用户注册时填写的基础属性信息和用户行为日志,可以挖掘出用户人口属性和兴趣偏好信息,如用户的年龄、性别、学历、收入等基础属性,用户感兴趣的地域商圈、二手房均价、厅室、装修程度等偏好信息。帖子标签挖掘包括提取帖子的固定属性、挖掘衍生属性以及计算动态属性。固定属性直接从帖子数据库提取即可,如分类、地域、标题、正文、图片、房源价格、厅室、小区等。我们还会基于贴子信息是否完备、价格是否合理、图片质量好坏、发帖人质量等多个维度来计算帖子质量分。基于用户行为日志数据可以计算帖子的PV、UV、点击率、转化率、停留时长等动态属性。这些数据最终会在召回环节和排序环节使用,例如基于用户标签和帖子标签可以进行兴趣召回,将用户标签和帖子标签作为特征迭代机器学习模型。</p>
<p>召回主要负责生成推荐的候选集,我们采用多种召回源融合的方式来完成该过程。我们先后迭代了如下各类召回策略:</p>
<ul>
<li>
<p>热门召回。基于曝光和点击日志,我们会计算不同粒度的热门数据。以二手车业务线为例,从粗粒度到细粒度的数据包括:城市下的热门商圈、商圈下的热门车系和品牌、特定车系和品牌下的热门车源等。每一个车源的热度我们通过最近一段时间内帖子的PV、UV、CTR等指标来衡量,这里的CTR会通过贝叶斯和COEC做平滑处理。热门召回策略会在冷启动时被大量采用。</p>
</li>
<li>
<p>地域召回。58同城是向用户提供本地生活服务类信息,用户的每次访问都会带上地域信息,如选择的城市、定位的地点等。我们主要结合地域信息和热门数据做召回,如附近最新或最热帖子召回、城市热门帖子召回等。</p>
</li>
<li>
<p>兴趣召回。基于帖子基础属性字段和帖子标签信息,我们构建了一套帖子检索系统,通过该系统能够以标签或属性字段检索出最新发布的帖子。在用户画像中,我们计算了每个用户的兴趣标签,因此基于用户兴趣标签便能在检索系统中检索出一批帖子,这可以作为一种召回源。此外,在帖子详情页相关推荐场景中,我们也可以利用当前帖子的属性和标签信息去检索系统中检索出相关帖子作为召回数据源。这两种检索召回其实就是我们常说的基于内容的推荐。</p>
</li>
<li>
<p>关联规则。这里并非直接采用传统Apriori、FP-growth关联规则算法,而是参考关联规则思想,将最近一段时间中每个用户点击所有物品当做一次事务,由此计算两两物品之间的支持度,并在支持度中融入时间衰减因子,最终可以得到每个物品的topK个关联性强的物品。这种召回方式其实类似协同过滤中的item相似度矩阵计算,我们主要将其应用在详情页相关推荐中。</p>
</li>
<li>
<p>协同过滤。我们使用Spark实现了基于User和基于Item的批量协同过滤计算,由于数据量大,批量计算会较消耗时间,我们又实现了基于Item的实时协同过滤算法。通常情况下我们会直接将用户的推荐结果列表作为一种召回源,而在详情页相关推荐场景,我们还会使用协同过滤计算出的Item相似度矩阵,将帖子最相似的topK个帖子也作为一种召回源。</p>
</li>
<li>
<p>矩阵分解。我们引入了SVD算法,将用户对帖子的点击、收藏、分享、微聊和电话等行为操作看作用户对帖子进行不同档次的评分,从而构建评分矩阵数据集来做推荐。</p>
</li>
<li>
<p>DNN召回。Google在YouTube视频推荐上使用了DNN来做召回,我们也正在进行相关尝试,通过DNN来学习用户向量和帖子向量,并计算用户最相近的topK个帖子做为召回源。</p>
</li>
</ul>
<p>上述不同的召回算法都产生出了一部分推荐候选数据,我们需要将不同的召回数据融合起来以提高候选集的多样性和覆盖率,这里我们主要使用两种召回融合策略:</p>
<ul>
<li>
<p>分级融合。设置一个候选集目标数量值,然后按照效果好坏的次序选择候选物品,直至满足候选集大小。假设召回算法效果好坏的顺序是A、B、C、D,则优先从A中取数据,不足候选集目标数量时则从B中取数据,依次类推。我们的系统支持分级融合策略的配置化,不同召回算法的先后顺序可以灵活配置。这里的效果好坏顺序是根据离线评价和线上评价来决定的,例如离线我们会比较不同召回算法的召回率和准确率,线上我们会比较最终点击或转化数据中不同召回算法的覆盖率。</p>
</li>
<li>
<p>调制融合。按照不同的比例分别从不同召回算法中取数据,然后叠加产生最终总的候选集。我们的系统也支持调制融合策略的配置化,选择哪些召回算法、每种召回算法的选择比例均可以灵活配置。这里的比例主要根据最终线上点击或转化数据中不同召回算法的覆盖率来设置。</p>
</li>
</ul>
<p>召回环节新召回源的添加或者新融合策略的上线,例如开发了一种新召回算法、需要修改调制融合策略中的配比等,我们都会做线上ABTest,最终通过比较不同策略的效果来指导我们的迭代。值得一提的是,召回环节我们还会有一些过滤规则,例如过滤低质量帖子、在某些特定场景下对召回算法产生的结果加一些条件限制等。</p>
<p>排序环节我们主要采用Pointwise方法,为每个帖子打分并进行排序,通过使用机器学习模型预估帖子的点击率、转化率和停留时长等多指标来做排序。早期我们主要优化点击率,目前我们不仅关注点击率外还会注重转化率的提高。在58同城的产品场景中,转化主要指用户在帖子详情页上的微聊、打电话操作。</p>
<p>排序离线流程主要包括样本生成和选择、特征抽取、模型训练和评价。首先对埋点日志中的曝光、点击、转化和停留时长等数据做抽取解析,如基于曝光序列号关联各类操作、解析埋点参数(例如日志中记录的实时特征)、解析上下文特征等,并同时打上label,生成模型样本。然后对样本进行过滤,例如过滤恶意用户样本、过滤无效曝光样本等。然后对样本做特征抽取,生成带特征的样本,我们主要从用户、帖子、发帖人和上下文四个维度做特征工程。之后,按照一定正负样本比例做采样,最终进行模型训练和评估,离线评估指标主要参考AUC,离线效果有提升后会进行ABTest上线,逐步迭代。我们先后迭代上线了如下排序策略:</p>
<ul>
<li>
<p>规则序。早期未上线机器学习模型时,对候选集中的帖子会直接使用刷新时间、统计CTR或者一些产品规则来做排序。</p>
</li>
<li>
<p>单机器学习模型。我们最早实践的是LR模型,它是线性模型,简单高效、可解释性好,但对特征工程要求较高,需要我们自己做特征组合来增强模型的非线性表达能力,早期我们使用LibLinear来训练模型,后来迁移到了Spark上。之后我们引入了XGBoost树模型,它非线性表达能力强、高效稳定,是目前开源社区里最火热的模型之一,最初我们采用单机版本训练,后期将XGBoost部署在我们的yarn集群上,使用分布式版本进行训练。同时,我们应用了FM模型,相比于LR模型它引进了特征组合,能够解决大规模稀疏数据下的特征组合问题,我们主要使用分布式FM (DiFacto,FM on Yarn)来进行模型训练。上述这些模型都是批量更新,通常是一天更新一次,为了快速捕捉用户行为的变化,我们还引入Online Learning模型,主要尝试应用FTRL方式去更新LR模型,在某些场景下获得了稳定的效果提升。</p>
</li>
<li>
<p>融合模型。类似Facebook、Kaggle的做法,我们实践了GBDT+LR和GBDT+FM的模型融合方案。首先利用XGBoost对原始特征做处理生成高阶特征,然后输入到LR和FM模型中,目前我们的点击率预估模型中效果最佳的是GBDT+LR融合模型,转化率预估模型中效果最佳的是GBDT+FM融合模型。此外,我们还会尝试将某个单指标(如点击率)下多个模型的预测结果进行融合(如相加或相乘等),也会将多个指标(点击率、转化率和停留时长)的模型进行融合(如相乘)以观察效果。</p>
</li>
<li>
<p>深度模型。深度学习正逐渐被各大公司应用于推荐系统中,我们也正在进行尝试。目前,我们已将FNN(Factorisation machine supported neuralnetwork)模型应用在我们的推荐排序中,相比单机器学习模型,FNN有较稳定的效果提升,但比融合模型效果要稍差,目前我们正在进行深度模型的调优,并在尝试引入Wide&Deep等其他深度模型。</p>
</li>
</ul>
<p>基于上述基础机器学习工具,目前我们主要会迭代点击率、转化率和停留时长预估模型,线上会ABTest上线单指标模型、多指标融合模型,以提高推荐效果。</p>
<p>架构</p>
<p>对于推荐系统来说,一套支撑算法策略高效迭代的推荐后台系统至关重要,我们基于微服务架构设计了推荐后台系统,它扩展性好、性能高,系统架构如下图所示,系统分为数据层、逻辑层和接入层,数据层提供各类基础数据的读取,逻辑层实现召回和排序策略并支持不同策略的ABTest,接入层对外提供了通用的访问接口。</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/11a11de815e24598b11747110a261512_th.jpg" alt=""></p>
<p>数据层提供推荐逻辑所需要的各类数据,这些数据存储在WRedis、文件、WTable等多种设备上,我们将所有数据的读取都封装成RPC服务,屏蔽了底层的存储细节。这里包括检索服务、召回源读取服务、帖子特征中心和用户特征中心:</p>
<ul>
<li>
<p>检索服务。我们搭建了一套搜索引擎用做召回检索,支持基于各类搜索条件去检索数据,例如可以检索出价格在200万至300万之间的回龙观两室的房源、检索出中关村附近的最新房源。该服务主要应用于这几类场景:在猜你喜欢推荐场景中基于用户标签去检索帖子、在相关推荐场景中基于当前帖子属性去检索相关帖子、冷启动时基于地域信息召回附近的帖子等。</p>
</li>
<li>
<p>召回源读取服务。提供各类召回源数据的读取,这些召回源数据通过离线或实时计算得到,包括热门数据、协同过滤数据、关联规则数据、矩阵分解结果等。该服务设计得较灵活,支持任意召回源的增加。</p>
</li>
<li>
<p>帖子特征中心。提供帖子所有属性字段的读取,在召回、排序和推荐主体逻辑中会使用到这些帖子属性,一般情况我们会在召回环节读取出所有帖子属性,然后应用于排序和规则逻辑中。召回得到的候选集大小一般是几十到几百,为了支持高性能的批量读取,我们选择使用WRedis集群存储帖子属性,并通过多线程并发读取、缓存、JVM调优等多项技术保证服务性能。目前,该服务每天承接数亿级请求,平均每次读取150条数据,耗时保证在2ms之内。</p>
</li>
<li>
<p>用户特征中心。UserProfile数据包括用户离线/实时兴趣标签、人口属性等,该数据会在召回环节使用,例如使用用户兴趣标签去检索帖子作为一种召回源,也会在排序环节使用,例如将用户标签作为机器学习排序模型的特征。</p>
</li>
</ul>
<p>逻辑层实现了详细的推荐策略,包括推荐主体服务、召回服务、排序服务和ABTest实验中心。这些服务由不同的开发人员维护,保证了推荐策略的高效迭代,例如召回和排序是我们经常迭代的环节,由不同的算法人员来完成,召回服务和排序服务的分离降低了耦合,提高了迭代效率。</p>
<ul>
<li>
<p>推荐主体服务。接收推荐请求,解析推荐场景参数,调用用户特征中心获取用户信息,请求ABTest实验中心获取对应场景的ABTest实验参数,如召回策略号、排序算法号、规则号和展示号。然后将推荐场景参数、ABTest实验参数等发送至召回服务获得候选集列表,之后再调用排序服务对候选集进行排序,最终对排序列表做相关规则处理,将结果列表封装返回。</p>
</li>
<li>
<p>召回服务。接收场景参数和召回策略号参数,调用检索服务和召回源读取服务读取各类召回数据,并进行分级融合或调制融合。我们实现了召回策略的配置化,一个召回号对应一种召回策略,策略采用哪种融合方式、每种融合方式下包含哪些召回源、不同召回源的数量均通过配置来完成。我们将召回配置进行Web化,算法或产品人员只需在Web页面上配置即可生效策略。此外,召回层还包括一些过滤规则,例如过滤低质量信息、过滤用户历史浏览记录、过滤产品指定的符合某些特定条件的数据等。</p>
</li>
<li>
<p>排序服务。接收场景参数、用户信息、候选集列表和排序算法号等参数,调用机器学习排序模块,对候选集列表做排序。我们设计了一套通用的特征提取框架,保证机器学习离线模型训练和线上排序共用相同的特征提取代码,并灵活支持不同模型之间的特征共享。在排序服务中上线一种模型成本很低,只需要提供模型文件和特征配置文件即可,后续我们将会对排序配置进行Web化,简化上线流程。目前,我们的排序服务中运行了基于LR、XGBoost、FM、XGBoost+LR、XGBoost+FM、DNN的几十个排序模型。</p>
</li>
<li>
<p>ABTest实验中心。我们设计了一套灵活通用的ABTest实验平台(内部称作“日晷”)来支持推荐系统的策略迭代,它包括流量控制、实时效果数据统计和可视化等功能,支持用户在Web页面上配置实验和流量,并能展示实时效果数据。这套实验平台不仅可以应用于推荐系统,还可以用于任何其它需要做ABTest实验的业务系统中,它支持多层ABTest实验,能充分利用每份流量去完成业务迭代。例如我们的推荐系统ABTest实验就包含召回、排序、规则和展示四层,不同层之间实现了流量的重新打散,保证了不同层之间实验的正交性。当请求到达我们的推荐系统时,推荐主体服务便请求“日晷”以获得该请求对应的召回号、排序号、规则号和展示号等实验参数,之后该请求便会被这些实验参数打上标记,贯穿于后续的推荐流程,决定每层中将走哪部分逻辑,最终这些实验参数会记录到后台和客户端埋点日志中,用于最终的实验效果统计。</p>
</li>
</ul>
<p><img src="http://img.mp.itc.cn/upload/20170717/e39258b2e33c44d2bfff6d0648aa328c_th.jpg" alt=""></p>
<p>接入层直接和客户端交互,从客户端接收请求并调用推荐主体服务获得推荐帖子id列表,然后查询出帖子详细属性返回给客户端做展示。在大部分推荐场景中,接入层由业务方维护,可能是PHP或Java实现的http接口;也有少部分场景的接入层是我们自主维护,我们采用58自研的MVC框架WF实现了相关http接口。</p>
<p>我们采用58自研的RPC框架SCF实现了上述微服务架构的推荐系统,采用58自研的监控系统WMonitor实现了推荐系统的立体监控,整个技术栈是Java。我们采用多线程、异步、缓存、JVM调优、降级、限流等措施保证了推荐系统的稳定和高可用,目前我们的推荐系统日均处理数亿的推荐请求,平均耗时约30毫秒。</p>
<p>数据</p>
<p>这里的数据主要指推荐埋点数据和推荐效果数据:埋点数据是推荐系统的基石,模型训练和效果数据统计都基于埋点数据,需保证埋点数据的正确无误;效果数据是对推荐系统的评价,指引推荐策略的迭代,构建完备的效果数据体系至关重要。</p>
<p>我们的推荐埋点日志数据包括曝光日志、点击日志、转化日志和页面停留时长日志等,这些日志数据都需要客户端通过埋点来产生。这里简单解释一下这些操作的含义:客户端请求一次推荐接口得到推荐结果列表叫做一次曝光;用户点击推荐结果列表上的某条帖子进入帖子详情页叫做一次点击;用户在帖子详情页上进行微聊、打电话、收藏等操作叫做转化;用户在帖子详情页上的阅读时间叫做页面停留时长。这里的曝光、点击和转化是一个漏斗,操作数量是逐渐递减的趋势。由于58同城上用户对帖子的访问可能来源于推荐、搜索和运营活动页等场景,为了标识出推荐产生的点击/转化/停留时长,我们需要在埋点中加入推荐相关的参数。我们将埋点参数设计成一个固定格式的字符串,它包含了曝光唯一序列号、推荐位标识、召回号、排序号、规则号、展示号、帖子id列表、帖子id等字段,这些字段将会作用于机器学习模型训练样本生成和推荐效果统计中。埋点参数主要分为列表参数和单贴参数两类:推荐接口返回一个帖子列表,会对应返回一个列表参数,包含了曝光序列号、推荐位标识、召回号、排序号、规则号、展示号、帖子id列表等字段;返回的帖子列表中,每个帖子会对应返回一个单贴参数,包含曝光序列号、推荐位标识、召回号、排序号、规则号、展示号、帖子id等字段。客户端得到推荐接口返回的埋点参数后,会将列表参数埋入到曝光日志中,将单贴参数埋入到点击日志、转化日志和停留时长日志当中,注意这里埋点时需要推荐列表页向帖子详情页传递单贴参数,一般需要通过修改跳转协议来实现。最终埋点日志中有了这些参数后,我们便可基于曝光唯一序列号将曝光、点击、转化、时长数据join起来,产生模型训练样本以及漏斗效果数据。值得一提的是,我们采取透传的方式在推荐后台、接入层、客户端间传递埋点参数字符串,所有埋点参数由推荐系统后台生成,接入层和客户端均不做任何处理。埋点参数仅由我们推荐一方负责,这样能够避免多方改动埋点参数,从而减少埋点错误的可能性,由于是透传处理,也便于今后埋点参数的扩展。</p>
<p>埋点数据是推荐系统的基石,不能有遗漏或者错误,这就要求我们严格把控开发测试流程,尤其是APP上的埋点,若发版之后发现有错误,便要等到下一次发版时解决。客户端开发和测试同事不清楚埋点参数的含义但熟练掌握测试环境部署及拥有Android和IOS测试机,而推荐后台同事清楚埋点参数含义但对测试环境较生疏并缺乏测试机,因此我们总结出了测试同事负责环境部署、推荐后台同事负责检验埋点参数的测试流程,详细流程如下图所示。此外,58同城上的APP开发比较复杂,不同产品线各自开发自己的APP业务模块,APP平台方开发主模块,每次发版前都有一个集成阶段,合并所有业务方提交的代码,产生最终的APP包,集成阶段很可能会发生业务方埋点未生效的情况。因此,我们的埋点测试包括业务方内部测试和集成测试两个阶段,以保证埋点万无一失。</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/e84e67fcf63a450b827acb6c7fe05513_th.jpg" alt=""></p>
<p>我们的推荐效果数据是一个多维数据集,我们主要关注推荐位上的点击、转化、停留时长等指标。日常工作中我们需要从不同业务线、不同客户端、不同推荐位、不同推荐算法等多个维度去分析这些指标数据,例如我们会观察房产和车在相同推荐位上的数据对比、猜你喜欢场景上不同召回或排序算法的数据对比、二手房详情页在Android和IPhone上数据对比等。各种数据分析对比能帮助我们优化推荐策略,甚至能发现某些业务线功能逻辑上的隐藏BUG,例如在我们推荐项目攻坚阶段,我们通过分析比较二手房详情页在Android和IPhone两端的推荐效果,发现了IPhone上详情页浏览回退的BUG,最终反馈给业务方并解决了该问题,该BUG的解决使得我们在二手房详情页推荐位上的推荐点击量提高了数十万。</p>
<p>我们从离线和实时两方面构建推荐效果数据,数据统计流程如下图所示:</p>
<p><img src="http://img.mp.itc.cn/upload/20170717/72934a1c238f46d18c49db69da04bf89_th.jpg" alt=""></p>
<p>早期,离线效果数据统计是通过 MapReduce + Hive + MySQL 来实现的,我们首先会编写MapReduce程序对原始埋点日志进行抽取生成Hive表,然后会编写大量的Hive SQL来统计各类指标数据,并将结果数据写入MySQL数据表,最终做可视化展示和邮件报表。由于我们比较的维度和指标多,Hive SQL语句的编写消耗了我们不少人力。在数据平台部门部署了Kylin多维分析系统后,我们将效果数据统计工作迁移到了Kylin上,我们只需要设计好Hive源数据表,并设置好维度和度量,Kylin便能根据维度和度量来自动预计算结果数据,这省去了我们编写Hive SQL的工作,大大提高了效率。关于如何利用Kylin构建多维数据集可以参考此文《基于Kylin的推荐系统效果评价系统》。</p>
<p>实时效果数据我们采用Storm + HBase 来计算,实时效果数据主要用于异常埋点监控、新上线推荐算法效果快速反馈、模型异常监控等,我们实现了一个包含较少维度的多维数据统计,今后我们将尝试引入Druid等实时多维分析系统来完善推荐实时效果数据的建设。</p>
<p>总结</p>
<p>本文介绍了58同城智能推荐系统在算法、工程和数据三方面的技术演进。我们在最近一年加快了推荐业务的迭代速度,接入了房产、车等业务线在APP、PC、M三端共计近百个推荐位,我们的推荐点击占比指标(推荐位上产生的点击量在总体点击量中的占比)相比一年之前提高了2~3倍,达到了20%~30%,每天能够产生数千万的推荐点击量,为业务线带来了流量提升。</p>
<p>任何推荐系统的发展必会经历推荐位扩充和推荐算法深入优化两个阶段,流量指标可以通过扩充推荐位来快速提高,当推荐位稳定之后,就需要依赖更加深入的算法优化来继续提高指标,而此时的效果提升也会相对缓慢。目前,我们的流量指标已相对稳定,我们会更进一层去关注转化指标,提高用户进入帖子之后与发帖人进行微聊或电话沟通的可能性,帮助用户找到真正有用的信息。</p>
<blockquote>
来源:https://www.cnblogs.com/manjianlei/p/11713949.html