推荐系统架构(转)

1、推荐系统目标和推荐方式

  推荐系统目标主要包括: 面试

  • 用户满意性:首当其冲的,推荐系统主要就是为了知足用户的需求,所以准确率是评判一个推荐系统好坏的最关键指标。
  • 多样性:虽然推荐系统最主要仍是知足用户的兴趣,可是也要兼顾内容的多样性,对于权重不一样的兴趣都要作到兼顾。
  • 新颖性:用户看到的内容是那些他们以前没有据说过的物品。简单的作法就是在推荐列表去掉用户以前有过行为的那些内容。
  • 惊喜度:和新颖性相似,但新颖性只是用户没看到过的可是确实是和他行为是相关的,而惊喜度是用户既没有看过和他以前的行为也不相关,但用户看到后的确是喜欢的。
  • 实时性:推荐系统要根据用户的上下文来实时更新推荐内容,用户的兴趣也是随着时间而改变的,须要实时更新。
  • 推荐透明度:对于用户看到的最终结果,要让用户知道推荐此内容的缘由。好比,“买过这本书的人同时也买过”、”你购买过的xx和此商品相似”。
  • 覆盖率:挖掘长尾内容也是推荐系统很重要的目标。所以,推荐的内容覆盖到的内容越多越好。

  基于这些目标,推荐系统包括四种推荐方式:算法

  • 热门推荐:就是热门排行榜的概念。这种推荐方式不只仅在IT系统,在日常的生活中也是到处存在的。这应该是效果最好的一种推荐方式,毕竟热门推荐的物品都是位于曝光量比较高的位置的。
  • 人工推荐:人工干预的推荐内容。相比于依赖热门和算法来进行推荐。一些热点时事如世界杯、nba总决赛等就须要人工加入推荐列表。另外一方面,热点新闻带来的推荐效果也是很高的。
  • 相关推荐:相关推荐有点相似于关联规则的个性化推荐,就是在你阅读一个内容的时候,会提示你阅读与此相关的内容。
  • 个性化推荐:基于用户的历史行为作出的内容推荐。也是本文主要讲述的内容。

  其中,前三者是和机器学习没有任何关系的,但倒是推荐效果最好的三种方式。通常说来,这部份内容应该占到总的推荐内容的80%左右,另外20%则是对长尾内容的个性化推荐。sql

2、推荐系统架构

         

 

online部分架构

      

  核心模块

  • 业务网关,推荐服务的入口,负责推荐请求的合法性检查,组装请求响应的结果。数据库

  • 推荐引擎,推荐系统核心,包括online逻辑,召回、过滤、特征计算、排序、 多样化等处理过程。网络

  数据路径

  一、请求的刷新从gateway,通过流量分配模块,传到业务gateway,业务gateway支持http,tcp(使用thirtf协议或者protobuf 协议)等多种类型接口;session

  二、用户行为数据,从gateway到Flume agent,而后到kafka,为后面online,realtime userprofile部分的提供实时数据,也为offline部分的数据存储系统提供数据。架构

  流量分配

  这部分包括流量分配和ABTest两个模块,流量分配模块主要是根据需求来动态进行流量的分配,须要作到线上实时修改实时响应;ABTest是为Web和App的页面或流程设计两个版本(A/B)或多个版本(A/B/n),同时随机的分别让必定比例的客户访问,而后经过统计学方法进行分析,比较各版本对于给定目标的转化效果。大家可能以为这两个模块功能有些冗余,其实并不是如此,有一些单纯营运的需求是不须要进ABTest的。以视频推荐为例解释一下 这个问题,假设营运有这样的需求:“他们根据数据发现,iOS用户观看视频更喜欢购买会员进行免除广告,Andriod用户更倾向于观看网剧”(固然这只是一种假设),因此iOS在进行流量分配的时候会把付费视频比例提升,而Andriod会把原创网剧比例提升。而后新的一种算法或者UI但愿知道是否会表现更好,这种状况就须要进行ABTest了,对照组和实验组里面iOS和Android都是包含的。负载均衡

  推荐引擎

  推荐引擎主要就包括,gateway,recall(match),ranking,其中reall主要offline经过各类算法,最经典的就是基于用户行为的矩阵分解,包括itemCF、userCF、ALS,还有基于深度学习的wise&&deep等方法,后面讲offline的时候会着重说各类算法如何使用和适合的场景。框架

  如今咱们就默认为,各类算法已经训练完毕,而后会生成一些二进制文件,以下图,这些就是offline算法收敛后的权重向量结果机器学习

      

  文件格式都是二进制,打开咱们也看不懂,这里就不打开了,若是有人好奇能够私信我。这些产生后,如何到线上使用呢?用最土的办法,经过脚本天天定时cp到线上的server。也能够经过sql或者nosql数据库等方法,可是这个文件通常比较大,图里展现的只是我其中一个实验,日活大约百万级用户的训练结果数据,若是后面用户更多,item更丰富这个文件也就越大,使用数据库是否是好方式有待商榷。

