推荐系统入门介绍

转载自:算法

https://mp.weixin.qq.com/s/d6bCGT8B4h5pfI77TvLicA缓存


这篇文章属于推荐系统的入门篇,本文暂不考虑线上环境的海量数据,目的是了解清楚推荐系统的基本构成,我会经过图解推荐算法以及程序demo的形式展开,内容包括:微信


image.png

01 走进推荐系统的世界
架构

“啤酒与尿布” 的故事相信不少人都听过,年轻爸爸去超市购买尿布时,常常会买点啤酒犒劳本身。所以,沃尔玛将这两种商品进行了捆绑销售,最终得到了更好的销量。

image.png

“啤酒与尿布”的故事 这个故事背后的理论依据就是 “推荐算法”, 由于尿布和啤酒常常出如今同一个购物车中,那么向购买尿布的年轻爸爸推荐啤酒确实有必定道理。

1. 推荐系统到底解决的是什么问题?并发

推荐系统从20世纪90年代就被提出来了,可是真正进入大众视野以及在各大互联网公司中流行起来,仍是最近几年的事情。app

随着移动互联网的发展,愈来愈多的信息开始在互联网上传播,产生了严重的信息过载。所以,如何从众多信息中找到用户感兴趣的信息,这个即是推荐系统的价值。精准推荐解决了用户痛点,提高了用户体验,最终便能留住用户。机器学习

推荐系统本质上就是一个信息过滤系统,一般分为:召回、排序、重排序这3个环节,每一个环节逐层过滤,最终从海量的物料库中筛选出几十个用户可能感兴趣的物品推荐给用户。
ide

image.png

推荐系统的分阶段过滤流程高并发

2. 推荐系统的应用场景

哪里有海量信息,哪里就有推荐系统,咱们天天最经常使用的APP都涉及到推荐功能:性能

  • 资讯类:今日头条、腾讯新闻等
  • 电商类:淘宝、京东、拼多多、亚马逊等
  • 娱乐类:抖音、快手、爱奇艺等
  • 生活服务类:美团、大众点评、携程等
  • 社交类:微信、陌陌、脉脉等

image.png

头条、京东、网易云音乐中的推荐功能

推荐系统的应用场景一般分为如下两类:

  • 基于用户维度的推荐:根据用户的历史行为和兴趣进行推荐,好比淘宝首页的猜你喜欢、抖音的首页推荐等。
  • 基于物品维度的推荐:根据用户当前浏览的标的物进行推荐,好比打开京东APP的商品详情页,会推荐和主商品相关的商品给你。

3. 搜索、推荐、广告三者的异同

搜索和推荐是AI算法最多见的两个应用场景,在技术上有相通的地方。这里提到广告,主要考虑不少没作过广告业务的同窗不清楚为何广告和搜索、推荐会有关系,因此作下解释。

  • 搜索:有明确的搜索意图,搜索出来的结果和用户的搜索词相关。
  • 推荐:不具备目的性,依赖用户的历史行为和画像数据进行个性化推荐。

  • 广告:借助搜索和推荐技术实现广告的精准投放,能够将广告理解成搜索推荐的一种应用场景,技术方案更复杂,涉及到智能预算控制、广告竞价等。

02 推荐系统的总体架构

image.png

推荐系统的总体架构

上面是推荐系统的总体架构图,自下而上分红了多层,各层的主要做用以下:

  • 数据源:推荐算法所依赖的各类数据源,包括物品数据、用户数据、行为日志、其余可利用的业务数据、甚至公司外部的数据。
  • 计算平台:负责对底层的各类异构数据进行清洗、加工,离线计算和实时计算。

  • 数据存储层:存储计算平台处理后的数据,根据须要可落地到不一样的存储系统中,好比Redis中能够存储用户特征和用户画像数据,ES中能够用来索引物品数据,Faiss中能够存储用户或者物品的embedding向量等。

  • 召回层:包括各类推荐策略或者算法,好比经典的协同过滤,基于内容的召回,基于向量的召回,用于托底的热门推荐等。为了应对线上高并发的流量,召回结果一般会预计算好,创建好倒排索引后存入缓存中。

  • 融合过滤层:触发多路召回,因为召回层的每一个召回源都会返回一个候选集,所以这一层须要进行融合和过滤。

  • 排序层:利用机器学习或者深度学习模型,以及更丰富的特征进行重排序,筛选出更小、更精准的推荐集合返回给上层业务。

