✎ 学习目标
MLlib是Spark提供的处理机器学习方面的功能库,该库包含了许多机器学习算法,开发者可以不需要深入了解机器学习算法就能开发出相关程序。
什么是实时计算
机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科,专门研究计算机如何模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。
机器学习是一种能够赋予机器进行自主学习,不依靠人工进行自主判断的技术,它和人类对历史经验归纳的过程有着相似之处。
什么是机器计算
在机器学习领域中,按照学习方式分类,可以让研究人员在建模和算法选择的时候,考虑根据输入数据来选择合适的算法从而得到更好的效果,通常机器学习可以分为有监督学习和无监督学习两种。
机器学习的应用
MLlib的简介
MLlib是Spark提供的可扩展的机器学习库,其中封装了一些通用机器学习算法和工具类,包括分类、回归、聚类、降维等,开发人员在开发过程中只需要关注数据,而不需要关注算法本身,只需要传递参数和调试参数。
Spark机器学习工作流程
Spark中的机器学习流程大致分为三个阶段,即数据准备阶段、训练模型评估阶段以及部署预测阶段。
# 创建一个密集本地向量
val dv:Vector = Vectors.dense(1.0,0.0,3.0)
dv: org.apache.spark.mllib.linalg.Vector = [1.0,0.0,3.0]
# 创建一个稀疏本地向量
val sv1: Vector = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0))
sv1: org.apache.spark.mllib.linalg.Vector = (3,[0,2],[1.0,3.0])
标注点
标注点是一种带有标签的本地向量,标注点通常用于监督学习算法中,MLlib使用Double数据类型存储标签,因此可以在回归和分类中使用标记点。
标注点实现类org.apache.spark.mllib.regression.LabeledPoint 创建带有正标签和密集向量的标注点 val pos = LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0)) 创建带有负标签和稀疏向量的标注点 val neg = LabeledPoint(0.0, Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)))
本地矩阵
创建一个3行2列的密集矩阵
scala>val dm: Matrix =Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))
创建一个3行2列的密集矩阵
scala> val sm: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 1),
Array(9, 6, 8))
摘要统计
MLlib提供了很多统计方法,包含摘要统计、相关统计、分层抽样、假设检验、随机数生成等统计方法,利用这些统计方法可帮助用户更好地对结果数据进行处理和分析。统计量的计算用到Statistics类,摘要统计主要方法如下所示。
相关统计
相关系数是反应两个变量之间相关关系密切程度的统计指标,这也是统计学中常用的统计方式,MLlib提供了计算多个序列之间相关统计的方法,目前MLlib默认采用皮尔森相关系数计算方法。皮尔森相关系数也称皮尔森积矩相关系数,它是一种线性相关系数。
分层抽样
分层抽样法也叫类型抽样法,将总体按某种特征分为若干层级,再从每一层内进行独立取样,组成一个样本的统计学计算方法。
例如某手机厂家估算当地潜在用户,可以将当地居民消费水平作为分层基础,减少样本中的误差,如果不采取分层抽样,仅在消费水平较高的用户中做调查,是不能准确的估算出潜在的用户。
分类算法
分类是指将事物分成不同类别,在分类模型中,可根据一组特征来判断类别,这些特征代表了物体、事物或上下文的相关属性。分类算法又被称为分类器,它是数据挖掘和机器学习领域中的一个重要分支。
MLlib支持多种分类分析方法,例如二元分类、多元分类,表中列出了不同种类的问题可采用不同的分类算法。
线性支持向量机
推荐模型分类
推荐系统的研究已相当广泛,也是最为大众所知的一种机器学习模型,目前最为流行的推荐系统所应用的算法是协同过滤,协同过滤用于推荐系统,这项技术是为填补关联矩阵的缺失项而实现推荐效果。简单的说,协同过滤是利用大量已有的用户偏好,来估计用户对其未接触过的物品的喜好程度。
在协同过滤算法中有着两个分支:基于群体用户的协同过滤(UserCF)和基于物品的协同过滤(ItemCF)。
利用MLlib实现电影推荐
在电影推荐系统中,通常分为针对用户推荐电影和针对电影推荐用户两种方式。若采用基于用户的推荐模型,则会利用相似用户的评级来计算对某个用户的推荐。若采用基于物品的推荐模型,则会依靠用户接触过的物品与候选物品之间的相似度来获得推荐。
在Spark MLlib实现了交替最小二乘(ALS)算法,它是机器学习的协同过滤式推荐算法,机器学习的协同过滤式推荐算法是通过观察所有用户给产品的评分来推断每个用户的喜好,并向用户推荐合适的产品。
用户评分文件,即u.data文件
电影数据文件,即u.item文件
(1) 采用Spark-Shell读取u.data数据文件,将其转换为RDD
$ spark-shell --master local[2]
scala> val dataRdd = sc.textFile("/spark/mldata/ml-100k/u.data")
scala> dataRdd.first()
res0: String = 196 242 3 881250949
(2) 使用take()方法提取前三个字段
scala> val dataRdds = dataRdd.map(_.split("\t").take(3))
scala> dataRdds.first()
res1: Array[String] = Array(196, 242, 3)
(3) 导入MLlib实现的ALS算法模型库
scala> import org.apache.spark.mllib.recommendation.ALS
(4) 将dataRdds转换成Rating格式的数据
scala> import org.apache.spark.mllib.recommendation.Rating
scala> val ratings = dataRdds.map {
case Array(user,movie,rating) =>
Rating(user.toInt,movie.toInt,rating.toDouble)}
scala> ratings.first()
res6: org.apache.spark.mllib.recommendation.Rating = Rating(196,242,3.0)
(5) 使用train()函数训练模型
scala> val model = ALS.train(ratings,50,10,0.01)
model: org.apache.spark.mllib.recommendation.MatrixFactorizationModel =
org.apache.spark.mllib.recommendation.MatrixFactorizationModel@6580f76c
# 定义用户id
scala> val userid = 100
# 定义推荐数量
scala> val num = 10
scala> val topRecoPro = model.recommendProducts(userid,num)
topRecoPro: Array[org.apache.spark.mllib.recommendation.Rating] = Array(
Rating(100,207,5.704436943409341),Rating(100,845,4.957373351732721),
Rating(100,489,4.955561012970148),Rating(100,242,4.930681946988706),
Rating(100,315,4.927258436518516),Rating(100,316,4.905582861372857),
Rating(100,313,4.8170984786843265),Rating(100,12,4.795107793201218),
Rating(100,451,4.760165688538673),Rating(100,485,4.7560380607401))
为了更直观的检测推荐效果,将u.item文件中的电影id与电影名称进行映射。
(1)先读取u.item文件并转换为RDD
scala> val moviesRdd =sc.textFile("/spark/mldata/ml-100k/u.item")
(2)使用map()函数针对每一项数据进行转换
val titles = moviesRdd.map(line => line.split("\\|").take(2)).map(array=>
(array(0).toInt,array(1))).collectAsMap()
(3)通过Rating对象的rating属性来对推荐的电影名称进行匹配
scala> topRecoPro.map(rating => (titles(rating.product),rating.rating))
.foreach(println)
(Cyrano de Bergerac (1990),5.704436943409341)
(That Thing You Do! (1996),4.957373351732721)
(Notorious (1946),4.955561012970148)
(Kolya (1996),4.930681946988706)
(Apt Pupil (1998),4.927258436518516)
(As Good As It Gets (1997),4.905582861372857)
(Titanic (1997),4.8170984786843265)
(Usual Suspects, The (1995),4.795107793201218)
(Grease (1978),4.760165688538673)
(My Fair Lady (1964),4.7560380607401)
scala> model.recommendUsers(100,5)
res1: Array[org.apache.spark.mllib.recommendation.Rating] = Array(
Rating(495,100,6.541442448267074),
Rating(30,100,6.538178750321883),
Rating(272,100,6.398878858473),
Rating(8,100,6.372883993450857),
Rating(68,100,6.37055453407313))