转载自:算法
https://mp.weixin.qq.com/s/d6bCGT8B4h5pfI77TvLicA缓存
这篇文章属于推荐系统的入门篇,本文暂不考虑线上环境的海量数据,目的是先了解清楚推荐系统的基本构成,我会经过图解推荐算法以及程序demo的形式展开,内容包括:微信
01 走进推荐系统的世界
架构
1. 推荐系统到底解决的是什么问题?并发
推荐系统从20世纪90年代就被提出来了,可是真正进入大众视野以及在各大互联网公司中流行起来,仍是最近几年的事情。app
随着移动互联网的发展,愈来愈多的信息开始在互联网上传播,产生了严重的信息过载。所以,如何从众多信息中找到用户感兴趣的信息,这个即是推荐系统的价值。精准推荐解决了用户痛点,提高了用户体验,最终便能留住用户。机器学习
推荐系统本质上就是一个信息过滤系统,一般分为:召回、排序、重排序这3个环节,每一个环节逐层过滤,最终从海量的物料库中筛选出几十个用户可能感兴趣的物品推荐给用户。
ide
推荐系统的分阶段过滤流程高并发
2. 推荐系统的应用场景哪里有海量信息,哪里就有推荐系统,咱们天天最经常使用的APP都涉及到推荐功能:性能
头条、京东、网易云音乐中的推荐功能
推荐系统的应用场景一般分为如下两类:
基于物品维度的推荐:根据用户当前浏览的标的物进行推荐,好比打开京东APP的商品详情页,会推荐和主商品相关的商品给你。
搜索和推荐是AI算法最多见的两个应用场景,在技术上有相通的地方。这里提到广告,主要考虑不少没作过广告业务的同窗不清楚为何广告和搜索、推荐会有关系,因此作下解释。
推荐:不具备目的性,依赖用户的历史行为和画像数据进行个性化推荐。
广告:借助搜索和推荐技术实现广告的精准投放,能够将广告理解成搜索推荐的一种应用场景,技术方案更复杂,涉及到智能预算控制、广告竞价等。
02 推荐系统的总体架构
推荐系统的总体架构
计算平台:负责对底层的各类异构数据进行清洗、加工,离线计算和实时计算。
数据存储层:存储计算平台处理后的数据,根据须要可落地到不一样的存储系统中,好比Redis中能够存储用户特征和用户画像数据,ES中能够用来索引物品数据,Faiss中能够存储用户或者物品的embedding向量等。
召回层:包括各类推荐策略或者算法,好比经典的协同过滤,基于内容的召回,基于向量的召回,用于托底的热门推荐等。为了应对线上高并发的流量,召回结果一般会预计算好,创建好倒排索引后存入缓存中。
融合过滤层:触发多路召回,因为召回层的每一个召回源都会返回一个候选集,所以这一层须要进行融合和过滤。
排序层:利用机器学习或者深度学习模型,以及更丰富的特征进行重排序,筛选出更小、更精准的推荐集合返回给上层业务。
推荐引擎的核心功能和技术方案
特征计算因为数据量大,一般采用大数据的离线和实时处理技术,像Spark、Flink等,而后将计算结果保存在Redis或者其余存储系统中(好比HBase、MongoDB或者ES),供召回和排序模块使用。 召回算法的做用是:从海量数据中快速获取一批候选数据,要求是快和尽量的准。这一层一般有丰富的策略和算法,用来确保多样性,为了更好的推荐效果,某些算法也会作成近实时的。 排序算法的做用是:对多路召回的候选集进行精细化排序。它会利用物品、用户以及它们之间的交叉特征,而后经过复杂的机器学习或者深度学习模型进行打分排序,这一层的特色是计算复杂可是结果更精准。03 图解经典的协同过滤算法
了解了推荐系统的总体架构和技术方案后,下面带你们深刻一下算法细节。这里选择图解的是推荐系统中的明星算法:协同过滤(Collaborative Filtering,CF)。 对于工程同窗来讲,可能以为 AI 算法晦涩难懂,门槛过高,确实不少深度学习算法的确是这样,可是协同过滤倒是一个简单同时效果很好的算法,只要你有初中数学的基础就能看懂。1. 协同过滤是什么?
协同过滤算法的核心就是「找类似」,它基于用户的历史行为(浏览、收藏、评论等),去发现用户对物品的喜爱,并对喜爱进行度量和打分,最终筛选出推荐集合。它又包括两个分支:
基于用户的协同过滤示例
基于物品的协同过滤:Item-CF,核心是找类似的物品。好比下图中,物品 a 和物品 b 同时被用户 A,B,C 购买了,那么物品 a 和 物品 b 被认为是类似的,由于它们的共现次数很高。这样,若是用户 D 购买了物品 a,则能够将和物品 a 最类似的物品 b 推荐给用户 D。
前面讲到,协同过滤的核心就是找类似,User-CF是找用户之间的类似,Item-CF是找物品之间的类似,那到底如何衡量两个用户或者物品之间的类似性呢?
咱们都知道,对于坐标中的两个点,若是它们之间的夹角越小,这两个点越类似,这就是初中学过的余弦距离,它的计算公式以下:
举个例子,A坐标是(0,3,1),B坐标是(4,3,0),那么这两个点的余弦距离是0.569,余弦距离越接近1,表示它们越类似。
清楚了类似性的定义后,下面以Item-CF为例,详细说下这个算法究竟是如何选出推荐物品的?
第一步:整理物品的共现矩阵
假设有 A、B、C、D、E 5个用户,其中用户 A 喜欢物品 a、b、c,用户 B 喜欢物品 a、b等等。第二步:计算物品的类似度矩阵
对于 Item-CF 算法来讲,通常不采用前面提到的余弦距离来衡量物品的类似度,而是采用下面的公式 :基于第1步计算出来的共现矩阵以及每一个物品的喜欢人数,即可以构造出物品的类似度矩阵:
上面的公式有点抽象,直接看例子更容易理解,假设我要给用户 E 推荐物品,前面咱们已经知道用户 E 喜欢物品 b 和物品 c,喜欢程度假设分别为 0.6 和 0.4。那么,利用上面的公式计算出来的推荐结果以下:
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。 经过脚本能够统计出不一样评分的人数分布:程序主要使用数据集中的 ratings.dat 这个文件,经过解析该文件,抽取出 user_id、movie_id、rating 3个字段,最终构造出算法依赖的数据,并保存在变量 dataset 中,它的格式为:dict[user_id][movie_id] = rate
基于第 2 步的 dataset,能够进一步统计出每部电影的评分次数以及电影的共生矩阵,而后再生成类似度矩阵。
最后,能够基于类似度矩阵进行推荐了,输入一个用户id,先针对该用户评分过的电影,依次选出 top 10 最类似的电影,而后加权求和后计算出每一个候选电影的最终评分,最后再选择得分前 5 的电影进行推荐。
下面选择 UserId=1 这个用户,看下程序的执行结果。因为推荐程序输出的是 movieId 列表,为了更直观的了解推荐结果,这里转换成电影的标题进行输出。
最终推荐的前5个电影为:
05 线上推荐系统的挑战
经过上面的介绍,你们对推荐系统的基本构成应该有了一个初步认识,可是真正运用到线上真实环境时,还会遇到不少算法和工程上的挑战,绝对不是几十行 Python 代码能够搞定的。
一、上面的示例使用了标准化的数据集,而线上环境的数据是非标准化的,所以涉及到海量数据的收集、清洗和加工,最终构造出模型可以使用的数据集。
二、复杂且繁琐的特征工程,都说算法模型的上限由数据和特征决定。对于线上环境,须要从业务角度选择出可用的特征,而后对数据进行清洗、标准化、归一化、离散化,并经过实验效果进一步验证特征的有效性。
三、算法复杂度如何下降?好比上面介绍的Item-CF算法,时间和空间复杂度都是O(N×N),而线上环境的数据都是千万甚至上亿级别的,若是不作算法优化,可能几天都跑不出数据,或者内存中根本放不下如此大的矩阵数据。
四、实时性如何知足?由于用户的兴趣随着他们最新的行为在实时变化的,若是模型只是基于历史数据进行推荐,可能结果不够精准。所以,如何知足实时性要求,以及对于新加入的物品或者用户该如何推荐,都是要解决的问题。
五、算法效果和性能的权衡。从算法角度追求多样性和准确性,从工程角度追求性能,这二者之间必须找到一个平衡点。
六、推荐系统的稳定性和效果追踪。须要有一套完善的数据监控和应用监控体系,同时有 ABTest 平台进行灰度实验,进行效果对比。