听云推荐系统

本文主要介绍在博主理解下的推荐系统基本架构

背景

  博主近半年的工作重心从爬虫移到了推荐方向上,但主要是在在线层的一些逻辑代码,所以本文不会具体涉及到离线层的算法/模型等,只是从大体的角度上总结整理下本人意识形态中的推荐系统.

什么是推荐?

  推荐系统是针对用户个性化的一种猜测和建议,同时也是一个人针对某种大类类型(比如电商产品,比如听歌喜好)的事物的喜好反映,是在大量信息中,系统根据用户的历史行为,以及数据之间的相似度,自动筛选出用户可能喜欢的部分数据,去除掉大量杂质内容后的精品数据
  推荐可以是各种类型的,但从根本上来说都是基于用户的行为,是人主动行为的实际表现,所以基于各个领域都有其特定类型的推荐策略和算法,比如说电商推荐的维度可以是包括以下部分维度

1
2
3
4
5
购买过/收藏/加入购物车的物品

浏览过的物品

浏览某件物品的时长

  对于歌曲的推荐可能是

1
2
3
4
5
收藏的歌手/歌曲

听歌历史

听某首歌的时长

  以上只是简单的举了一些例子,因为可用的维度很多很多,可以对某个维度进行更进一步的细化,拿听歌来说,可以有:听歌时间超过60s的和未超过60s的… 类推其他

推荐的组成部分

  推荐分成 在线离线 两个部分,另外模块可以有 实时反馈系统(也属于在线层)

离线层

  顾名思义,就是在离线情况下的一些计算任务,主要是通过计算得到 在线层 需要使用到的基础数据,常用的有

1
2
3
4
5
6
7
8
9
1.协同过滤(ItemCF)得到的基础相似数据(基础模型)

2.基于其他高级算法模型得到的一些相似数据(其他模型)

3.用户画像/物品维度模型

4.人工分类标签下的数据

5.冷启动数据(热数据)

主要模型与策略(1 & 2)

  在这里我们将一种算法称为一个模型 – model,将多个算法的基础数据混合的方法称为策略 – strategy.
  一个策略包含一种或多种模型(算法),每个模型(算法)占用一定的权重,我们根据具体模型(算法)的权重对所有的相似数据进行重排序

  我们对于这些常用的算法,可以走混合推荐
    即对于每种模型(算法)赋予一个权重,使用这个权重去控制各个模型在一个策略(多个模型组合而成)中的重要性(权重),并应用到重新计算权重重排序上
  
  也可以直接使用ABTest分流,一个策略中只配置一个模型(算法),根据收集用户反馈的行为数据,来判断哪个模型的效果是最好的.

其他策略(2 & 3 & 4)

  用户画像是根据用户的行为所得到的用户的基本喜好信息,可以理解成网站对某个用户的定义

1
2
3
4
5
用户听云
喜欢听华语歌 -- 0.5
喜欢听英文歌 -- 0.8
喜欢听粤语歌 -- 0.2
....

  物品模型是物品在一些常见维度上的详细信息

1
2
3
4
一首歌曲的歌曲模型
语种
发行地区
....

  至于人工分类是一种更准确的数据,可以针对用户选中目标的一些推荐,但是此种方法太耗费人力,需要不断更新,一般只用作参考,适当使用
  冷启动数据的话,是根据数据本身在网站中的表现(点击数,浏览数…..等)所计算得到的热度较高的数据,一般体现了针对某个网站的大众用户的喜好,这些数据一般不算作推荐,用于补充推荐数据较少的情况
  
  一般在常规的推荐逻辑中没有足够数据时候,我们直接使用冷启动数据或者标签数据又可能会存在很不靠谱的结果,所以一般使用用户画像对这些热数据进行重排序,推测出更准确的结果返回