gateway

  这个模块只要负责用户请求的处理,主要功能包括请求参数检查,参数解析,结果组装返回。gateway业务比较轻量级,其中只有一个问题就是“假曝光”,假曝光是相对真曝光而言的,真曝光是指推送给用户的内容且用户看到了,假曝光就是指,推送给用户,可是未向用户展现的内容。推荐系统为了不重复推荐,因此基于UUID存储推荐历史,存储时间是几小时,或者1天,再或几天,这个须要根据各自的业务状况,也要考虑资源库的大小。假曝光的处理能够在gateway中,把推送的message_id在gateway写入到nosql中,而后根据真曝光数据在离线pipeline中能够获取到,在离线pipeline定时运行时把假曝光的message_id的数据归还到recall队列中。

recall

  用户请求到recall引擎后,会根据用户行为和相关配置,启动不一样的召回器,下发召回任务,用户行为只要是看是否为新用户进冷启动,相关配置可能就是地区,国家等差别。用户的userprofile若是少于几个行为,通常建议为5-10个点击行为,少于这个标准属于冷启动用户,那么在recall manager的队列里只有冷启动召回器和热门召回器。热门召回器是为了保证推荐内容的热门度,而冷启动召回器是保证推荐结果的新鲜度。recall引擎还要负责任务分配,根据推荐场景,按召回源进行任务拆分,关键是让分布式任务到达负载均衡。

  在各个召回器返回后recall manager收集返回结果,也就是各个召回器的返回的message_id的倒排队列,而后再进行一次总体的ranking。

        

  下面再展开介绍一下召回器内部框架

         

  • 召回阶段,获取候选集,通常从基于用户画像、用户偏好、热门label等维度进行召回,若是是用户画像中点击少于10个会使用冷启动服务进行召回;

  • 过滤阶段,基于人工规则,和政策规则,避免涉黄,避免政治明感等内容,例如最近的未成年孕妇等进行过滤,总之计算保留合法的,合乎运营须要的结果;

  • 特征计算阶段,结合用户实时行为、用户画像、知识图谱,计算出召回的候选集的特征向量;

  • 排序阶段,使用算法模型对召回候选集进行粗排序,由于通常用户请求10条数据,召回样本大概在200-400个因此在召回器的排序内会进行序列从新调整,而后整体ranking时会选取粗排序的前100或前200结果,并不是召回结果都是用,避免没必要要的计算,增长响应时间。

  在召回、排序阶段都是基于message_id,并无包含文章内容或是视频信息,这些内容会在ranking后,在detial服务中对推荐的返回结果的进行拼装,detail服务后还会有一层对总体结果的调整服务即tuner。

  offline部分架构

  本文从大框架上介绍推荐系统架构,在许多公司面试中会给你一个推荐或者数据挖掘的问题,好比让你简单设计一个feed流推荐系统,因此须要对推荐系统的总体框架要了解。下面是一个推荐系统的主要部分

           

  从框架的角度看,推荐系统基本能够分为数据层、召回层、排序层。

  数据层包括数据生成和数据存储,主要是利用各类数据处理工具对原始日志进行清洗,处理成格式化的数据,落地到不一样类型的存储系统中,供下游的算法和模型使用。

  • sessionlog:对原始数据进行清洗合并,sessionlog通常就是清洗合并后的数据,后续的算法和统计都是根据sessionlog进行再加工。
  • userprofile:对用户属性和行为等信息进行采集和统计,为后续算法提供特征支持。
  • itemDoc:对视频、商品等属性、曝光、点击等字段进行统计, 为后续算法提供特征支持。

  召回层主要是从用户的历史行为、实时行为等角度利用各类触发策略产生推荐的候选集,对不一样的策略和算法产生的候选集进行融合并按照产品规则进行过滤,通常融合和过滤后的候选集仍是比较多的,一次线上请求过来以后线上系统没法对那么多的候选集进行排序,因此在召回层通常还会有粗排序,对融合的候选集进行一次粗排序,过滤掉粗排分数较低的候选集。

  排序层主要是利用机器学习的模型对召回层筛选出来的候选集进行精排序。