从数据存储层到召回层、再到融合过滤层和排序层,候选集逐层减小,可是精准性要求愈来愈高,所以也带来了计算复杂度的逐层增长,这个即是推荐系统的最大挑战。 其实对于推荐引擎来讲,最核心的部分主要是两块:特征和算法。

image.png

推荐引擎的核心功能和技术方案

特征计算因为数据量大,一般采用大数据的离线和实时处理技术,像Spark、Flink等,而后将计算结果保存在Redis或者其余存储系统中(好比HBase、MongoDB或者ES),供召回和排序模块使用。 召回算法的做用是:从海量数据中快速获取一批候选数据,要求是快和尽量的准。这一层一般有丰富的策略和算法,用来确保多样性,为了更好的推荐效果,某些算法也会作成近实时的。 排序算法的做用是:对多路召回的候选集进行精细化排序。它会利用物品、用户以及它们之间的交叉特征,而后经过复杂的机器学习或者深度学习模型进行打分排序,这一层的特色是计算复杂可是结果更精准。

03 图解经典的协同过滤算法

了解了推荐系统的总体架构和技术方案后,下面带你们深刻一下算法细节。这里选择图解的是推荐系统中的明星算法:协同过滤(Collaborative Filtering,CF)。 对于工程同窗来讲,可能以为 AI 算法晦涩难懂,门槛过高,确实不少深度学习算法的确是这样,可是协同过滤倒是一个简单同时效果很好的算法,只要你有初中数学的基础就能看懂。

1. 协同过滤是什么?

协同过滤算法的核心就是找类似,它基于用户的历史行为(浏览、收藏、评论等),去发现用户对物品的喜爱,并对喜爱进行度量和打分,最终筛选出推荐集合。它又包括两个分支:

  • 基于用户的协同过滤:User-CF,核心是找类似的人。好比下图中,用户 A 和用户 C 都购买过物品 a 和物品 b,那么能够认为 A 和 C 是类似的,由于他们共同喜欢的物品多。这样,就能够将用户 A 购买过的物品 d 推荐给用户 C

image.png

基于用户的协同过滤示例

  • 基于物品的协同过滤:Item-CF,核心是找类似的物品。好比下图中,物品 a 和物品 b 同时被用户 A,B,C 购买了,那么物品 a 和 物品 b 被认为是类似的,由于它们的共现次数很高。这样,若是用户 D 购买了物品 a,则能够将和物品 a 最类似的物品 b 推荐给用户 D。

image.png 基于物品的协同过滤 示例 2. 如何找类似?

前面讲到,协同过滤的核心就是找类似,User-CF是找用户之间的类似,Item-CF是找物品之间的类似,那到底如何衡量两个用户或者物品之间的类似性呢?

咱们都知道,对于坐标中的两个点,若是它们之间的夹角越小,这两个点越类似,这就是初中学过的余弦距离,它的计算公式以下:

image.png

举个例子,A坐标是(0,3,1),B坐标是(4,3,0),那么这两个点的余弦距离是0.569,余弦距离越接近1,表示它们越类似。

image.png

除了余弦距离,衡量类似性的方法还有不少种,好比:欧式距离、皮尔逊相关系数、Jaccard 类似系数等等,这里不作展开,只是计算公式上的差别而已。 3. Item-CF的算法流程

清楚了类似性的定义后,下面以Item-CF为例,详细说下这个算法究竟是如何选出推荐物品的?

第一步:整理物品的共现矩阵

假设有 A、B、C、D、E 5个用户,其中用户 A 喜欢物品 a、b、c,用户 B 喜欢物品 a、b等等。

image.png

所谓共现,即:两个物品被同一个用户喜欢了。好比物品 a 和 b,因为他们同时被用户 A、B、C 喜欢,因此 a 和 b 的共现次数是3,采用这种统计方法就能够快速构建出共现矩阵。


第二步:计算物品的类似度矩阵

对于 Item-CF 算法来讲,通常不采用前面提到的余弦距离来衡量物品的类似度,而是采用下面的公式

image.png

其中,N(u) 表示喜欢物品 u 的用户数,N(v) 表示喜欢物品 v 的用户数,二者的交集表示同时喜欢物品 u 和物品 v 的用户数。很显然,若是两个物品同时被不少人喜欢,那么这两个物品越类似。

基于第1步计算出来的共现矩阵以及每一个物品的喜欢人数,即可以构造出物品的类似度矩阵:

