MLlib 支持存放在单机上的本地向量和矩阵,也支持通过多个RDD实现的分布式矩阵。因此MLlib的数据类型主要分为两大类:一个是本地单机向量;另一个是分布式矩阵。下面分别介绍一下这两大类都有哪些类型:
1、Local vector(本地向量)
(1)Vector
最基本的类型是Vector,该类型索引是从0开始的整型类型,值类型是double类型。并提供了两个实现:DenseVector
and SparseVector。
但是一把情况下都是推荐使用工厂方法来创建Vector。如下所示:
import org.apache.spark.mllib.linalg.{Vector, Vectors} // Create a dense vector (1.0, 0.0, 3.0). val dv: Vector = Vectors.dense(1.0, 0.0, 3.0) // Create a sparse vector (1.0, 0.0, 3.0) by specifying its indices and values corresponding to nonzero entries. val sv1: Vector = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)) // Create a sparse vector (1.0, 0.0, 3.0) by specifying its nonzero entries. val sv2: Vector = Vectors.sparse(3, Seq((0, 1.0), (2, 3.0)))
(2)LabeledPoint
LabeledPoint
类型一般用于有监督的学习算法当中,因为该类型会标记对应的标签。并且第一个参数就是标签,第二个参数是一个vector类型的数据。
val pos = LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0))
(3)Local matrix
Local matrix是有一个int类型的行索引和列索引,和double类型的值。并且存储在单机。Local matrix最基本的类型是Matrix
,也提供了两个实现类型:DenseMatrix
, and SparseMatrix
。但是依伴推荐使用工厂方法:Matrices
。 如下所示:
val dm: Matrix = Matrices.dense(3, 2, Array(1.0, 3.0, 5.0, 2.0, 4.0, 6.0)) val sm: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 1), Array(9, 6, 8))
2、Distributed matrix(分布式矩阵)
(1)RowMatrix
RowMatrix矩阵是一个基于行的,且没有索引的一个分布式矩阵,它的所有行组成一个RDD,它的每一行是一个local Vector。由于它的行类型是Local Vector,所以它的列应该是有限的。因为它必须能保证能够存储在一台机器内。如下所示:
val rows = sc.textFile("/user/liujiyu/spark/mldata1.txt") .map(_.split(' ') // 转换为RDD[Array[String]]类型 .map(_.toDouble)) // 转换为RDD[Array[Double]]类型 .map(line => Vectors.dense(line)) //转换为RDD[Vector]类型 // Create a RowMatrix from an RDD[Vector]. val mat: RowMatrix = new RowMatrix(rows)
(2)IndexedRowMatrix
IndexedRowMatrix类型与RowMatrix类型相似,但是IndexedRowMatrix拥有强大的行索引。IndexedRowMatrix能够由RDD[IndexedRow]创建,而IndexedRow是由(Long,Vector)封装。
val rows1 = sc.textFile("/user/liujiyu/spark/mldata1.txt") .map(_.split(' ') // 转换为RDD[Array[String]]类型 .map(_.toDouble)) // 转换为RDD[Array[Double]]类型 .map(line => Vectors.dense(line)) //转换为RDD[Vector]类型 .map((vc) => new IndexedRow(vc.size, vc)) //IndexedRow 带有行索引的矩阵,初始化的参数,列数和每一行的vector val irm = new IndexedRowMatrix(rows1)
(3)CoordinateMatrix(坐标矩阵)
CoordinateMatrix是一个分布式矩阵,它是由Entry组成的一个RDD,每一个Entry是由(i:Long,j:Long,value:Double)封装。这里的i表示的是行索引,j表示的是列索引,value表示的对应的值。CoordinateMatrix能够通过RDD[MatrixEntry]来创建。如果矩阵是非常大的而且稀疏,坐标矩阵一定是最好的选择。坐标矩阵则是通过RDD[MatrixEntry]实例创建,MatrixEntry是(long,long.Double)封装形式。如下所示:
对应的矩阵文件mldata1.txt:
1 1 4
2 6 2
1 3 4
2 3 4
2 8 1
3 2 4
5 1 3
读取该文件,并初始化为CoordinateMatrix:
val rows2 = sc.textFile("/user/liujiyu/spark/mldata1.txt") .map(_.split(' ') // 转换为RDD[Array[String]]类型 // .map(_.toDouble)) // 转换为RDD[Array[Double]]类型 .map(m => (m(0).toLong, m(1).toLong, m(2).toDouble)) .map((vc) => new MatrixEntry(vc._1, vc._2, vc._3)) //IndexedRow 带有行索引的矩阵,初始化的参数,列数和每一行的vector val cm = new CoordinateMatrix(rows2)
(4)BlockMatrix
BlockMatrix是一个分布式矩阵,它是由MatrixBlock
s组成的一个RDD 。这里的MatrixBlock
s是由字典类型((Int,Int),Matrix)组成。这里(Int,Int)是block的索引,Matrix是这个给定的尺寸rowsPerBlock
x colsPerBlock
的子矩阵。
BlockMatrix能够容易通过IndexedRowMatrix
or CoordinateMatrix
的toBlockMatrix
方法来创建。toBlockMatrix
方法默认创建的blocks的大小是1024*1024。用户可以通过传递参数的方式来改变这个blocks的大小,如:toBlockMatrix(rowsPerBlock, colsPerBlock)
。
//A BlockMatrix can be most easily created from an IndexedRowMatrix or CoordinateMatrix by calling toBlockMatrix. val matA: BlockMatrix = cm.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)