数据特征

  数据决定了特征,特征决定了效果的上限,模型决定了接近效果上限的程度。

行为类别

行为表现

用户主动行为

点击、分享、评分

用户画像

用户属性(性别、年龄、收入)、视频分类兴趣分布、地域、时间

负反馈

负评

  1. 用户主动行为数据记录了用户在平台的的各类行为,这些行为一方面用于候选集触发算法中的离线计算(主要是浏览、下单),另一方面,这些行为表明的意图的强弱不一样,所以在训练重排序模型时能够针对不一样的行为设定不一样的回归目标值,以更细地刻画用户的行为强弱程度。此外,用户对deal的这些行为还能够做为重排序模型的交叉特征,用于模型的离线训练和在线预测。
  2. 负反馈数据反映了当前的结果可能在某些方面不能知足用户的需求,所以在后续的候选集触发过程当中须要考虑对特定的因素进行过滤或者降权,下降负面因素再次出现的概率,提升用户体验;同时在重排序的模型训练中,负反馈数据能够做为不可多得的负例参与模型训练,这些负例要比那些展现后未点击、未下单的样本显著的多。
  3. 用户画像是刻画用户属性的基础数据,其中有些是直接获取的原始数据,有些是通过挖掘的二次加工数据,好比用户的聚类和向量化,这些属性一方面能够用于候选集触发过程当中对deal进行加权或降权,另一方面能够做为重排序模型中的用户维度特征。

召回层(ReCall)

协同过滤

  协同过滤(Collaborative Filtering)可说是推荐系统里资历最老最经典的一种算法了,如 userCF、itemCF。原理是基于用户对内容的行为协同,为某一用户没有看过的某条内容做出点击预测。实现方法有不少种,如传统的 Memory-based 方法、基于矩阵分解的方法(LFM/SVD/SDV++)、基于 DNN 的方法。

  Memory-based 方法很简单,是基于统计的一种算法。以 item-based CF 举例:

         

  根据用户点击行为,咱们能够统计出 item-item 的共现矩阵(矩阵单元内为 item i 与 item j 共同被用户点击的次数),再依此经过Jaccard类似度/余弦类似度/欧氏距离得出 item 类似度矩阵,最后根据用户的点击记录检索出 topK 类似的内容推荐给用户。在计算过程当中须要考虑一些因素,好比热门物品对类似度计算的影响、不一样倾向的用户的影响等等。

  然而 Memory-based 方法不能解决的问题是,当咱们的矩阵很稀疏时,大多数 item 和 item 之间是没有关联的(类似度为0),这也就形成最后咱们召回的内容覆盖率很低,也许大多集中在头部内容。因而基于矩阵分解的方法诞生了。

MF(Matrix Factorization)的原理是将一个高维稀疏矩阵分解成两个低秩矩阵,其中 k 被称为隐向量维度。在原始的稀疏矩阵 R 中,大部分二阶特征的关系系数是缺失的。而经过训练模型最小化 R 和预测矩阵 R‘ 的损失(如最小二乘),能够求出任意 Ri,j 的值。

    

  MF 可说是大部分推荐系统里协同过滤的标杆方法了,但仍然存在一些问题。好比过于稀疏的矩阵对于最后评分的预测依然有很大影响,而且当用户特征或者内容特征缺失(即冷启动)时,没法进行合理的预测。此时,基于深度学习的一些尝试开始了。如基于DNN实现,能够很轻易地将内容的一些语义特征,以及用户的固有属性与行为特征拼接在一块儿做为神经网络输入来训练,能够在以前行为协同的前提下加入对内容特征的学习,从而解决冷启动问题。

基于内容的召回

  主要是以以前 NLP 获得的内容画像为基础,以item 对应分类/主题/关键词的权重创建召回,依据用户画像的相应权重和内容画像的距离排序召回。

  基于用户群

  首先咱们须要对用户分群,聚类的方案有不少,

    一、对item进行向量化(w2v)而后对item进行聚类,用户对item的行为就能够把item的簇赋值到user身上。

    二、直接对用户进行向量化,好比降维。

  总之最终的目的就是将用户embedding成一个向量,而后在对用户向量进行聚类,通常k-means就能够胜任大部分的场景。

