Spark MLlib分布式机器学习源码分析:矩阵向量

​    Spark是一个极为优秀的大数据框架,在大数据批处理上基本无人能敌,流处理上也有一席之地,机器学习则是当前正火热AI人工智能的驱动引擎,在大数据场景下如何发挥AI技术成为优秀的大数据挖掘工程师必备技能。本文结合机器学习思想与Spark框架代码结构来实现分布式机器学习过程,希望与大家一起学习进步~

目录

1.本地向量(Local vector)

2.标注点(Labeled point)

3.本地矩阵(Local Matrix)

4.分布式矩阵

1.RowMatrix

2.IndexedRowMatrix

3.CoordinateMatrix

4.BlockMatrix


 

        本文采用的组件版本为:Ubuntu 19.10、Jdk 1.8.0_241、Scala 2.11.12、Hadoop 3.2.1、Spark 2.4.5。有关框架介绍和环境配置可以参考以下内容:    

    大数据处理框架Hadoop、Spark介绍

    linux下Hadoop安装与环境配置

    linux下Spark安装与环境配置

老规矩先开启一系列Hadoop、Spark服务与Spark-shell窗口:

    MLlib既支持保存在单台机器上的本地向量和矩阵,也支持备份在一个或多个RDD中的分布式矩阵。本地向量和本地矩阵是简单的数据模型,作为公共接口提供。底层的线性代数操作通过Breezejblas提供。 在MLlib中,用于有监督学习的训练样本称为标注点(labeled point)。

1.本地向量(Local vector)

   一个本地向量拥有从0开始的integer类型的索引以及double类型的值,它保存在单台机器上面。MLlib支持两种类型的本地向量:稠密(dense)向量和稀疏(sparse)向量。 

  • 一个dense向量通过一个double类型的数组保存数据,这个数组表示向量的条目值(entry values);

  • sparse向量通过两个并行数组存储,例如,一个向量 (1.0, 0.0, 3.0)可以以稠密的格式保存为[1.0, 0.0, 3.0] 或者以稀疏的格式保存为(3, [0, 2], [1.0, 3.0]),其中3表示数组的大小。

import org.apache.spark.mllib.linalg.{Vector, Vectors}// 创建一个dense向量(1.0,0.0,3.0)val dv: Vector = Vectors.dense(1.0, 0.0, 3.0)// 创建一个sparse向量(1.0, 0.0, 3.0),并且指定它的索引和值val sv1: Vector = Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0))// 创建一个sparse向量(1.0, 0.0, 3.0),并且指定它的索引和值val sv2: Vector = Vectors.sparse(3, Seq((0, 1.0), (2, 3.0)))

2.标注点(Labeled point)

    一个标注点就是一个本地向量(或者是稠密的或者是稀疏的),这个向量和一个标签或者响应相关联。在MLlib中,标注点用于有监督学习算法。我们用一个double存储标签,这样我们就可以在回归和分类中使用标注点。对于二分类,一个标签可能是0或者是1;对于多分类,一个标签可能代表从0开始的类别索引。

 在MLlib中,一个标注点通过样本类LabeledPoint表示。

@Since("0.8.0")@BeanInfocase class LabeledPoint @Since("1.0.0") (    @Since("0.8.0") label: Double,    @Since("1.0.0") features: Vector) {  override def toString: String = {    s"($label,$features)"  }}

    下面是使用LabeledPoint的一个例子。

import org.apache.spark.mllib.linalg.Vectorsimport org.apache.spark.mllib.regression.LabeledPoint// 创建一个标签为正类,数据为dense向量的标签点val pos = LabeledPoint(1.0, Vectors.dense(1.0, 0.0, 3.0))// 创建一个标签为负类,数据为sparse向量的标签点val neg = LabeledPoint(0.0, Vectors.sparse(3, Array(0, 2), Array(1.0, 3.0)))

    在现实的应用中,训练数据是稀疏的情况非常常见,MLlib支持读取训练数据存储为LIBSVM格式。

3.本地矩阵(Local Matrix)

    一个本地矩阵拥有Integer类型的行和列索引以及Double类型的值。MLlib支持稠密矩阵和稀疏矩阵两种。稠密矩阵将条目(entry)值保存为单个double数组,这个数组根据列的顺序存储。稀疏矩阵的非零条目值保存为压缩稀疏列(Compressed Sparse Column ,CSC)格式,这种格式也是以列顺序存储。例如下面的稠密矩阵:

    这个稠密矩阵保存为一维数组[1.0, 3.0, 5.0, 2.0, 4.0, 6.0],数组大小为(3,2)。本地矩阵的基类是Matrix,它提供了两种实现:DenseMatrix和SparseMatrix。推荐使用Matrices的工厂方法来创建本地矩阵。下面是一个实现的例子:

import org.apache.spark.mllib.linalg.{Matrix, Matrices}// 创建一个dense矩阵 ((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))// 创建一个sparse矩阵 ((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))

4.分布式矩阵

    一个分布式矩阵(Distributed matrix)拥有long类型的行和列索引,以及double类型的值,分布式的存储在一个或多个RDD中。选择正确的格式存储大型分布式矩阵是非常重要的。将一个分布式矩阵转换为另外一个格式可能需要一个全局的shuffle,这是非常昂贵的。到目前为止,已经实现了三种类型的分布式矩阵。

  • 1.RowMatrix

 RowMatrix是一个面向行的分布式矩阵,它没有有意义的行索引。它的行保存为一个RDD,每一行都是一个本地向量。因为每一行保存为一个本地向量,所以列数限制在了整数范围。

  一个RowMatrix可以通过RDD[Vector]实例创建。创建完之后,我们可以计算它的列的统计和分解。QR分解的形式为A=QR,其中Q是一个正交矩阵, R是一个上三角矩阵。下面是一个RowMatrix的例子。

