赞
踩
标量:常量
本地向量
稀疏性向量:只存储非0值
稠密性向量:所有值都存储
用途:对比机器学习中特征向量
import org.apache.spark.mllib.linalg import org.apache.spark.mllib.linalg.Vectors /** * 本地向量主要两种类型构成----sparse稀疏性数据(只记录非0值,节省存储空间)------dense稠密性数据集 * (9,5,2,7)---(9,5,2,7) * (9,5,2,7)---(4,位置(0,1,2,3)(9,5,2,7)) * (9,5,0,2,7)---(5,位置(0,1,2,4)(9,5,2,7)) */ object localVector2 { def main(args: Array[String]): Unit = { val data: linalg.Vector = Vectors.dense(9,5,2,7) println(data) println(data(3)) val data1: linalg.Vector = Vectors.sparse(4,Array(0,1,2,3),Array(9,5,2,7)) println(data1) println(data1(0)) println(data1(2)) // 这个方法构造向量的时候需要注意的是,向量的值一定要是Double类型,否者会报错的哦。 val data2: linalg.Vector = Vectors.sparse(5,Seq((0,9.0),(1,5.0),(2,2.0),(4,7.0))) println(data2) println(data2(0)) println(data2(2)) } }
标签向量
import org.apache.spark.mllib.linalg import org.apache.spark.mllib.linalg.Vectors import org.apache.spark.mllib.regression.LabeledPoint /** * 机器学习中:特征(向量or矩阵)+类别标签列(标签向量labelpoint) * 要构造出下面两个标签向量 * (1.0,[2.0,0.0,6.0]):特征向量需要使用的是稠密性向量 * (2.0,(5,[0,1,2,3],[9.0,5.0,2.0,7.0])):特征向量的钩爪使用的是稀疏性向量 */ object labelpointVector2 { def main(args: Array[String]): Unit = { // 1. 创建出本地向量 val feature: linalg.Vector = Vectors.dense(2,0,6) // 2. 通过标签,本地向量构建标签向量 val label = LabeledPoint(1.0,feature) // 3. 打印标签向量 println(label) // 创建稀疏性向量 val vector2: linalg.Vector = Vectors.sparse(5,Array(0,1,2,3),Array(9,5,2,7)) // 通过标签,本地向量构建标签向量 val label2 = LabeledPoint(2,vector2) // 打印标签向量 println(label2) // 打印标签向量对应的类 println(label2.getClass) // 打印标签向量的标签 println(label2.label) // 获取标签向量的特征 val getFeature: linalg.Vector = label2.features // 打印特征 println(getFeature) // 获取特征向量中的索引是4对应的值 println(getFeature(4)) } }
libsvm:数据类型:存储稀疏性数据:引入SparkContext,使用的是MLUtils.loadLibSVMFile
本地矩阵
import org.apache.spark.mllib.linalg.{Matrices, Matrix} /** * 矩阵---维度2维度----具有整数类型的行和列索引和double类型的数值,存储在单机上 * Mllib中支持密集型矩阵,存储方式以列为主 * 非0值的存储以列主要顺序并且以CSC的压缩方式进行压缩存放 */ object localmatrix1 { def main(args: Array[String]): Unit = { // 1. 构建稠密型矩阵,通过稠密性向量来构建 // (numRows: Int, numCols: Int, values: Array[Double])第一个参数表示矩阵的行数,第二个参数表示矩阵的列数 // 第三个参数表示稠密型向量,注意因为是稠密型向量,向量中元素的个数要等于矩阵中元素的个数 val dense: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5, 2, 4, 6)) // 构建稀疏型的矩阵,下面是我对稀疏性矩阵的理解。 // numRows: Int,第一个参数代表的是矩阵的行数,例子中一共是3行 // numCols: Int,第二个参数代表的是矩阵的列数,例子中一共是2列 // colPtrs: Array[Int],第三个参数,数组中的每一个元素代表每一列及其前几列总元素的个数,为什么2列,却有3个列值,因为默认第一个元素的值是0 // 第二个元素表示矩阵第一列中非0值的个数,这里第一列有一个元素是非0的,故第二个元素为1, // 第三个元素代表得是矩阵第二列非0值得个数+第一列非0值的个数,这个第二列非0的个数为2,所以第三个元素是3 // rowIndices: Array[Int],表示各个非0值元素所在行,下标从0开始,有多少个非0值元素,就有多少个小标。 // values: Array[Double]),表示各个元素的值。 val spare: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 0), Array(9, 6, 8)) println(dense) /* 1.0 2.0 3.0 4.0 5.0 6.0 */ println(dense(2,0))//5 println(spare) /* 3 x 2 CSCMatrix (0,0) 9.0 (2,1) 6.0 (0,1) 8.0 */ //println(spare(2,1))//6 // 自己推导以下下面稀疏型矩阵的构成,是否跟上面的理解一致。 val spare1: Matrix = Matrices.sparse(3, 3, Array(0, 1, 3,4), Array(0, 2, 0,0), Array(9, 6, 8,33)) println(spare1) /* 3 x 3 CSCMatrix (0,0) 9.0 (2,1) 6.0 (0,1) 8.0 (0,2) 33.0 */ } }
分布式矩阵
分布式矩阵由长整型行列索引和双精度浮点型值数据组成,分布式存储在一个或多个RDD中,对于巨大的分布式矩阵来说,选择正确的存储格式非常重要,将一个分布式矩阵转化为另外一个不同格式需要混洗(shuffle),其代价很高。在MLlib实现了三类分布式矩阵存储格式,分别是行矩阵(RowMatrix)、行索引矩阵(IndexedRowMatrix)、三元组矩阵(CoordinateMatrix)和分块矩阵(BlockMatrix)等四种。
RowMatrix:行矩阵
RowMatrix
是最基础的分布式矩阵类型。每行是一个本地向量,行索引无实际意义(即无法直接使用)。数据存储在一个由行组成的RDD中,其中每一行都使用一个本地向量来进行存储。由于行是通过本地向量来实现的,故列数(即行的维度)被限制在普通整型(integer
)的范围内。在实际使用时,由于单机处理本地向量的存储和通信代价,行维度更是需要被控制在一个更小的范围之内。RowMatrix
可通过一个RDD[Vector]
的实例来创建。IndexedRowMatrix:列矩阵
IndexedRowMatrix
与RowMatrix
相似,但它的每一行都带有一个有意义的行索引值,这个索引值可以被用来识别不同行,或是进行诸如join之类的操作。其数据存储在一个由IndexedRow
组成的RDD里,即每一行都是一个带长整型索引的本地向量。import org.apache.spark.mllib.linalg import org.apache.spark.mllib.linalg.Vectors import org.apache.spark.mllib.linalg.distributed.{IndexedRow, IndexedRowMatrix, RowMatrix} import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /** * 基础的分布式矩阵--将矩阵存储起来了,不能按照行号访问 */ object RowMatrixTest2 { def main(args: Array[String]): Unit = { val conf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("RowMatrixTest2") val sc: SparkContext = new SparkContext(conf) // 1. 创建稠密型向量 val vec1: linalg.Vector = Vectors.dense(1,2,3) val vec2: linalg.Vector = Vectors.dense(4,5,6) // 2.构建RowMatrix val rddvec: RDD[linalg.Vector] = sc.parallelize(Seq(vec2, vec2)) val rowMatrix = new RowMatrix(rddvec) // 3. 打印rowMatrix中的元素 rowMatrix.rows.foreach(println) // [4.0,5.0,6.0] // [4.0,5.0,6.0] // 4. 构建IndexedRow对象 val row1: IndexedRow = IndexedRow(1,vec1) val row2: IndexedRow = IndexedRow(2, vec2) // 5. 通过sc.parallelize构建rdd val input: RDD[IndexedRow] = sc.parallelize(Seq(row1, row2)) // 如果直接敲类名,idea没有提示导包,说明这个类没有apply方法,前面加上new后就能自动导包了。 // 构建IndexedRowMatrix val indexedMatrix = new IndexedRowMatrix(input) indexedMatrix.rows.foreach(println) // IndexedRow(1,[1.0,2.0,3.0]) // IndexedRow(2,[4.0,5.0,6.0]) } }
坐标矩阵:Coordinate Matrix
坐标矩阵CoordinateMatrix
是一个基于矩阵项构成的RDD的分布式矩阵。每一个矩阵项MatrixEntry
都是一个三元组:(i: Long, j: Long, value: Double)
,其中i
是行索引,j
是列索引,value
是该位置的值。坐标矩阵一般在矩阵的两个维度都很大,且矩阵非常稀疏的时候使用。
CoordinateMatrix
实例可通过RDD[MatrixEntry]
实例来创建,其中每一个矩阵项都是一个(rowIndex, colIndex, elem)的三元组:
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry} import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object CoorinaterMatrixTest1 { def main(args: Array[String]): Unit = { //三元组矩阵(coordinateMatrix):是一个分布式矩阵,其实体集合是一个RDD,每一个实体是一个(i:Long,j:Ling,value:Double)三元组 //其中i代表行索引,j代表列索引,value代表实体值 //三元组矩阵常用于表示稀疏性比较高的计算中,是由RDD[MatrixEntry]来构建的。 val conf = new SparkConf().setMaster("local[*]").setAppName("RowMatrixTest") val sc = new SparkContext(conf) // 创建两个矩阵项ent1和ent2,每一个矩阵项都是由索引和值构成的三元组 val ent1 = new MatrixEntry(0,1,0.5) val ent2 = new MatrixEntry(2,2,1.8) // 创建RDD[MatrixEntry] val entries : RDD[MatrixEntry] = sc.parallelize(Array(ent1,ent2)) // 通过RDD[MatrixEntry]创建一个坐标矩阵 val coordMat: CoordinateMatrix = new CoordinateMatrix(entries) //打印 coordMat.entries.foreach(println) // MatrixEntry(0,1,0.5) // MatrixEntry(2,2,1.8) // 将coordMat进行转置 val transMat: CoordinateMatrix = coordMat.transpose() transMat.entries.foreach(println) /* MatrixEntry(1,0,0.5) MatrixEntry(2,2,1.8)*/ // 将坐标矩阵转换成一个索引行矩阵 val indexedRowMatrix = transMat.toIndexedRowMatrix() indexedRowMatrix.rows.foreach(println) // IndexedRow(1,(3,[0],[0.5])) // IndexedRow(2,(3,[2],[1.8])) } }
分块矩阵(Block Matrix)
分块矩阵是基于矩阵块MatrixBlock
构成的RDD的分布式矩阵,其中每一个矩阵块MatrixBlock
都是一个元组((Int, Int), Matrix)
,其中(Int, Int)
是块的索引,而Matrix
则是在对应位置的子矩阵(sub-matrix),其尺寸由rowsPerBlock
和colsPerBlock
决定,默认值均为1024。分块矩阵支持和另一个分块矩阵进行加法操作和乘法操作,并提供了一个支持方法validate()
来确认分块矩阵是否创建成功。
分块矩阵可由索引行矩阵IndexedRowMatrix
或坐标矩阵CoordinateMatrix
调用toBlockMatrix()
方法来进行转换,该方法将矩阵划分成尺寸默认为1024×1024的分块,可以在调用toBlockMatrix(rowsPerBlock, colsPerBlock)
方法时传入参数来调整分块的尺寸。
import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} object BlockMatrixTest1 { def main(args: Array[String]): Unit = { //分块矩阵:BlockMatrix是支持矩阵分块RDD的分布式矩阵,其中矩阵分块由((int,int),matrix)元祖所构成 //(int,int)是该部分矩阵所处的矩阵的索引位置,Matrix表示该索引位置上的子矩阵 //分块矩阵支持矩阵加法和乘法,并设有辅助函数验证用于检查矩阵是否设置正确。 val conf = new SparkConf().setMaster("local[*]").setAppName("RowMatrixTest") val sc = new SparkContext(conf) import org.apache.spark.mllib.linalg.distributed.{BlockMatrix, CoordinateMatrix, MatrixEntry} // 创建8个矩阵项,每一个矩阵项都是由索引和值构成的三元组 val ent1 = new MatrixEntry(0,0,1) val ent2 = new MatrixEntry(1,1,1) val ent3 = new MatrixEntry(2,0,-1) val ent4 = new MatrixEntry(2,1,2) val ent5 = new MatrixEntry(2,2,1) val ent6 = new MatrixEntry(3,0,1) val ent7 = new MatrixEntry(3,1,1) val ent8 = new MatrixEntry(3,3,1) // 创建RDD[MatrixEntry] val entries : RDD[MatrixEntry] = sc.parallelize(Array(ent1,ent2,ent3,ent4,ent5,ent6,ent7,ent8)) // 通过RDD[MatrixEntry]创建一个坐标矩阵 val coordMat: CoordinateMatrix = new CoordinateMatrix(entries) // 将坐标矩阵转换成2x2的分块矩阵并存储,尺寸通过参数传入 val matA: BlockMatrix = coordMat.toBlockMatrix(2,2).cache() // 可以用validate()方法判断是否分块成功 matA.validate() println(matA.toLocalMatrix) // 1.0 0.0 0.0 0.0 // 0.0 1.0 0.0 0.0 // -1.0 2.0 1.0 0.0 // 1.0 1.0 0.0 1.0 // 查看其分块情况 println(matA.numColBlocks)//2 println(matA.numRowBlocks)//2 // 计算矩阵A和其转置矩阵的积矩阵 val ata = matA.transpose.multiply(matA) println(ata.toLocalMatrix) /* 3.0 -1.0 -1.0 1.0 -1.0 6.0 2.0 1.0 -1.0 2.0 1.0 0.0 1.0 1.0 0.0 1.0*/ } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。