倒排链

  tag-itemList,对每一个用户的tag进行遍历,而后经过倒排链快速找到含有该tag的itemList而后topN抽取。

子策略融合

  为告终合不一样触发算法的优势,同时提升候选集的多样性和覆盖率,须要将不一样的触发算法融合在一块儿。常见的融合的方法有如下几种:

    • 加权型:最简单的融合方法就是根据经验值对不一样算法赋给不一样的权重,对各个算法产生的候选集按照给定的权重进行加权,而后再按照权重排序。
    • 分级型:优先采用效果好的算法,当产生的候选集大小不足以知足目标值时,再使用效果次好的算法,依此类推。
    • 调制型:不一样的算法按照不一样的比例产生必定量的候选集,而后叠加产生最终总的候选集。
    • 过滤型:当前的算法对前一级算法产生的候选集进行过滤,依此类推,候选集被逐级过滤,最终产生一个小而精的候选集合。

  目前咱们使用的方法集成了调制和分级两种融合方法,不一样的算法根据历史效果表现给定不一样的候选集构成比例,同时优先采用效果好的算法触发,若是候选集不够大,再采用效果次之的算法触发,依此类推。

模型排序(Ranking)

       如上所述,对于不一样算法触发出来的候选集,只是根据算法的历史效果决定算法产生的item的位置显得有些简单粗暴,同时,在每一个算法的内部,不一样item的顺序也只是简单的由一个或者几个因素决定,这些排序的方法只能用于第一步的初选过程,最终的排序结果须要借助机器学习的方法,使用相关的排序模型,综合多方面的因素来肯定。

一、模型选择和比较  

  非线性模型能较好的捕捉特征中的非线性关系,但训练和预测的代价相对线性模型要高一些,这也致使了非线性模型的更新周期相对要长。反之,线性模型对特征的处理要求比较高,须要凭借领域知识和经验人工对特征作一些先期处理,但由于线性模型简单,在训练和预测时效率较高。所以在更新周期上也能够作的更短,还能够结合业务作一些在线学习的尝试。在咱们的实践中,非线性模型和线性模型都有应用。

非线性模型  

       目前咱们主要采用了非线性的树模型gbdt,相对于线性模型,非线性模型能够更好的处理特征中的非线性关系,没必要像线性模型那样在特征处理和特征组合上花费比较大的精力。gbdt是一个加性模型,由不少个树组成,后面的树不断拟合前一颗树的残差,并且每个树带入的都是全训练集,由此能够减少过拟合的影响。

      

线性模型

  目前应用比较多的线性模型非Logistic Regression莫属了。为了能实时捕捉数据分布的变化,咱们引入了online learning,接入实时数据流,使用google提出的FTRL[5]方法对模型进行在线更新。后续也会单独写一篇FTRL的应用、特征、落地、面试问点等细节。


      

主要的步骤以下:

  • 在线写特征向量到HBase
  • Storm解析实时点击和曝光日志流,改写HBase中对应特征向量的label
  • 经过FTRL更新模型权重
  • 将新的模型参数应用于线上

2. 数据

  • 采样:对于点击率预估而言,正负样本严重不均衡,因此须要对负例作一些采样。 
  • 负例:正例通常是用户产生点击、下载、分享等转换行为的样本,可是用户没有转换行为的样本是否就必定是负例呢?其实否则,不少展示其实用户根本没有看到,因此把这样样本视为负例是不合理的,也会影响模型的效果。比较经常使用的方法是skip-above,即用户点击的item位置以上的展示才可能视做负例。固然,上面的负例都是隐式的负反馈数据,除此以外,咱们还有用户主动删除的显示负反馈数据,这些数据是高质量的负例。
  • 去噪:对于数据中混杂的刷单等类做弊行为的数据,要将其排除出训练数据,不然会直接影响模型的效果。

3. 特征

  在目前的重排序模型中,大概分为如下几类特征:

  • item维度的特征:主要是item自己的一些属性,包括category、pv、ctr、sub-category、tag等
  • user维度的特征:包括用户等级、用户的人口属性、用户的客户端类型等
  • user、deal的交叉特征:包括用户对item的category的点击、收藏等

  对于非线性模型,上述特征能够直接使用;而对于线性模型,则须要对特征值作一些分桶、归一化等处理,使特征值成为0~1之间的连续值或01二值。

相关文章
相关标签/搜索