Python Spark 创建搜索引擎

1、Python Spark 创建搜索引擎

1.1、常见推荐算法

  • 常见推荐算法
算法 说明
基于关系型规则的推荐(Association Rule) 消费者购买产品A,那么他有多大机会购买产品B;<br> 购物车分析(啤酒和尿布)
基于内容的推荐(Context-based) 分析网页内容自动分类,在将用户自动分类;<br> 将新进分类的网页推荐给对该群感兴趣的用户
人口统计式的推荐(Demographic) 将用户以个人属性(性别、年龄、教育背景、居住地、语言)作为分类指标; <br> 以此类作为推荐标准
协同过滤式推荐(Collaborative Filtering) 通过观察所有用户对产品的评分来推断用户的喜好; <br> 找出对产品评分相近的其他用户,他们喜欢的产品当前用户多半也会喜欢
  • 协同过滤式推荐(Collaborative Filtering)推荐的优缺点
有点 缺点
可以达到个性化推荐;<br> 不需要内容分析;<br> 可以发现用户新的兴趣点; <br> 自动化程度高 冷启动问题(Cold-start):如果没有历史数据就没有办法分析; <br> 新用户问题:新用户没有数据,就不知道他的喜好;

1.2、Spark MLlib ALS(Alternating Least Squares) 推荐算法

ALS(Alternating Least Squares) 推荐算法,交替最小二乘法。在机器学习中,特指使用最小二乘法的一种协同推荐算法;

网站上的设计经常会请用户对某个产品进行评分,如1-5分,可以整理如下图的矩阵;

  • 显示评分
用户ID 项目1 项目2 项目3 项目4 项目5
user1 2 1 5
user2 1 3 1 1
user3 3 4
user4 2 2 1 2
user5 1 1 1 4 1

有些网站在设计可能并不会请用户进行评分,但是会记录用户是否选择了某个产品,如果用户选择了某个产品,就代表用户可能对该产品有兴趣,可用1表示,整理如下图的矩阵;

  • 隐式评分
用户ID 项目1 项目2 项目3 项目4 项目5
user1 1 1 1
user2 1 1 1 1
user3 1 1
user4 1 1 1 1
user5 1 1 1 1 1

推荐算法就是要找出两个用户的相似性,如,user1有兴趣的项目为项目(1,2,3),user2有兴趣的项目为项目(1,2,3,4),user1比user2少了项目4;因此,当推荐算法要推荐项目给user1会推荐项目4;

  • 稀疏矩阵

当用户与项目评分越来越多时,会出现大部分都是空白(大部分项目没有评分),这种矩阵称为稀疏矩阵;当矩阵非常大的时候,要计算这样的矩阵,非常浪费资源和时间;

  • 矩阵分解

为了解决稀疏矩阵的问题,需要采用矩阵分解,将矩阵A(m X n)分解为X(m X rank)矩阵与Y(rank X n),如下图

Python Spark 创建搜索引擎

1.3、ALS数据训练和推荐

1.3.1、数据准备

使用的数据主要有u.data(用户评分数据)和u.item(电影数据)

$ head data/u.{data,item}
==> data/u.data <==
196 242 3   881250949
186 302 3   891717742
22  377 1   878887116
244 51  2   880606923
166 346 1   886397596
298 474 4   884182806
115 265 2   881171488
253 465 5   891628467
305 451 3   886324817
6   86  3   883603013