应用新的算法模型

  依照以上的构成部分及关系,我们可以知道应用一个新的算法模型只需要在离线任务计算好结果,定义好redis的key 和 模型的权重 等等一些公共配置文件,最后再添加在线层使用redis数据的代码逻辑,就可以比较可控地应用我们新的算法模型,效果部分的话还需要在后续的数据反馈中收集日志(用户的反馈行为日志),之后再来决定是否提高(降低)某个模型的比重,这是一个推荐的基础循环模式.

在线层

  在线层是用于处理用户请求的一套接口平台,可以理解成:封装离线数据然后吐出给用户的可执行文件,其不同的实现逻辑分摊到你提供的接口形式,举一个简单的歌曲关联歌单的推荐接口
  在线层
示例图1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
用户请求(输入):
uid = userid
songid = songid
target = songlist
count = 10

在线层(输出):
{
status:200,
num:10,
data:{
songlistid1:weight,
songlistid2:weight,
...
songlistid10:weight,
}
}

  以上可以理解为:请求接口需要的几个参数是 – 用户id,歌曲id,返回的数据类型,需要的数目
  
  在线层的作用就是:解析这些参数,并且根据传入的各种参数的组合,返回对应类型的数据结果。这里是歌曲关联歌单的推荐,比如用户“听云”昨天听过了“春风十里”这首歌,今天给“听云”推送一组可能喜欢的歌单,总数为10个.

  在线层可以分成两个部分,前端接入层,后端处理引擎

前端接入层

  这部分主要的一个目的是对用户请求接口的前置处理,比如:参数校验,封禁策略,理由配置,缓存处理,降级处理….
  这里相当于置放在nginx中的一个前端项目,nginx可以很友好的进行一些黑白名单的配置,路由配置,日志记录,以及负载均衡的配置。而如果说在后端处理引擎中去处理这些逻辑,那将会是一件特别麻烦的事情

1
2
3
4
5
1.语言实现上难度较高(底层语言),容易出错,维护代价大 

2.修改一些配置文件或者前端展示位置,需要重新编译整个程序,上线效率低

3.由于是黑盒测试,测试的难度都会变得格外地大

  但是把这部分工作放到前端接入层那就会变得特别简单,通常写这种功能的高级语言(php/python等)都支持热加载 – 也就是修改即生效,对于前端逻辑调试和格式化结果操作等等,都是很高效的.

后端推荐引擎

  这部分是我们需要核心关注的部分,也是大部分开发工作所在,以下把整个逻辑梳理下

1
2
3
4
5
1.首先,我们的请求(推荐api)到达前端接入层,经过解析/校验之后

2.丢入连接池,将必要的参数(如:userid,songid,return data type,need count)封装在某一个连接中,设定超时时间(及重试次数)

3.发送给推荐引擎

  等待推荐引擎解析参数读取配置的模型我们编写的在线处理逻辑,将数据返回
  
  由于这部分逻辑涉及到具体的推荐逻辑的实现,需要针对具体的业务才能说明。但总的来说就是你自定义想要如何推出相关的数据,如:歌曲 推荐 歌单,根据哪些基础算法,还有如何与用户的喜好信息结合起来等等,完成一次推荐.

实时反馈系统

  这部分内容比较简单,主要就是在开发阶段需要和在线层约定好的一些缓存key的使用(redis key值),但是涉及到和前端开发人员的日志上报规则约定,简单的举例

1
2
3
4
5
6
前端实时上报到日志系统

实施系统制定好相关的redis key值,采集上报的日志,解析日志,实时更新到缓存中,以供在线层使用

根据用户的具体行为,在在线层中编写好对应的处理逻辑,如:
根据用户的实时(歌单)点击(click_songlistid_userid),过滤掉已经推荐过的歌单内容

常规逻辑如下图
示例图1

  注:实时系统是一个单独维护的系统,它关心的只有日志上报格式 以及 redis key的写入

End

  以上整理难免会有纰漏,若您发现任何问题,希望您抽空邮件给我,我会尽快修改完善这些内容,谢谢!