机器学习库支持本地向量和矩阵存储在单台机器上,
MLlib支持本地的向量和矩阵存储在一个单独的机器,以及分布式矩阵由一个或多个RDD。
本地向量和矩阵作为公共接口的简单的数据模型。
底层由Breeze和jblas提供线性代数操作。
一个训练的例子中使用监督学习在MLlib称为“标记点”(labeled point)
本地向量(Local vector)
本地向量是由一个整数类型和从零开始的索引,浮点类型的值,存储在一个单独的机器。
MLlib支持两种类型的本地向量:密集型和稀疏型。
密集型向量是由浮点类型数组,表示全部值,而稀疏型向量是由两个并行的数组:索引和值。
例如,一个向量(1.0, 0.0, 3.0)表示为密集型是[1.0, 0.0, 3.0],为稀疏型是(3, [0, 2], [1.0, 3.0]),是大小为3的向量。
最基本的本地向量类是Vector,我们提供了两种类型的实现:DenseVector 和 SparseVector。我们推荐使用实现工厂方法Vectors去创建本地向量。
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)
dv: org.apache.spark.mllib.linalg.Vector = [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))
sv1: org.apache.spark.mllib.linalg.Vector = (3,[0,2],[1.0,3.0])
sv1.toArray
res3: Array[Double] = Array(1.0, 0.0, 3.0)
sv1.size
res6: Int = 3
// 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)))
sv2: org.apache.spark.mllib.linalg.Vector = (3,[0,2],[1.0,3.0])
sv2.toArray
res7: Array[Double] = Array(1.0, 0.0, 3.0)
注意:scala 默认引入scala.collection.immutable.Vector,因此你需要显性的引入org.apache.spark.mllib.linalg.Vector作为MLlib向量
标记点(Labeled point)
一个标记点是本地向量,是密集或稀疏,与一个标签/响应有关。
在MLlib,标记点被用于监督学习算法中。我们使用一个字符型存储一个标签,因此我们可以在回归和分类中使用标签点。
对于二元分类,一个标签应该是0(负数)或者1(整数)。对于多元分类,标签应该是从0,1,2,3..开始的索引类。
一个标签点使用样例类LabeledPoint表示
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
// Create a labeled point with a positive label and a dense feature vector.
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])
// Create a labeled point with a negative label and a sparse feature vector.
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]))
稀疏数据(Sparse data)
在实践中经常使用稀疏训练集数据。MLlib支持读取训练集示例存储于LIBSVM格式,LIBSVM和LIBLINEAR作为默认的格式。它是一种文本格式,每一行代表一个标记稀疏特征向量使用以下格式:
label index1:value1 index2:value2 ...
索引是从1开始,升序递增的。加载后,特征索引转换成从0开始。
MLUtils.loadLibSVMFile读取训练示例数据存储到LIBSVM格式。
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.rdd.RDD
val examples: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "file:///home/cluster/apps/spark/spark-1.4.1/data/mllib/sample_libsvm_data.txt")
examples.collect
Array[org.apache.spark.mllib.regression.LabeledPoint] = Array((0.0,(692,[127,128,129,130,131,154,155,156,157,158,159,181,182,183,184,185,186,187,188,189,207,208,209,210,211,212,213,214,215,216,217,235,236,237,238,239,240,241,242,243,244,245,262,263,264,265,266,267,268,269,270,271,272,273,289,290,291,292,293,294,295,296,297,300,301,302,316,317,318,319,320,321,328,329,330,343,344,345,346,347,348,349,356,357,358,371,372,373,374,384,385,386,399,400,401,412,413,414,426,427,428,429,440,441,442,454,455,456,457,466,467,468,469,470,482,483,484,493,494,495,496,497,510,511,512,520,521,522,523,538,539,540,547,548,549,550,566,567,568,569,570,571,572,573,574,575,576,577,578,594,595,596,597,598,599,600,601,602,603,604,622,623,624,625,626,627,628,629,630,651,652,653,654,655,656,657],[51.0,159.0,2...
本地矩阵(Local matrix)
本地矩阵是由一个整数类型行和列索引以及浮点类型的值,存储在一个单独的机器。
MLlib支持稠密矩阵的条目的值,存储在一个双数组列为主的顺序。稀疏矩阵的非零项值存储在压缩稀疏列(CSC)格式列为主的秩序
例如,如下密集矩阵
是存储在一维数组[1.0, 3.0, 5.0, 2.0, 4.0, 6.0],矩阵大小是3行2列。
本地矩阵是由基本类Matrix,我们提供两种实现:DenseMatrix和SparseMatrix。我们推荐使用Matrices工厂类方法创建本地矩阵。
记住,在MLlib中,本地矩阵存储在列为主的秩序中
import org.apache.spark.mllib.linalg.{Matrix, Matrices}
// Create a dense matrix ((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))
def
sparse(numRows: Int, numCols: Int, colPtrs: Array[Int], rowIndices: Array[Int], values: Array[Double]): Matrix
Creates a column-major sparse matrix in Compressed Sparse Column (CSC) format.
numRows
number of rows
numCols
number of columns
colPtrs
the index corresponding to the start of a new column
rowIndices
the row index of the entry
values
non-zero matrix entries in column major
// Create a sparse matrix ((9.0, 0.0), (0.0, 8.0), (0.0, 6.0))
val sm: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3), Array(0, 2, 1), Array(9, 6, 8))
sm: org.apache.spark.mllib.linalg.Matrix =
3 x 2 CSCMatrix
(0,0) 9.0
(2,1) 6.0
(1,1) 8.0
sm.toArray
res6: Array[Double] = Array(9.0, 0.0, 0.0, 0.0, 8.0, 6.0)
分布式矩阵(Distributed matrix)
一个分布式矩阵由长整型行和索引列以及浮点数类型值,分布的存储在一个或者多个RDD中。选择正确的格式来存储和分布式矩阵是非常重要的。
将一个分布式矩阵转换成不同格式需要一个全部的shuffle,这是相当消耗资源的。到目前为止,已经实现了3种分布式矩阵类型。
最基本的类型是RowMatrix。RowMatrix是面向行的分布式矩阵,没有意义的行索引,例如,特征向量的集合。是由一个多行RDD,每行是本地向量。我们假设一个RowMatrix中列数不多,以至于单个本地向量可以与driver端合理的通信,也能使用单个节点存储/操作。
IndexedRowMatrix是类似于RowMatrix,但具有行索引,可以用于确定行以及执行join操作。
CoordinateMatrix是分布式矩阵存储在coordinate列表(COO)格式,是由全部的RDD组成。
注意:
底层的抽样分布的矩阵必须是确定的,因为我们缓存矩阵大小。一般使用非确定性抽样可能导致错误。
行矩阵(RowMatrix)
RowMatrix是面向行的分布式矩阵,没有意义的行索引,由一个RDD的行,每一行是一个本地的向量。由于每一行是用本地向量表示,列数是由整数范围限定的,但在实际情况中是很小的。RowMatrix可以使用RDD[Vector]实例创建。然后我们可以计算它的列汇总统计和分解。QR分解是形式为A = QR,其中Q是一个正交矩阵,R是一个R是一个上三角矩阵。对于奇异值分解(SVD)和主成分分析(PCA),请参考降维。
import org.apache.spark.mllib.linalg.Vector import org.apache.spark.mllib.linalg.distributed.RowMatrix // an RDD of local vectors val rows: RDD[Vector] = sc.makeRDD(Seq(Vectors.dense(1.0, 0.0, 3.0))) rows: org.apache.spark.rdd.RDD[org.apache.spark.mllib.linalg.Vector] = ParallelCollectionRDD[1] at makeRDD at <console>:24 // Create a RowMatrix from an RDD[Vector]. val mat: RowMatrix = new RowMatrix(rows) // Get its size. val m = mat.numRows() n: Long = 1 val n = mat.numCols() n: Long = 3
索引行矩阵(IndexedRowMatrix)
索引行矩阵类似于行矩阵,但有意义的行索引。是由一个索引行RDD,所以每一行代表了其索引(long-typed)和本地的一个向量。IndexedRowMatrix可以由RDD[IndexedRow]实例创建,IndexedRow是通过(Long, Vector)包装的。通过删除行索引,可将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分布式矩阵由一个RDD的条目。
每一条目是由一个(i: Long, j: Long, value: Double)的元组构成,其中i 是行索引,j是列索引,value是条目是值。
CoordinateMatrix应该只有当使用矩阵的两个维度是巨大的和矩阵是非常稀少的。
CoordinateMatrix可以通过RDD[MatrixEntry]实例创建,而MatrixEntry是由(Long, Long, Double)包装的。通过调用toIndexedRowMatrix方法,可将CoordinateMatrix转换成具有稀释行的IndexedRowMatrix。
目前对于CoordinateMatrix其他的计算还不支持。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)
块矩阵是由MatrixBlocks RDD组成的分布式矩阵,MatrixBlocks是由一个((Int, Int), Matrix)的元组,而(Int, Int) 是块的索引,Matrix是给定rowsPerBlock x colsPerBlock大小的子矩阵。
块矩阵支持与另一个块矩阵相加和相乘的方法。
块矩阵也具有一个用于验证BlockMatrix是否合理创建的工具函数
通过调用toBlockMatrix,BlockMatrix更容易由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 BlockMatrix val 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)
作者:stark_summer
出处:http://blog.csdn.net/stark_summer/article/details/48916031