==> data/u.item <==
1|Toy Story (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Toy%20Story%20(1995)|0|0|0|1|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0
2|GoldenEye (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?GoldenEye%20(1995)|0|1|1|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0
3|Four Rooms (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Four%20Rooms%20(1995)|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|0|0
4|Get Shorty (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Get%20Shorty%20(1995)|0|1|0|0|0|1|0|0|1|0|0|0|0|0|0|0|0|0|0
5|Copycat (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Copycat%20(1995)|0|0|0|0|0|0|1|0|1|0|0|0|0|0|0|0|1|0|0
6|Shanghai Triad (Yao a yao yao dao waipo qiao) (1995)|01-Jan-1995||http://us.imdb.com/Title?Yao+a+yao+yao+dao+waipo+qiao+(1995)|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0
7|Twelve Monkeys (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Twelve%20Monkeys%20(1995)|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|1|0|0|0
8|Babe (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Babe%20(1995)|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|0|0|0|0
9|Dead Man Walking (1995)|01-Jan-1995||http://us.imdb.com/M/title-exact?Dead%20Man%20Walking%20(1995)|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0
10|Richard III (1995)|22-Jan-1996||http://us.imdb.com/M/title-exact?Richard%20III%20(1995)|0|0|0|0|0|0|0|0|1|0|0|0|0|0|0|0|0|1|0
u.data包含4个字段:userid(用户id)、item id(项目id)、rating(评分)、timestamp(日期时间戳)
u.item有多个字段,在此取前两个:movie id(电影id)、movie title(电影片名)

1.3.2、程序思路

【u.data】 ——sc.textFile——> 【rawUserData】 ——map——> 【rawRatings】 ——map——> 【RatingsRDD】 ——ALS.train——> 【MatirixFactoization Model】

1.3.3、程序实现

  • 设置文件读取路径
In [1]: Path = "file:/home/hadoop/pyspark/PythonProject/recommend/"
  • 导入u.data数据,取前3个字段:用户id,产品id,评分
In [2]: rawUserData = sc.textFile(Path + "data/u.data")

In [3]: ratingsRDD = rawUserData.map(lambda line: line.split("\t")[:3] ).map(lambda x: (x[0],x[1],x[2]))
  • 导入ALS进行模型训练
In [4]: from pyspark.mllib.recommendation import ALS

In [5]: model = ALS.train(ratingsRDD, 10, 10, 0.01)
  • 导入电影数据u.item,取前两个字段:电影ID和电影名称
In [6]: itemRDD = sc.textFile(Path + "data/u.item")

In [7]: movieTitle = itemRDD.map(lambda line:line.split("|")).map(lambda a:(a[0],a[1])).collectAsMap()
  • 使用模型针对用户进行产品推荐,针对用户id:100,推荐5部影片
In [8]: recommendMovie = model.recommendProducts(100,5)

In [9]: for rdm in recommendMovie:
   ...:     print("针对用户ID: {0},推荐电影:{1} ,推荐评分:{2}".format(rdm[0], movieTitle.get(str(rdm[1])), rdm[2]))
   ...:         
针对用户ID: 100,推荐电影:Angel Baby (1995) ,推荐评分:7.610337473154874
针对用户ID: 100,推荐电影:Pather Panchali (1955) ,推荐评分:6.615085728728855
针对用户ID: 100,推荐电影:Once Were Warriors (1994) ,推荐评分:6.417519553465505
针对用户ID: 100,推荐电影:Radioland Murders (1994) ,推荐评分:6.24059727584324
针对用户ID: 100,推荐电影:Crooklyn (1994) ,推荐评分:5.944125863246919
  • 使用模型针对电影进行用户推荐,针对产品id:200,给5个用户推荐
In [10]: recommendUser = model.recommendUsers(200,5)

In [11]: for reu in recommendUser:
    ...:     print("针对用户ID: {0},推荐电影:{1} ,推荐评分:{2}".format(reu[0], movieTitle.get(str(reu[1])), reu[2]))
    ...:     
针对用户ID: 475,推荐电影:Shining, The (1980) ,推荐评分:7.06404094277568
针对用户ID: 762,推荐电影:Shining, The (1980) ,推荐评分:6.720699631364651
针对用户ID: 695,推荐电影:Shining, The (1980) ,推荐评分:6.221277830269441
针对用户ID: 810,推荐电影:Shining, The (1980) ,推荐评分:5.9598423486309535
针对用户ID: 917,推荐电影:Shining, The (1980) ,推荐评分:5.947701017469912

1.4、总结

使用 ALS 模块对影片的评价数据进行训练,训练后产生 MatrixFactorizationModel模型进行推荐,分布是针对产品和用户的推荐;

猜你喜欢

转载自blog.51cto.com/balich/2134500