Apache Spark MLlib学习笔记(一)MLlib数据存储Vector/Matrix/LablePoint

来源:互联网 发布:女装淘宝销量排行榜 编辑:程序博客网 时间:2024/05/24 22:45

在进行具体算法模型剖析之前,首先要清楚MLlib采用的数据结构,spark官方文档也提供了英文的数据结构介绍,地址如下:
http://spark.apache.org/docs/latest/mllib-data-types.html

MLlib支持单机local vectors 和 matrices以及分布式矩阵。其中local vectors 和 matrices是一种用于公共接口的简单数据结构。内部的数学运算是由Breeze 和 jblas提供的。在有监督学习中使用的某个训练样例在MLlib中被称为一个“labeled point”。
1、local vector
MLlib的本地向量主要分为Dense和Sparse两种,前者是用来保存稠密向量,后者是用来保存稀疏向量。例如,对于向量 (1.0, 0.0, 3.0) , [1.0, 0.0, 3.0] 代表稠密向量,(3, [0, 2], [1.0, 3.0])代表稀疏向量,其中3代表的是总长度,0,2代表的是非零元素的位置。
其创建方式主要有三种,以下为其Scala代码:

import org.apache.spark.mllib.linalg.{Vector, Vectors}// 创建稠密向量 (1.0, 0.0, 3.0).val dv: Vector = Vectors.dense(1.0, 0.0, 3.0)// 创建稀疏向量 (1.0, 0.0, 3.0) val sv1: Vector = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0))// 创建稀疏向量 (1.0, 0.0, 3.0) val sv2: Vector = Vectors.sparse(3, Seq((0, 1.0), (2, 3.0)))

需要注意的是,Scala默认会导入scala.collection.immutable.Vector包,所以必须手动导入org.apache.spark.mllib.linalg.Vector包才能使用MLlib的vector包。

2、Labeled point
一个向量标签是一个带有标签的紧密或稀疏的local vector。在MLlib中,labeled points被用于有监督学习,我们使用double来存储标签,因此在分类和回归中都可以使用,在二值分类中它可以是0或1,在多值分类中则是从0开始的一个序列,如0,1,2,3······
创建向量标签的Scala代码如下:

import org.apache.spark.mllib.linalg.Vectorsimport 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)))

在实践中稀疏训练数据是十分常见的,MLlib支持从LIBSVM格式的文件中直接读取训练数据,LIBSVM格式是LIBSVM 和LIBLINEAR的默认数据格式,这种格式每行代表一个稀疏属性的标签向量,格式如下:

label index1:value1 index2:value2 ...

按照这种格式读入标签的方法如下:

import org.apache.spark.mllib.regression.LabeledPointimport org.apache.spark.mllib.util.MLUtilsimport org.apache.spark.rdd.RDDval examples: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

3、Local matrix
本地矩阵具有整型的行列下标和double型的值,MLlib支持密集向量
矩阵
可以被表示为一维的array [1.0, 3.0, 5.0, 2.0, 4.0, 6.0] ,矩阵的大小为 (3, 2)。
Scala创建矩阵的代码如下;

import org.apache.spark.mllib.linalg.{Matrix, Matrices}// 创建密集矩阵((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))val dm: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0))

4、分布式矩阵
分布式矩阵的行列索引是long类型的,数值是double型,它存储在一个或多个RDD中,选择合适的格式存储大型分布式矩阵非常重要。目前MLlib提供了三种类型的分布式矩阵。
最基本的类型叫做RowMatrix,它没有有意义的行索引,每行是一个本地向量,如果假设列的数量不是非常大,在单个节点上可以被存储和处理。 IndexedRowMatrix 类似于前者,但是可以按照行来索引。CoordinateMatrix是一个coordinate list (COO)格式的分布式矩阵,适用于特别稀疏的矩阵。

①RowMatrix
RowMatrix是一个行索引的分布式矩阵,但是它的行索引并没有实际意义。每行都是一个本地向量,因为每行都被一个本地向量代表,所以列的数量收到整数最大值的限制,但是实际操作中应该远小于上限值。

import org.apache.spark.mllib.linalg.Vectorimport org.apache.spark.mllib.linalg.distributed.RowMatrixval rows: RDD[Vector] = ... // an RDD of local vectors// Create a RowMatrix from an RDD[Vector].val mat: RowMatrix = new RowMatrix(rows)// Get its size.val m = mat.numRows()val n = mat.numCols()

②IndexedRowMatrix
IndexedRowMatrix和RowMatrix类似,但是行索引有其实际意义。每一行被它的索引和一个本地向量表示。

import org.apache.spark.mllib.linalg.distributed.{IndexedRow, IndexedRowMatrix, RowMatrix}val rows: RDD[IndexedRow] = ... // an RDD of indexed rows// Create an IndexedRowMatrix from an RDD[IndexedRow].val mat: IndexedRowMatrix = new IndexedRowMatrix(rows)// Get its size.val m = mat.numRows()val n = mat.numCols()// Drop its row indices.val rowMat: RowMatrix = mat.toRowMatrix()

③CoordinateMatrix
CoordinateMatrix的每一个元素都是一个元组 (i: Long, j: Long, value: Double),i是行,j是列,value是值。只用于特别稀疏的矩阵。

import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}val entries: RDD[MatrixEntry] = ... // an RDD of matrix entries// Create a CoordinateMatrix from an RDD[MatrixEntry].val mat: CoordinateMatrix = new CoordinateMatrix(entries)// Get its size.val m = mat.numRows()val n = mat.numCols()// Convert it to an IndexRowMatrix whose rows are sparse vectors.val indexedRowMatrix = mat.toIndexedRowMatrix()

最后介绍BlockMatrix
BlockMatrix是一个元组((Int, Int), Matrix),其中 (Int, Int)是块的下标,Matrix是给定下标rowsPerBlock x colsPerBlock的子矩阵。BlockMatrix支持add 和 multiply方法和其他矩阵进行运算。还有一个validate方法用于检查BlockMatrix创建的是否合适。
BlockMatrix 一般很容易通过 toBlockMatrix方法从IndexedRowMatrix 或 CoordinateMatrix变换出来,toBlockMatrix方法默认创建一个 1024 x 1024大小的矩阵。用户可以通过toBlockMatrix(rowsPerBlock, colsPerBlock)来自行定义大小。

import org.apache.spark.mllib.linalg.distributed.{BlockMatrix, CoordinateMatrix, MatrixEntry}val entries: RDD[MatrixEntry] = ... // an RDD of (i, j, v) matrix entries// Create a CoordinateMatrix from an RDD[MatrixEntry].val coordMat: CoordinateMatrix = new CoordinateMatrix(entries)// Transform the CoordinateMatrix to a BlockMatrixval matA: BlockMatrix = coordMat.toBlockMatrix().cache()// Validate whether the BlockMatrix is set up properly. Throws an Exception when it is not valid.// Nothing happens if it is valid.matA.validate()// Calculate A^T A.val ata = matA.transpose.multiply(matA)
0 0