image.png

第三步:推荐物品
最后一步,即可以基于类似度矩阵推荐物品了,公式以下:

image.png

其中,P uj 表示用户 u 对物品 j 的感兴趣程度,值越大,越值得被推荐。N(u) 表示用户 u 感兴趣的物品集合,S(j,N) 表示和物品 j 最类似的前 N 个物品,W ij 表示物品 i 和物品 j 的类似度,R ui  表示用户 u 对物品 i 的兴趣度。

上面的公式有点抽象,直接看例子更容易理解,假设我要给用户 E 推荐物品,前面咱们已经知道用户 E 喜欢物品 b 和物品 c,喜欢程度假设分别为 0.6 和 0.4。那么,利用上面的公式计算出来的推荐结果以下:

image.png

由于物品 b 和物品 c 已经被用户 E 喜欢过了,因此再也不重复推荐。最终对比用户 E 对物品 a 和物品 d 的 感兴 趣程度,由于 0.682 > 0.3,所以选择推荐物品 a。

04 从0到1搭建一个推荐系统

有了上面的理论基础后,咱们就能够用 Python 快速实现出一个推荐系统。

1. 选择数据集

这里采用的是推荐领域很是经典的 MovieLens 数据集,它是一个关于电影评分的数据集,官网上提供了多个不一样大小的版本,下面以 ml-1m 数据集(大约100万条用户评分记录)为例。

下载解压后,文件夹中包含:ratings.dat、movies.dat、users.dat 3个文件,共6040个用户,3900部电影,1000209条评分记录。各个文件的格式都是同样的,每行表示一条记录,字段之间采用 :: 进行分割。

以ratings.dat为例,每一行包括4个属性: UserID, MovieID, Rating, Timestamp。 经过脚本能够统计出不一样评分的人数分布:

image.png

2. 读取原始数据

程序主要使用数据集中的 ratings.dat 这个文件,经过解析该文件,抽取出 user_id、movie_id、rating 3个字段,最终构造出算法依赖的数据,并保存在变量 dataset 中,它的格式为:dict[user_id][movie_id] = rate

图片

3. 构造物品的类似度矩阵

基于第 2 步的 dataset,能够进一步统计出每部电影的评分次数以及电影的共生矩阵,而后再生成类似度矩阵。

图片

4. 基于类似度矩阵推荐物品

最后,能够基于类似度矩阵进行推荐了,输入一个用户id,先针对该用户评分过的电影,依次选出 top 10 最类似的电影,而后加权求和后计算出每一个候选电影的最终评分,最后再选择得分前 5 的电影进行推荐

图片

5. 调用推荐系统

下面选择 UserId=1 这个用户,看下程序的执行结果。因为推荐程序输出的是 movieId 列表,为了更直观的了解推荐结果,这里转换成电影的标题进行输出。

图片

最终推荐的前5个电影为:

图片

05 线上推荐系统的挑战

经过上面的介绍,你们对推荐系统的基本构成应该有了一个初步认识,可是真正运用到线上真实环境时,还会遇到不少算法和工程上的挑战,绝对不是几十行 Python 代码能够搞定的。

一、上面的示例使用了标准化的数据集,而线上环境的数据是非标准化的,所以涉及到海量数据的收集、清洗和加工,最终构造出模型可以使用的数据集。

二、复杂且繁琐的特征工程,都说算法模型的上限由数据和特征决定。对于线上环境,须要从业务角度选择出可用的特征,而后对数据进行清洗、标准化、归一化、离散化,并经过实验效果进一步验证特征的有效性。

三、算法复杂度如何下降?好比上面介绍的Item-CF算法,时间和空间复杂度都是O(N×N),而线上环境的数据都是千万甚至上亿级别的,若是不作算法优化,可能几天都跑不出数据,或者内存中根本放不下如此大的矩阵数据。

四、实时性如何知足?由于用户的兴趣随着他们最新的行为在实时变化的,若是模型只是基于历史数据进行推荐,可能结果不够精准。所以,如何知足实时性要求,以及对于新加入的物品或者用户该如何推荐,都是要解决的问题。

五、算法效果和性能的权衡。从算法角度追求多样性和准确性,从工程角度追求性能,这二者之间必须找到一个平衡点。

六、推荐系统的稳定性和效果追踪。须要有一套完善的数据监控和应用监控体系,同时有 ABTest 平台进行灰度实验,进行效果对比。

相关文章
相关标签/搜索