import org.apache.spark.mllib.linalg.Vectorimport org.apache.spark.mllib.linalg.distributed.RowMatrixval rows: RDD[Vector] = sc.parallelize(Seq(sv1,sv1)) // 一个本地向量的RDD// 由RDD创建一个RowMatrixval mat: RowMatrix = new RowMatrix(rows)// 获取size大小val m = mat.numRows()val n = mat.numCols()// QR分解val qrResult = mat.tallSkinnyQR(true)
  • 2.IndexedRowMatrix

 IndexedRowMatrix在RowMatrix基础上拥有行索引。索引的行保存为一个RDD[IndexedRow],其中IndexedRow是一个参数为(Long, Vector)的样本类,所以每一行通过它的索引以及一个本地向量表示。

  一个IndexedRowMatrix可以通过RDD[IndexedRow]实例创建,并且一个IndexedRowMatrix可以通过去掉它的行索引,转换成RowMatrix。下面是一个例子:

import org.apache.spark.mllib.linalg.distributed.{IndexedRow, IndexedRowMatrix, RowMatrix}val rows: RDD[IndexedRow] = ... // 带有索引Row的RDD// 由一个RDD[IndexedRow]创建一个IndexedRowMatrixval mat: IndexedRowMatrix = new IndexedRowMatrix(rows)// 获取size大小val m = mat.numRows()val n = mat.numCols()// 去掉行索引val rowMat: RowMatrix = mat.toRowMatrix()

    IndexedRow这个样本类的代码如下:

case class IndexedRow(index: Long, vector: Vector)
  • 3.CoordinateMatrix

    CoordinateMatrix是一个分布式矩阵,它的条目保存为一个RDD。每一个条目是一个(i: Long, j: Long, value: Double)格式的元组,其中i表示行索引,j表示列索引,value表示条目值。CoordinateMatrix应该仅仅在矩阵维度很大并且矩阵非常稀疏的情况下使用。

    CoordinateMatrix可以通过RDD[MatrixEntry]实例创建,其中MatrixEntry是(Long, Long, Double)的包装。CoordinateMatrix可以转换成IndexedRowMatrix。下面是一个例子:

import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}val entries: RDD[MatrixEntry] = sc.parallelize(Seq(MatrixEntry(1,1,1.0),MatrixEntry(1,1,1.0)))// 创建一个matrix entries RDD// 从RDD[MatrixEntry]中创建一个CoordinateMatrixval mat: CoordinateMatrix = new CoordinateMatrix(entries)// 获取大小val m = mat.numRows()val n = mat.numCols()// 将其转换为一个行为sparse矩阵的IndexRowMatrixval indexedRowMatrix = mat.toIndexedRowMatrix()

    MatrixEntry这个样本类的代码如下:

case class MatrixEntry(i: Long, j: Long, value: Double)
  • 4.BlockMatrix

    BlockMatrix是一个分布式矩阵,它的保存为一个MatrixBlocks的RDD。MatrixBlock是一个((Int, Int), Matrix)类型的元组,其中(Int, Int)代表块的索引,Matrix代表子矩阵。BlockMatrix支持诸如add和multiply等方法。BlockMatrix还有一个帮助方法validate,用来判断一个BlockMatrix是否正确的创建。

    可以轻松的通过调用toBlockMatrix从一个IndexedRowMatrix或者CoordinateMatrix创建一个BlockMatrix。toBlockMatrix默认创建1024 * 1024大小的块,用户可以手动修个块的大小。下面是一个例子:

import org.apache.spark.mllib.linalg.distributed.{BlockMatrix, CoordinateMatrix, MatrixEntry}val entries: RDD[MatrixEntry] = sc.parallelize(Seq(MatrixEntry(1,1,1.0),MatrixEntry(1,1,1.0)))// 创建一个matrix entries RDD// 从RDD[MatrixEntry]中创建一个CoordinateMatrixval coordMat: CoordinateMatrix = new CoordinateMatrix(entries)// 将CoordinateMatrix转换为一个BlockMatrixval matA: BlockMatrix = coordMat.toBlockMatrix().cache()// 当BlockMatrix正确建立时才有效matA.validate() // 有效情况下不输出// 计算 A^T*Aval ata = matA.transpose.multiply(matA)

    Spark矩阵向量的内容至此结束,有关Spark的基础文章可参考前文:

    Spark大数据分布式处理实战笔记(一):快速开始

    Spark大数据分布式处理实战笔记(二):RDD、共享变量

    Spark大数据分布式处理实战笔记(三):Spark SQL

    Spark大数据分布式处理实战笔记(四):Spark Streaming

    Spark大数据分布式机器学习处理实战

    Spark大数据分布式图计算处理实战

 

 

    参考链接:

    https://github.com/endymecy

    http://spark.apache.org/docs/latest/mllib-data-types.html

 

 

数据分析与挖掘

数据结构与算法

机器学习与大数据组件

欢迎关注,感谢“在看”,随缘稀罕~

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值