Machine Learning On Spark——基础数据结构(一)

来源:互联网 发布:arctime字幕软件官方 编辑:程序博客网 时间:2024/06/07 17:06

本节主要内容

  1. 本地向量和矩阵
  2. 带类标签的特征向量(Labeled point)
  3. 分布式矩阵

1. 本地向量和矩阵

本地向量(Local Vector)存储在单台机器上,索引采用0开始的整型表示,值采用Double类型的值表示。Spark MLlib中支持两种类型的矩阵,分别是密度向量(Dense Vector)和稀疏向量(Spasre Vector),密度向量会存储所有的值包括零值,而稀疏向量存储的是索引位置及值,不存储零值,在数据量比较大时,稀疏向量才能体现它的优势和价值。下面给出其应用示例:

import org.apache.spark.mllib.linalg.{Vector, Vectors}//密度矩阵,零值也存储scala> val dv: Vector = Vectors.dense(1.0, 0.0, 3.0)dv: org.apache.spark.mllib.linalg.Vector = [1.0,0.0,3.0]// 创建稀疏矩阵,指定元素的个数、索引及非零值,数组方式scala> 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])// 创建稀疏矩阵,指定元素的个数、索引及非零值,采用序列方式scala> val sv2: Vector = Vectors.sparse(3, Seq((0, 1.0), (2, 3.0)))sv2: org.apache.spark.mllib.linalg.Vector = (3,[0,2],[1.0,3.0])

本地矩阵(Local Matrix)指的也是存储于单台机器上的数据结构,本地矩阵采用整体的行列序号存取元素,本地矩阵也有密度矩阵(Dense Matrix)、稀疏矩阵(Sparse Matrix)两种存储方法,其使用代码如下:

//密度矩阵的存储scala> import org.apache.spark.mllib.linalg.{Matrix, Matrices}import org.apache.spark.mllib.linalg.{Matrix, Matrices}//创建一个密度矩阵scala> val dm: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))dm: org.apache.spark.mllib.linalg.Matrix = 1.0  2.0  3.0  4.0  5.0  6.0  

在Spark MLLib中,稀疏矩阵采用的是Compressed Sparse Column (CSC) 格式进行矩阵的存储,具体参见(http://www.tuicool.com/articles/A3emmqi)对稀疏矩阵存储的介绍,例如

//下列矩阵    1.0 0.0 4.0    0.0 3.0 5.0    2.0 0.0 6.0如果采用稀疏矩阵存储的话,其存储信息包括:实际存储值: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]`,矩阵元素对应的行索引:rowIndices=[0, 2, 1, 0, 1, 2]`列起始位置索引: `colPointers=[0, 2, 3, 6]`.scala> val sparseMatrix= Matrices.sparse(3, 3, Array(0, 2, 3, 6), Array(0, 2, 1, 0, 1, 2), Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0))sparseMatrix: org.apache.spark.mllib.linalg.Matrix = 3 x 3 CSCMatrix(0,0) 1.0(2,0) 2.0(1,1) 3.0(0,2) 4.0(1,2) 5.0(2,2) 6.0
  • 1

2. 带类标签的特征向量(Labeled point)

Labeled point是Spark MLlib中最重要的数据结构之一,它在无监督学习算法中使用十分广泛,它也是一种本地向量,只不过它提供了类的标签,对于二元分类,它的标签数据为0和1,而对于多类分类,它的标签数据为0,1,2,…。它同本地向量一样,同时具有Sparse和Dense两种实现方式,例如:

scala> import org.apache.spark.mllib.regression.LabeledPointimport org.apache.spark.mllib.regression.LabeledPoint// LabeledPoint第一个参数是类标签数据,第二参数是对应的特征数据//下面给出的是其密度向量实现方式scala> val pos = LabeledPoint(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]) // LabeledPoint的稀疏向量实现方式scala> val neg = LabeledPoint(0.0, Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)))neg: org.apache.spark.mllib.regression.LabeledPoint = (0.0,(3,[0,2],[1.0,3.0]))

LabeledPoint的稀疏向量实现方式在实际中应用最为广泛,这是因为某一特征的维度可能达到上千,而这其中又存在大量对后期训练无益的零值特征信息,如果对所有的零值特征都进行存储的话,会浪费大量的存储空间,因此实际中常常使用稀疏的实现方式,使用的是LIBSVM格式:label index1:value1 index2:value2 …进行特征标签及特征的存储与读取。

scala> val examples: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "/data/sample_data.txt")examples: org.apache.spark.rdd.RDD[org.apache.spark.mllib.regression.LabeledPoint] = MapPartitionsRDD[6] at map at MLUtils.scala:98
  • 1

3. 分布式矩阵RowMatrix与CoordinateMatrix

下列代码演示了RowMatrix与CoordinateMatrix及其相关核心类的使用方法

