公司动态

Spark大数据分析与实战笔记(第八章 Spark MLlib 机器学习算法库-02)

📅 2026/8/22 16:45:15
Spark大数据分析与实战笔记(第八章 Spark MLlib 机器学习算法库-02)
文章目录每日一句正能量章节概要8.3 数据类型8.3.1 本地向量8.3.2 标注点8.3.3 本地矩阵8.4 Spark MLlib基本统计8.4.1 摘要统计8.4.2 相关统计8.4.3 分层抽样每日一句正能量最结实的希望是用下一步编织的。希望不是空中楼阁而是由连续不断的、微小的行动经纬编织而成的地毯。那些光、花、根、蝉鸣、滚烫、茶香与镜台……拼贴起来就是一个完整而自足的世界。章节概要MLlib是Spark提供的处理机器学习方面的功能库该库包含了许多机器学习算法开发者可以不需要深入了解机器学习算法就能开发出相关程序。本章将介绍Spark MLlib基本知识以及使用方法最后通过构建推荐引擎了解机器学习系统的构建思路及流程。8.3 数据类型MLlib的主要数据类型包括本地向量、标注点、本地矩阵。本地向量与本地矩阵是提供公共接口的简单数据类型Breeze和Jblas提供了底层的线性代数运算。在监督学习中使用标注点类型表示训练样本。8.3.1 本地向量本地向量分为密集向量Dense和稀疏向量Sparse密集向量是由Double类型的数组支持而稀疏向量是由两个并列的数据索引、值支持。例如向量1.0, 0.0, 3.0的密集向量表示的格式为[1.0, 0.0, 3.0]由稀疏向量表示的格式为3, [0, 2], [1.0, 3.0]其中3是向量1.00.0 3.0的长度[0, 2]是向量中非0维度的索引值即向量索引0和2的位置为非0元素[1.03.0]是按照索引排列的数组元素值。本地向量的基类是VectorMLlib提供了DenseVector和SparseVector类官方建议使用Vectors工具类下的工厂方法来创建本地向量创建方式如下所示。#导包 scalaimportorg.apache.spark.mllib.linalg.{Vector,Vectors}#创建一个密集本地向量 scalavaldv:VectorVectors.dense(1.0,0.0,3.0)#创建一个稀疏本地向量 scalavalsv1:VectorVectors.sparse(3,[0,2],[1.0,3.0])# 通过指定非零项目创建稀疏本地向量 scalavalsv2:VectorVectors.sparse(3,Seq((0,1.0),(1.0,3.0)))需要说明的是在Scala中默认会导入scala.collection.immutable.Vector包所以必须显式导入org.apache.spark.mllib.linalg.Vector才能使用MLlib提供的Vector类。结果如下图所示#导包 scalaimportorg.apache.spark.mllib.linalg.{Vector,Vectors}#创建一个密集本地向量 scalavaldv:VectorVectors.dense(1.0,0.0,3.0)dv:org.apache.spark.mllib.linalg.Vector[1.0,0.0,3.0]#创建一个稀疏本地向量 scalavalsv1:VectorVectors.sparse(3,[0,2],[1.0,3.0])# 通过指定非零项目创建稀疏本地向量 scalavalsv2:VectorVectors.sparse(3,Seq((0,1.0),(1.0,3.0)))sv2:org.apache.spark.mllib.linalg.Vector(3,[0,2],[1.0,3.0])8.3.2 标注点标注点是一种带有标签的本地向量标注点通常用于监督学习算法中MLlib使用Double数据类型存储标签因此可以在回归和分类中使用标记点。如果只有两种分类可以使用二分法则正样本标签为1.0负样本标签为0.0对于多分类问题来说标签是一个以0开始的索引序列如0、1、2…。标注点的实现类是org.apache.spark.mllib.regression.LabeledPoint 创建标注点方式的代码如下。#导包 scalaimportorg.apache.spark.mllib.linalg.Vectors scalaimportorg.apache.spark.mllib.regression.LabeledPoint #创建带有正标签和密集向量的标注点 scalavalposLabeledPoint(1.0,Vectors.dense(1.0,0.0,3.0))#创建带有负标签和稀疏向量的标注点 scalavalnegLabeledPoint(0.0,Vectors.sparse(3,Array(0,2),Array(1.0,3.0)))结果如下图所示#导包 scalaimportorg.apache.spark.mllib.linalg.Vectors scalaimportorg.apache.spark.mllib.regression.LabeledPoint #创建带有正标签和密集向量的标注点 scalavalposLabeledPoint(1.0,Vectors.dense(1.0,0.0,3.0))pos:org.apache.spark.mllib.regression.LabeledPoint(1.0,[1.0,0.0,3.0])#创建带有负标签和稀疏向量的标注点 scalavalnegLabeledPoint(0.0,Vectors.sparse(3,Array(0,2),Array(1.0,3.0)))neg:org.apache.spark.mllib.regression.LabeledPoint(0.0,(3,[0m2],[1.0,3.0]))稀疏向量数据在机器学习应用中较为常见MLlib支持读取LIBSVM的格式数据LIBSVM格式是一种每一行表示一个标签稀疏向量的文本格式其格式如下label index1:value1 index2:value2…上述格式中label是该样本点的标签值”index: value“代表了该样本向量中所有非零的索引和元素值需要注意的是index是以1递增的。8.3.3 本地矩阵本地矩阵具有整型的行和列索引值以及Double类型的元素值它存储在单个机器上。MLlib支持密集矩阵和稀疏矩阵密集矩阵将所有元素的值存储在一个列优先的双精度数组中而稀疏矩阵则将以列优先的非零元素压缩到稀疏列CSC格式中。本地矩阵的基类是MatrixDenseMatrix和SparseMatrix均是Matrix的继承类。创建本地矩阵方式的代码如下。#导包 scalaimportorg.apache.spark.mllib.linalg.{Matrix,Matrices}#创建一个3行2列的密集矩阵 scalavaldm:MatrixMatrices.dense(3,2,Array(1.0,3.0,5.0,2.0,4.0,6.0))#创建一个3行2列的稀疏矩阵 scalavalsm:MatrixMatrices.sparse(3,2,Array(0,1,3),Array(0,2,1),Array(9,6,8))结果如下图所示#导包 scalaimportorg.apache.spark.mllib.linalg.{Matrix,Matrices}#创建一个3行2列的密集矩阵 scalavaldm:MatrixMatrices.dense(3,2,Array(1.0,3.0,5.0,2.0,4.0,6.0))dm:org.apache.spark.mllib.linalg.Matrix1.02.03.04.05.06.0#创建一个3行2列的稀疏矩阵 scalavalsm:MatrixMatrices.sparse(3,2,Array(0,1,3),Array(0,2,1),Array(9,6,8))sm:org.apache.spark.mllib.linalg.Matrix3x2CSCMatrix 009.0216.0118.0上述是创建本地矩阵的方式需要注意的是这里的数组参数是列优先的即按照列的方式从数组中提取元素。8.4 Spark MLlib基本统计MLlib提供了很多统计方法包含摘要统计、相关统计、分层抽样、假设检验、随机数生成等统计方法利用这些统计方法可以帮助用户更好地对结果数据进行处理和分析。8.4.1 摘要统计在MLlib中统计量的计算主要用到Statistics类摘要统计主要方法及相关说明如表所示。方法名称相关说明count列的大小mean每列的均值variance每列的方差max每列的最大值min每列的最小值numNonzeros每列非零向量的个数方差公式接下来使用Spark-Shell演示摘要统计方法代码如下。#导包 scalaimportorg.apache.spark.mllib.linalg.Vectors scalaimportorg.apache.spark.mllib.stat.{MultivariateStatisticalSummary,Statistics}#创建密集矩阵 scalavalobservationssc.parallelize(Seq(Vectors.dense(1.0,10.0,100.0),Vectors.dense(2.0,10.0,200.0),Vectors.dense(3.0,30.0,300.0)))#计算列摘要统计信息 scalavalsummary:MultivariateStatisticalSummaryStatistics.colStats(observations)#打印平均值 scalaprintln(summary.mean)[2.0,20.0,200.0]#打印方差 scalaprintln(summary.variance)[1.0,100.0,10000.0]结果如下图所示8.4.2 相关统计相关系数是反应两个变量之间相关关系密切程度的统计指标这也是统计学中常用的统计方式MLlib提供了计算多个序列之间相关统计的方法目前MLlib默认采用皮尔森相关系数计算方法。皮尔森相关系数Pearson correlation coefficient也称皮尔森积矩相关系数Pearson product-moment correlation coefficient它是一种线性相关系数计算公式如下Statistics提供了计算序列之间相关性的方法接下来通过Spark Shell演示相关统计方法具体代码如下。#导包 scalaimportorg.apache.spark.mllib.linalg._ scalaimportorg.apache.spark.mllib.stat.Statistics scalaimportorg.apache.spark.mllib.rdd.RDD #创建序列 scalavalseriesX:RDD[Double]sc.parallelize(Array(1,2,3,3,5))scalavalseriesY:RDD[Double]sc.parallelize(Array(11,22,33,33,555))#计算seriesX,seriesY的相关系数 scalavalcorrelation:DoubleStatistics.corr(seriesX,seriesY,pearson)#打印数据 scalaprintln(sCorrelation is:$correlation)Correlation is:0.8500286768773001#利用皮尔森方法计算密集矩阵相关系数 scalavaldata:RDD[Vector]sc.parallelize(Seq(Vectors.dense(1.0,10.0,100.0)Vectors.dense(2.0,20.0,200.0)Vectors.dense(5.0,33.0,366.0)))scalavalcorrelMatrix:MatrixStatistics.corr(data,pearson)scalaprintln(correlMatrix.toString)在上述代码中通过Statistics.corr(data, “pearson”)方法选择使用皮尔森相关系数算法获得数据的相关系数但在MLlib中还提供了斯皮尔曼等级相关系数方法只需要在corr()方法中标注spearman参数即可。结果如下图所示8.4.3 分层抽样分层抽样法也叫类型抽样法它是先将总体按照某种特征分为若干次级层然后再从每一层内进行独立取样组成一个样本的统计学计算方法。例如某手机厂家估算当地 潜在用户可以将当地居民消费水平作为分层基础减少样本中的误差如果不采取分层抽样仅在消费水平较高的用户中做调查是不能准确的估算出潜在的用户。接下来通过Spark-Shell演示分层抽样方法具体代码如下。#创建键值对RDD scalavaldatasc.parallelize(Seq((1.a),(1,b),(2,c),(2,d),(2,e),(3,f)))#设定抽样格式 scalavalfractionsMap(1-0.1,2-0.6,3-0.3)#从每层获取抽样样本 scalavalapproxSampledata.sampleByKeyy(withReplacementfalse,fractionsfractions)# 从每层获取精确样本 scalavalexactSampledata.sampleByKeyExact(withReplacementfalse,fractionsfractions)#打印抽样样本 scalaapproxSample.foreach(println)(2,e)#打印精确样本 scalaexactSample.foreach(println)(2,d)(3,f)结果如下图所示在上述代码中用到了两种分层抽样方法其中sampleByKey()方法需要作用于一个键值对数组其中Key用于分类Value可以是任意值然后通过fractions参数定义分类条件和采样机率fractions参数被定义成一个Map类型Key是键值对数组的分层条件Value是满足Key条件的采样比例1.0代表概率为100%withReplacement代表每次抽样是否有放回。sampleByKey()方法会对全量数据做采样计算。对于每个类别其都会产生fk·nk个样本其中fk是键为fractions的Key的样本类别采样的比例nk是Key所拥有的样本数。sampleByKeyExtra采样的结果会更准确有99.99%的置信度但耗费的计算资源也更多。sampleByKey()方法和sampleByKeyExact()方法的区别在于sampleByKey()方法每次都得通过给定的概率以一种类似于掷硬币的方式来决定这个观察值是否被放入样本因此一遍就可以过滤完所有数据最后得到一个近似大小的样本但往往并不够准确。转载自https://blog.csdn.net/u014727709/article/details/163802680欢迎 点赞✍评论⭐收藏欢迎指正