Spark大数据分析与实战笔记(第八章 Spark MLlib 机器学习算法库-03) 文章目录每日一句正能量第八章 Spark MLlib 机器学习算法库章节概要8.5 分类8.5.1 线性支持向量机8.5.2 逻辑回归8.6 案例——构建推荐系统8.6.1 推荐模型分类8.6.2利用MLlib实现电影推荐每日一句正能量“用平和之心过朝朝暮暮用知足之心览人间烟火。”平和与知足是生活的最佳状态。朝朝暮暮的平凡因心境而变得珍贵。慢下来在平凡中体味生活的丰盛用知足平和的心态过好每一天。用这颗修炼好的心去点染和照亮每一个平凡的日子最终将整个生活过成一件艺术品。第八章 Spark MLlib 机器学习算法库章节概要MLlib是Spark提供的处理机器学习方面的功能库该库包含了许多机器学习算法开发者可以不需要深入了解机器学习算法就能开发出相关程序。本章将介绍Spark MLlib基本知识以及使用方法最后通过构建推荐引擎了解机器学习系统的构建思路及流程。8.5 分类MLlib支持多种分类分析方法例如二元分类、多元分类表列出了不同种类的问题可以采用不同的分类算法。分析方法相关算法二元分类线性支持向量机、逻辑回归、决策树、随机森林、梯度提升树、朴素贝叶斯多元分类逻辑回归、决策树、随机森林、朴素贝叶斯分类是指将事物分成不同类别在分类模型中可根据一组特征来判断类别这些特征代表了物体、事物或上下文的相关属性。分类算法又被称为分类器它是数据挖掘和机器学习领域中的一个重要分支它属于有监督学习的一种形式我们用带有类标记或者类输出的训练样本来训练模型要想评价一个分类器的好坏我们就要有评价指标最常见的就是准确率。8.5.1 线性支持向量机线性支持向量机是一种常见判别方法在机器学习领域中是一个有监督学习模型用来进行模式识别、分类以及回归分析。使用MLlib提供的线性支持向量机算法训练模型需要导入线性支持向量机所需包。#导入线性支持向量机所需包 scalaimportorg.apache.spark.mllib.classification.{SVMModel,SVMWithSGD}#导入二元分类评估类 scalaimportorg.apache.spark.mllib.evaluation.BinaryClassificationMetrics #MLUtils提供了一些辅助方法用于加载保存和预处理MLlib中使用的数据 scalaimportorg.apache.spark.mllib.util.MLUtils #加载Spark官方提供数据集 scalavaldataMLUtils.loadLibSVMFile(sc,file:///export/servers/spark/data/mllib/sample_libsvm_data.txt)#将数据的60%分为训练数据40%分为测试数据 scalavalsplitsdata.randomSplit(Array(0.6,0.4),seed11L)scalavaltrainingsplits(0).cache()scalavaltestsplits(1)#设置迭代次数 scalavalnumIterations100#执行算法来构建模型 scalavalmodelSVMWithSGD.train(training,numIterations)#用测试数据评估模型 scalavalscoreAndLabelstest.map{pointvalscoremodel.predice(point.features)(score,point.label)}#获取评估指标 scalavalmetricsnewBinaryClassificationMetrics(scoreAndLabels)#计算二元分类的PR和ROC曲线下的面积 scalavalauROCmetrics.areaUnderROC()auROC:Double1.0#保存并加载模型 scalamodel.save(sc,target/tmp/scalaSVMWithSGDModel)scalavalsameModelSVMModel.load(sc,target/tmp/scalaSVMWithSGDModel)上述代码中我们将数据文件分为两份其中60%的数据为训练模型数据40%的数据为测试数据用来评估我们创建的模型。第19行代码调用SVMWithSGD.train()方法构建训练模型。为了检验分类器的好坏程度可以利用MLlib提供的二元分类评估类计算ROC面积ROC曲线是对分类器的真假阳性率图形化的解释ROC下的面积通常称为AUC表示平均值当AUC为1.0时表示是一个完美的分类器当AUC为0.5时表示该模型和随机预测效果一样没有必要使用。评估模型完成后还可以使用save()方法保存至HDFS目录中下次只需调用load()方法即可加载该模型。结果如下图所示8.5.2 逻辑回归逻辑回归又称为逻辑回归分析是一个概率模型的分类算法用于数据挖掘、疾病自动诊断及经济预测等领域。例如在流行病学研究中探索引发某一疾病的危险因素根据模型预测在不同自变量情况下推测发生某一疾病。Spark MLlib提供了逻辑回归算法下面具体演示加载数据并执行训练模型方法具体代码如下。#导入逻辑回归所需包 scalaimportorg.apache.spark.mllib.classification.{LogisticRegressionModel,LogisticRegressionWithLBFGS}#导入分类评估器 scalaimportorg.apache.spark.mllib.evaluation.MulticlassMetrics scalaimportorg.apache.spark.mllib.regressin.LabeledPoint scalaimportorg.apache.spark.mllib.util.MLUtils #加载Spark官方提供数据集 scalavaldataMLUtils.loadLibSVMFile(sc,file:///export/servers/spark/data/mllib/sample_libsvm_data.txt)#将数据的60%分为训练数据40%分为测试数据 scalavalsplitsdata.randomSplit(Array(0.6,0.4),seed11L)scalavaltrainingsplits(0).cache()scalavaltestsplits(1)#运行训练算法来构建模型 scalavalmodelnewLogisticRegressionWithLBFGS().setNumClasses(10).run(training)#用测试数据评估模型 scalavalpredictionAndLabelstest.map{caseLabeledPoint(label,features)valpredictionmodel.predict(features)(prediction,label)}#获取评估指标 scalavalmetricsnewMulticlassMetrics(predictionAndLabels)scalavalaccuracymetrics.accuracy accuracy:Double1.0#保存并加载模型 scalamodel.save(sc,target/tmp/scalaLogisticRegressionWithLBFGSModel)scalavalsameModelLogisticRegressionModel.load(sc,target/tmp/scalaLogisticRegressionWithLBFGSModel)评估模型的性能不仅仅只有通过ROC曲线通常在二元分类中使用的评估方法有预测正确率和错误率、准确率和召回率等。准确率通常用于评估结果的质量召回率用来评估结果的完整性在二元分类问题中准确率定义为真阳性数据个数除以真阳性和假阳性的数据总数其中真阳性是指被正确预测的类别为1的样本假阳性是错误预测为类别1的样本。如果每个数据被分类器预测为1的样本那么准确率即为1.0。结果如下图所示8.6 案例——构建推荐系统8.6.1 推荐模型分类随着电子商务规模的不断扩大商品个数和种类快速增长顾客就需要花费大量的时间才能找到自己想买的商品这样就会造成消费者花费很长时间搜索商品从而造成用户体验下降。为了解决这些问题个性化推荐系统应运而生。个性化推荐系统是建立在海量数据挖掘基础上的一种高级商务智能平台从而为其顾客购物提供完全个性化的决策支持和信息服务。推荐系统的研究已经相当广泛也是最为大众所知的一种机器学习模型目前最为流行的推荐系统所应用的算法是协同过滤协同过滤通常用于推荐系统这项技术是为了填补关联矩阵的缺失项从而实现推荐效果。简单地说协同过滤是利用大量已有的用户偏好来估计用户对其未接触的物品的喜好程度。在协同过滤算法中有着两个分支基于群体用户的协同过滤UserCF和基于物品的协同过滤ltemCF.1.基于物品的推荐ltemCF基于物品的推荐是利用现有用户对物品的偏好或是评级情况计算物品之间的某种相似度以用户接触过的物品来表示这个用户然后寻找出和这些物品相似的物品并将这些物品推荐给用户。2.基于物品的推荐(UserCF)基于用户的推荐可以用“志趣相投”一词所表示通常是对用户的历史行为数据分析例如购买、收藏的商品评论内容或搜索内容通过某种算法将用户喜好的物品进行打分。根据不同用户对相同物品或内容数据的态度和偏好程度来计算用户之间的关系程度在有相同喜好的用户之间进行商品推荐。8.6.2利用MLlib实现电影推荐在电影推荐系统中通常分类针对用户推荐电影和针对电影推荐用户两种方式。具体实现方式取决于采用的推荐模型若采用基于用户的推荐模型则会利用相似用户的评级来计算对某个用户的推荐。若采用基于物品的推荐模型则会依靠用户接触过的物品与候选物品之间的相似度来获得推荐。在Spark MLlib实现了交替最小二乘ALS算法它是机器学习的协同过滤式推荐算法机器学习的协同过滤式推荐算法是通过观察所有用户给产品的评分来推断每个用户的喜好并向用户推荐合适的产品。接下来我们将分步骤讲解利用Spark MLlib实现电影推荐案例的核心过程。准备训练模型数据MovieLens是历史最悠久的推荐系统它是由美国Minnesota大学计算机科学与工程学院的GroupLens项目组创办是一个以研究为目的的、非商业性质的实验性站点读者可以从该网站中下载实验数据进行学习网站地址为https://grouplens.org/datasets/movielens/下载ml-100k.zip解压包。具体如图8-6所示。图8-6也可以直接在Linux系统上输入以下命令下载文件具体命令如下。wgethttp://files.grouplens.org/datasets/movielens/m1-100k.zip实验数据文件下载完成后将其进行解压命令如下。yuminstallunzipunzip-jm1-100k结果如下图所示最终将解压文件上传到HDFS中的/spark/mldata路径下效果如图8-7所示。命令如下hadoop fs-mkdir/spark/mldatacd..hadoop fs-putml-100k /spark/mldata结果如下图所示在本案例中主要用到u.data文件用户评分数据以及u.item文件电影数据数据片段分别为如图所示。文件u.item中具有多个字段本案例主要使用第一列电影id、第二列电影名称后续将针对该文本进行字符串处理。编写程序训练模型我们采用Spark-Shell读取u.data数据文件将其转换为RDD执行命令如下。$ spark-shell--master local[2]#读取文件转换RDD scalavaldataRddsc.textFile(/spark/mldata/ml-100k/u.data)#输出RDD第一行数据 scaladataRdd.first()res0:String1922423881250949结果如下图所示从上一章节已经得知该数据是由用户id、电影id、等级评价和时间戳依次组成在训练模型时可以去除时间戳字段使用take()方法提取前三个字段即可具体代码如下。scalavaldataRddsdataRdd.map(_.split(\t).take(3))scaladataRdds.first()res1:Array[String]Array(196,242,3)根据图的u.data文件内容可知使用“\t”进行分割返回一个Array[String]类型的RDD分别对应用户id、影片id以及等级。至此就有了dataRdds数据集可以使用first()函数查看第一行数据。下面就可以使用Spark MLlib训练模型了首先导入MLlib实现的ALS算法模型库。scalaimportorg.apache.spark.mllib.recommendation.ALS在ALS库中可以通过调用train()函数来训练模型具体代码如下。def train( ratings: RDD[Rating], rank: Int, iterations: Int, lambda: Double ): MatrixFactorizationModel上述代码中train()函数需要提供四个参数如表所示。参数名称相关说明ratings训练的数据格式是Rating(UserID, productID, rating)的RDDrank对应ALS模型中的因子个数也就是在低阶近似矩阵中的隐含特征个数因子个数一般越多越好但是也会加大内存开销开销通常值为10-200iterations对应运算时的迭代次数减少评级矩阵的重建误差默认值为5大部分情况下设置10次左右lambda该参数控制模型的正则化过程从而控制模型的拟合程度。值越高正则化越严厉该参数的值与实际数据的大小、特征和稀疏程度有关默认值0.01训练模型需要Rating格式的数据可以将dataRdds使用map()方法进行转换得到Rating格式数据传入到train()函数具体代码如下。#导入Rating包 scalaimportorg.apache.spark.mllib.recommendation.Rating scalavalratingsdataRdds.map{caseArray(user,movie,rating)Rating(user.toInt,movie.toInt,rating.toDouble)}scalaratings.first()res6:org.apache.spark.mllib.recommendation.RatingRating(196,242,3.0)结果如下图所示需要注意的是使用case语句来提供各属性对应的变量名dataRdds是从u.data文本文件中转换的数据因此需要把String类型转换成对应的数据类型提取简单特征后就可以调用train()函数训练模型代码如下。scalavalmodelALS.train(ratings,50,10,0.01)model:org.apache.spark.mllib.recommendation.MatrixFactorizationModelorg.apache.spark.mllib.recommendation.MatrixFactorizationModel6580f76c结果如下图所示调用ALS.train训练数据集后就会创建推荐引擎模型MatrixFactorizationModel矩阵分解对象该对象成员如表所示。对象成员相关说明predict(user: Int, product: Int): Double计算给定用户和物品的预期得分productFeatures:RDD[(Int, Array[Double])]分解后的物品矩阵rank: Int分解后的参数userFeatures: Rdd[(Int, Array[Double])]分解后产品矩阵表中predict函数以(user, product)作为输入参数该函数将为每一对生成相应的预测得分具体代码如下。scalavalpredictedRatingmodel.predict(100,200)predictedRating:Double1.1136730131397399结果如下图所示从上述执行结果可以看出改模型预测用户id100对电影id200的评级约为1.11。需要注意的是ALS模型的初始化过程根据硬件环境以及参数等因素会造成不同的结果。为用户推荐多个电影如果要为某个用户推荐多个物品可以调用MatrixFactorizationModel对象所提供的recommendProducts(user: Int, num: Int)函数来实现返回值即为预测得分最高的前num个物品具体代码如下。#定义用户id scalavaluserid100#定义推荐数量 scalavalnum10scalavaltopRecoPromodel.recommendProducts(userid,num)结果如下图所示从上述代码可以看出使用训练完成的模型进行推荐传入参数(user100, num10)返回结果是一个Rating数据类型的数组其中参数分别表示用户iduser、推荐电影idproduct、算法得出的评分rating其中评分越高代表推荐引擎优先推荐这件物品。Rating100, 207, 5.704436943409341数据表示针对id100的用户预测对id207的电影评级为5.70分。为了更直观的检测推荐效果可以将u.item文件中的电影id与电影名称进行映射因此首先读取u.item文件并转换为RDD。具体代码如下。scalavalmoviesRddsc.textFile(/spark/mldata/ml-100k/u.item)根据图中u.item文件的数据格式进行分析可以通过|字符分割使用map()函数针对每一项数据进行转换提取前2个数据并将电影id、电影名称产生映射关系。具体代码如下。valtitlesmoviesRdd.map(lineline.split(\\|).take(2)).map(array(array(0).toInt,array(1))).collectAsMap()结果如下图所示对于100个用户可以通过Rating对象的rating属性来对推荐的电影名称进行匹配具体代码如下。scalatopRecoPro.map(rating(titles(rating.product),rating.rating)).foreach(println)结果如下图所示至此根据用户推荐电影实现完成。将物品推荐给用户如果要为某个物品推荐多个用户时可以调用MatrixFactorizationModel对象所提供的recommendUsers(product: Int, num: Int)函数来实现其中product参数代表被推荐的物品idnum为推荐物品的数量最终返回值为针对这件物品可能感兴趣的num名用户具体代码如下。scalamodel.recommendUsers(100,5)通过上述返回结果看出电影编号为100的推荐给用户编号为495、30、272、8、68这五位用户至此基于物品推荐电影实现完成。转载自https://blog.csdn.net/u014727709/article/details/133902769欢迎 点赞✍评论⭐收藏欢迎指正