package cn.ml.datastructimport org.apache.spark.SparkConfimport org.apache.spark.SparkContextimport org.apache.spark.mllib.linalg.Vectorsimport org.apache.spark.mllib.linalg.distributed.RowMatriximport org.apache.spark.mllib.linalg.distributed.CoordinateMatrixobject RowMatrixDedmo extends App {  val sparkConf = new SparkConf().setAppName("RowMatrixDemo").setMaster("spark://sparkmaster:7077")  val sc = new SparkContext(sparkConf)  // 创建RDD[Vector]  val rdd1= sc.parallelize(      Array(          Array(1.0,2.0,3.0,4.0),          Array(2.0,3.0,4.0,5.0),          Array(3.0,4.0,5.0,6.0)          )      ).map(f => Vectors.dense(f))   //创建RowMatrix   val rowMatirx = new RowMatrix(rdd1)   //计算列之间的相似度,返回的是CoordinateMatrix,采用   //case class MatrixEntry(i: Long, j: Long, value: Double)存储值   var coordinateMatrix:CoordinateMatrix= rowMatirx.columnSimilarities()   //返回矩阵行数、列数   println(coordinateMatrix.numCols())   println(coordinateMatrix.numRows())   //查看返回值,查看列与列之间的相似度   //Array[org.apache.spark.mllib.linalg.distributed.MatrixEntry]    //= Array(MatrixEntry(2,3,0.9992204753914715),    //MatrixEntry(0,1,0.9925833339709303),    //MatrixEntry(1,2,0.9979288897338914),    //MatrixEntry(0,3,0.9746318461970762),    //MatrixEntry(1,3,0.9946115458726394),    //MatrixEntry(0,2,0.9827076298239907))   println(coordinateMatrix.entries.collect())   //转成后块矩阵,下一节中详细讲解   coordinateMatrix.toBlockMatrix()   //转换成索引行矩阵,下一节中详细讲解   coordinateMatrix.toIndexedRowMatrix()   //转换成RowMatrix   coordinateMatrix.toRowMatrix()   //计算列统计信息    var mss:MultivariateStatisticalSummary=rowMatirx.computeColumnSummaryStatistics()   //每列的均值, org.apache.spark.mllib.linalg.Vector = [2.0,3.0,4.0,5.0]   mss.mean   // 每列的最大值org.apache.spark.mllib.linalg.Vector = [3.0,4.0,5.0,6.0]   mss.max   // 每列的最小值 org.apache.spark.mllib.linalg.Vector = [1.0,2.0,3.0,4.0]   mss.min   //每列非零元素的个数org.apache.spark.mllib.linalg.Vector = [3.0,3.0,3.0,3.0]   mss.numNonzeros   //矩阵列的1-范数,||x||1 = sum(abs(xi));   //org.apache.spark.mllib.linalg.Vector = [6.0,9.0,12.0,15.0]   mss.normL1   //矩阵列的2-范数,||x||2 = sqrt(sum(xi.^2));   // org.apache.spark.mllib.linalg.Vector = [3.7416573867739413,5.385164807134504,7.0710678118654755,8.774964387392123]   mss.normL2   //矩阵列的方差   //org.apache.spark.mllib.linalg.Vector = [1.0,1.0,1.0,1.0]   mss.variance   //计算协方差   //covariance: org.apache.spark.mllib.linalg.Matrix =    //1.0  1.0  1.0  1.0     //1.0  1.0  1.0  1.0     //1.0  1.0  1.0  1.0     //1.0  1.0  1.0  1.0     var covariance:Matrix=rowMatirx.computeCovariance()    //计算拉姆矩阵rowMatirx^T*rowMatirx,T表示转置操作   //gramianMatrix: org.apache.spark.mllib.linalg.Matrix =     //14.0  20.0  26.0  32.0      //20.0  29.0  38.0  47.0      //26.0  38.0  50.0  62.0      //32.0  47.0  62.0  77.0     var gramianMatrix:Matrix=rowMatirx.computeGramianMatrix()   //对矩阵进行主成分分析,参数指定返回的列数,即主分成个数   //PCA算法是一种经典的降维算法   //principalComponents: org.apache.spark.mllib.linalg.Matrix =   //-0.5000000000000002  0.8660254037844388      //-0.5000000000000002  -0.28867513459481275    //-0.5000000000000002  -0.28867513459481287    //-0.5000000000000002  -0.28867513459481287     var principalComponents=rowMatirx.computePrincipalComponents(2)/**   * 对矩阵进行奇异值分解,设矩阵为A(m x n). 奇异值分解将计算三个矩阵,分别是U,S,V   * 它们满足 A ~= U * S * V', S包含了设定的k个奇异值,U,V为相应的奇异值向量   */  //   svd: org.apache.spark.mllib.linalg.SingularValueDecomposition[org.apache.spark.mllib.linalg.distributed.RowMatrix,org.apache.spark.mllib.linalg.Matrix] =   //SingularValueDecomposition(org.apache.spark.mllib.linalg.distributed.RowMatrix@688884e,[13.011193721236575,0.8419251442105343,7.793650306633694E-8],-0.2830233037672786  -0.7873358937103356  -0.5230588083704528    //-0.4132328277901395  -0.3594977469144485  0.5762839813994667     //-0.5434423518130005  0.06834039988143598  0.4166084623124157     //-0.6736518758358616  0.4961785466773299   -0.4698336353414313  )   var svd:SingularValueDecomposition[RowMatrix, Matrix]=rowMatirx.computeSVD(3,true)   //矩阵相乘积操作   var multiplyMatrix:RowMatrix=rowMatirx.multiply(Matrices.dense(4, 1, Array(1,2,3,4)))}

原创粉丝点击