数据类型——基于RDD的API

  • 本地矢量
  • 标记点
  • 本地矩阵
  • 分布式矩阵
    • RowMatrix(行矩阵)
    • IndexedRowMatrix(索引行矩阵)
    • CoordinateMatrix(坐标矩阵)
    • BlockMatrix(块矩阵)

  MLlib 支持存储在单台机器上的本地向量和矩阵,以及由一个或多个 RDD 支持的分布式矩阵。本地向量和本地矩阵是用作公共接口的简单数据模型。有监督学习中使用的训练示例在MLlib中称为"标记点"。

一、本地矢量(Local Vector)

MLlib 支持两种类型的局部向量:密集和稀疏。密集向量由表示其条目值的双精度数组支持,而稀疏向量由两个并行数组支持:索引和值。例如:向量(1.0, 0.0, 3.0)

  • 稠密向量的表现形式:[1.0, 0.0, 3.0];
  • 稀疏向量的表现形式:(3,[0,2],[1.0,3.0]),其中3表示向量长度,[0,2]是数组非0向量的索引,而[1.0,3.0]是索引对应的向量值;

本地矢量都以 org.apache.spark.mllib.linalg.Vector 为基类,提供了两个实现:DenseVectorSparseVector,分别对应稠密向量和稀疏向量。

%spark
//使用Vectors工具类下定义的工厂方法来创建本地向量
import org.apache.spark.mllib.linalg.{Vector, Vectors}
//创建一个本地稠密向量
val dv:Vector = Vectors.dense(2.0,0.0,8.0)
//创建一个本地稀疏向量
val sv1:Vector = Vectors.sparse(3,Array(0,2),Array(2.0,8.0))
//另一种创建本地稀疏向量的方法,参数由长度和一个键值对组成(index,elem),每个键值对都是一个非0的向量
val sv2:Vector = Vectors.sparse(3,Seq((0,2.0),(2,8.0)))

注意:Scala会默认引入 scala.collection.immutable.Vector 这个包,所以必须要显示引org.apache.spark.mllib.linalg.Vector来使用MLlib提供的向量类型。

二、标记点(Labeled Point)

  标记点是(Label/Response)的本地向量,可以是稠密或稀疏的。在 MLlib 中,标记点用于监督学习算法。由于标签是使用双精度浮点型来存储的,因此可以在回归和分类问题中使用标记点。对于二元分类问题,标签应为(负/0)或(正/1);对于多类分类,标签应是从零开始的类索引:0,1,2 。。。

标记点的实现类是:org.apache.spark.mllib.regression.LabeledPoint

%spark
//创建一个被标记为1.0的稠密向量标记点,创建一个被标记为0的稀疏向量
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
val temp1 = LabeledPoint(1.0,Vectors.dense(2.0,0.0,8.0))
val temp2 = LabeledPoint(0.0,Vectors.sparse(3,Seq((0,2.0),(2,8.0))))

在实践中,稀疏的训练数据非常普遍。MLlib 支持读取以格式存储的训练示例,这是LIBSVM 和LIBLINEAR使用的默认格式。它是一种文本格式,其中每行使用以下格式表示标记的稀疏特征向量:LIBSVM

label index1:value1 index2:value2 ...

其中 label是该样本点的标签值,一系列 index:value对则代表了该样本向量中所有非零元素的索引和元素值。这里需要特别注意的是,index是以1开始并递增的。

MLlib在org.apache.spark.mllib.util.MLUtils工具类中提供了读取LIBSVM格式的方法loadLibSVMFile,示例如下:

%spark
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.rdd.RDD
//使用MLUtils类中的loadLibSVMFile方法读取LIBSVM格式的数据
//sample_libsvm_data.txt为spark自带的一个示例
val examples: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")

三、本地矩阵(Local Matrix)

本地矩阵具有整数类型的行和列索引以及存储在单台计算机上的双精度浮点型值。MLlib 支持稠密矩阵(其条目值按列主序存储在单个双精度数组中)和稀疏矩阵(其非零条目值以压缩稀疏列 (CSC) 格式按列主序存储)。本地矩阵的基类是org.apache.spark.mllib.linalg.MatrixDenseMatrixSparseMatrix均是它的实现类,和本地向量类似,MLlib也为本地矩阵提供了相应的工具类Matrices,调用工厂方法即可创建实例:

%spark
import org.apache.spark.mllib.linalg.{Matrix,Matrices}
//创建一个3行2列的稠密矩阵,注意是列先序的
val dm:Matrix = Matrices.dense(3,2,Array(1.0,3.0,5.0,2.0,4.0,6.0)) 输出:
dm: org.apache.spark.mllib.linalg.Matrix =
1.0 2.0
3.0 4.0
5.0 6.0

同样创建稀疏矩阵:

// 创建一个3行2列的稀疏矩阵[ [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

四、分布式矩阵(Distributed Matrix)

分布式矩阵由长整型的行列索引值和双精度浮点型的元素值组成。它可以分布式地存储在一个或多个RDD上,MLlib提供了三种分布式矩阵的存储方案:行矩阵RowMatrix,索引行矩阵IndexedRowMatrix、坐标矩阵CoordinateMatrix和分块矩阵BlockMatrix。它们都属于org.apache.spark.mllib.linalg.distributed包。

1、行矩阵(RowMatrix)

行矩阵RowMatrix是最基础的分布式矩阵类型。每行是一个本地向量,行索引无实际意义(即无法直接使用)。数据存储在一个由行组成的RDD中,其中每一行都使用一个本地向量来进行存储。由于行是通过本地向量来实现的,故列数(即行的维度)被限制在普通整型(integer)的范围内。在实际使用时,由于单机处理本地向量的存储和通信代价,行维度更是需要被控制在一个更小的范围之内。RowMatrix可通过一个RDD[Vector]的实例来创建,如下代码所示:

%spark
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.linalg.{Vector,Vectors}
import org.apache.spark.mllib.linalg.distributed.RowMatrix
//首先创建两个本地稠密向量
val dv1:Vector = Vectors.dense(1.0,2.0,3.0)
val dv2:Vector = Vectors.dense(2.0,3.0,4.0)
val rows:RDD[Vector] = sc.parallelize(Array(dv1,dv2))
//通过RDD[Vector]创建一个行矩阵
val mat:RowMatrix = new RowMatrix(rows)
//使用numRows和numCols方法分别输出行矩阵的行、列
mat.numRows()
mat.numCols()
//打印行矩阵
mat.rows.foreach(println)

在获得RowMatrix的实例后,我们可以通过其自带的computeColumnSummaryStatistics()方法获取该矩阵的一些统计摘要信息,并可以对其进行QR分解SVD分解PCA分解。 统计摘要信息的获取如下代码段所示(接上代码段):

//通过computeColumnSummaryStatistics()方法获取统计摘要
val summary = mat.computeColumnSummaryStatistics()
//根据统计信息获取行数
summary.count
//获取最大向量
summary.max
//获取方差向量
summary.variance
//平均向量
summary.mean
//L1范数向量
summary.normL1

2、索引行矩阵(IndexedRowMatrix)

索引行矩阵IndexedRowMatrixRowMatrix相似,但它的每一行都带有一个有意义的行索引值,这个索引值可以被用来识别不同行,或是进行诸如join之类的操作。其数据存储在一个由IndexedRow组成的RDD里,即每一行都是一个带长整型索引的本地向量。IndexedRowMatrix的实例可以通过RDD[IndexedRow]实例来创建。

%spark
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.linalg.{Vector,Vectors}
import org.apache.spark.mllib.linalg.distributed.{IndexedRow, IndexedRowMatrix}
//1、首先创建两个本地稠密向量
val dv1:Vector = Vectors.dense(1.0,2.0,3.0)
val dv2:Vector = Vectors.dense(2.0,3.0,4.0)
// 2、通过本地向量dv1 dv2来创建对应的IndexedRow
// 在创建时可以给定行的索引值,如这里给dv1的向量赋索引值1,dv2赋索引值2
val idxr1 = IndexedRow(1,dv1)
val idxr2 = IndexedRow(2,dv2)
//3、 通过IndexedRow创建RDD[IndexedRow]
val idxrows = sc.parallelize(Array(idxr1,idxr2))
//4、 通过RDD[IndexedRow]创建一个索引行矩阵
val idxmat: IndexedRowMatrix = new IndexedRowMatrix(idxrows)
//5、 打印输出索引行矩阵
idxmat.rows.foreach(println)

3、坐标矩阵(CoordinateMatrix)

坐标矩阵CoordinateMatrix是一个基于矩阵项构成的RDD的分布式矩阵。每一个矩阵项MatrixEntry都是一个三元组:(i: Long, j: Long, value: Double),其中i是行索引,j是列索引,value是该位置的值。坐标矩阵一般在矩阵的两个维度都很大,且矩阵非常稀疏的时候使用

CoordinateMatrix实例可通过RDD[MatrixEntry]实例来创建,其中每一个矩阵项都是一个(rowIndex, colIndex, elem)的三元组:

%spark
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}
//1、创建两个矩阵项,每个矩阵项由索引和值构成三元组
val ent1 = new MatrixEntry(0,1,0.5)
val ent2 = new MatrixEntry(2,2,1.8)
//2、创建RDD[MatrixEntry]
val entries : RDD[MatrixEntry] = sc.parallelize(Array(ent1,ent2))
//3、通过RDD[MatrixEntry]创建一个坐标矩阵
val coordMat: CoordinateMatrix = new CoordinateMatrix(entries)
//4、打印
coordMat.entries.foreach(println)

坐标矩阵可以通过transpose()方法对矩阵进行转置操作,并可以通过自带的toIndexedRowMatrix()方法转换成索引行矩阵IndexedRowMatrix

//5、将coordMat进行转置
val transMat: CoordinateMatrix = coordMat.transpose()
//打印输出
transMat.entries.foreach(println)
//6、将坐标矩阵转换成一个索引行矩阵
val indexedRowMatrix = transMat.toIndexedRowMatrix()
indexedRowMatrix.rows.foreach(println)

4、分块矩阵(BlockMatrix)

分块矩阵是基于矩阵块MatrixBlock构成的RDD的分布式矩阵,其中每一个矩阵块MatrixBlock都是一个元组((Int, Int), Matrix),其中(Int, Int)是块的索引,而Matrix则是在对应位置的子矩阵(sub-matrix),其尺寸由rowsPerBlockcolsPerBlock决定,默认值均为1024。分块矩阵支持和另一个分块矩阵进行加法操作和乘法操作,并提供了一个支持方法validate()来确认分块矩阵是否创建成功。

分块矩阵可由索引行矩阵IndexedRowMatrix或坐标矩阵CoordinateMatrix调用toBlockMatrix()方法来进行转换,该方法将矩阵划分成尺寸默认为1024x1024的分块,可以在调用toBlockMatrix(rowsPerBlock, colsPerBlock)方法时传入参数来调整分块的尺寸。

%spark
import org.apache.spark.rdd.RDD
import org.apache.spark.mllib.linalg.distributed.{CoordinateMatrix, MatrixEntry}
import org.apache.spark.mllib.linalg.distributed.BlockMatrix
//1、 创建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)
//2、 创建RDD[MatrixEntry]
val entries : RDD[MatrixEntry] = sc.parallelize(Array(ent1,ent2,ent3,ent4,ent5,ent6,ent7,ent8))
//3、 通过RDD[MatrixEntry]创建一个坐标矩阵
val coordMat: CoordinateMatrix = new CoordinateMatrix(entries)
//4、 将坐标矩阵转换成2x2的分块矩阵并存储,尺寸通过参数传入
val matA: BlockMatrix = coordMat.toBlockMatrix(2,2).cache()
//5、 可以用validate()方法判断是否分块成功
matA.validate()
//6、构建成功后,可通过toLocalMatrix转换成本地矩阵,并查看其分块情况
matA.toLocalMatrix 输出:
res6: org.apache.spark.mllib.linalg.Matrix =
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
//查看其分块情况
matA.numColBlocks
matA.numRowBlocks
// 计算矩阵A和其转置矩阵的积矩阵
val ata = matA.transpose.multiply(matA)
//转换为本地矩阵查看
ata.toLocalMatrix

输出:
ata: org.apache.spark.mllib.linalg.distributed.BlockMatrix = org.apache.spark.mllib.linalg.distributed.BlockMatrix@37b6f828
res7: org.apache.spark.mllib.linalg.Matrix =
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

分块矩阵BlockMatrix将矩阵分成一系列矩阵块,底层由矩阵块构成的RDD来进行数据存储。值得指出的是,用于生成分布式矩阵的底层RDD必须是已经确定(Deterministic)的,因为矩阵的尺寸将被存储下来,所以使用未确定的RDD将会导致错误。而且,不同类型的分布式矩阵之间的转换需要进行一个全局的shuffle操作,非常耗费资源。所以,根据数据本身的性质和应用需求来选取恰当的分布式矩阵存储类型是非常重要的。

2、标记点

MLlib学习——基本数据类型的更多相关文章

  1. js学习之数据类型

    js学习之数据类型 基础类型:number string boolean null undefined 引用类型:object array function undefined值是派生自null值的( ...

  2. Go语言学习之数据类型

    ### Go语言学习之数据类型 数据类型的转换 1.Go语言不允许隐式类型转换(显示转换才可以) 2.别名和原有类型也不能进行隐式类型转换 例子: func TestImplicit(t *testi ...

  3. python学习6—数据类型之集合与字符串格式化

    python学习6—数据类型之集合与字符串格式化 1. 使用id()可以查看一个变量的内存地址: name = 'alex' id(name) 2. 进制转换 十进制转换为二进制等: a = 10 # ...

  4. MySQL学习笔记--数据类型

    一.数据类型(内容参考<SQL学习指南>)不完整 1.文本类型 文本类型 最大字节数 tinytext 255 text 65535 varchar 65536 mediumtext 16 ...

  5. C语言基础学习基本数据类型-变量的输出与输入

    变量的输出 变量如何输入输出呢?实际上,在这之前你已经使用过输出语句(printf语句)了,我们可以使用printf来执行输出. printf语句的使用方法如下: printf(格式控制字符串, 数据 ...

  6. C语言基础学习基本数据类型-变量和常量

    变量和常量 什么是变量和常量?有些数据在程序运行前就预先设定,并在运行过程中不发生变化,称之为常量:有些数据在程序运行中可能发生变化或被赋值,称之为变量. 使用变量前必须先声明一个变量.变量定义的语法 ...

  7. Redis 学习(二) —— 数据类型及操作

    Redis支持string.list.set.zset.hash等数据类型,这一篇学习redis的数据类型.命令及某些使用场景. 一.String,字符串 字符串是 Redis 最基本的数据类型.一个 ...

  8. MySQL学习4 - 数据类型一

    介绍 一.数值类型 二.浮点型 验证三种类型建表 验证三种类型的精度 三.日期类型 综合练习: 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选 ...

  9. python学习Day7 数据类型的转换,字符编码演变历程

    一.数据类型的转换 1.1.1.字符转列表:lst1 = str.split(默认空格,也可依据指定字符分界),若无分界字符,就没法拆分,这时可以直接放进list转成列表 ----> s1 = ...

随机推荐

  1. 表达式树扩展 动态生成表达式树插件 Sy.ExpressionBuilder。

    CURD中,基础查询我感觉还是很烦人的一个浪费时间的工作,我经历过远古时代的GetAll(string name,int age),这种方式写服务的时候真的是心中一万个草泥马飞过,后面逐渐的变成了传一 ...

  2. STM32时钟系统的配置寄存器和源码分析

    一.时钟系统 概述 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令,时钟系统就是CPU的脉搏,决定cpu速率. STM32有多个时钟来源的选择,为什么 STM32 要有多个时钟源呢 ...

  3. python 使用hashlib进行md5加密

    使用场景,某个接口或某个场景的数据需要做md5处理,就可以通过hashlib模块进行md5加密,如一个接口,需要传入md5加密后的数据 导入模块 import hashlib def exchange ...

  4. 初识python: 字典

    使用数据字典,编写一个多级菜单: 需求:每一级可返回上级,可退出. 多级菜单 #!/user/bin env python # author:Simple-Sir # time:20180915 # ...

  5. MySQL 开启和关闭远程访问

    MySQL 开启和关闭远程访问权限 一.开启MySQL/MariaDB的远程访问权限 [root@localhost ~]# mysql -u root -p MariaDB [(none)]> ...

  6. Git 如何放弃所有本地修改

    git checkout . #本地所有的修改,没有提交的,都返回到原来的状态 git stash #把所有没有提交的修改暂存到stash里面.可用git stash pop恢复. git reset ...

  7. Android官方文档翻译 十一 2.4Overlaying the Action Bar

    Overlaying the Action Bar 叠加菜单栏 This lesson teaches you to 这节课教给你: Enable Overlay Mode 启用叠加模式 For An ...

  8. Python常用的数据结构

    一.list 列表 1.列表的特点 有序的,元素可以重复,列表中的元素可以进行增上改查,可以存放不同的数据类型 2.创建列表 中括号创建并填充 --->[] 通过构造函数创建 list() 列表 ...

  9. gorm中的删除

    删除 删除一条记录 删除一条记录时,删除对象需要指定主键,否则会触发 批量 Delete,例如: db.Debug().Where("id = ?", 6).Delete(new( ...

  10. java内部类概述和修饰符

    1 package face_09; 2 /* 3 * 内部类访问特点: 4 * 1,内部类可以直接访问外部类的成员. 5 * 2,外部类要访问内部类,必须建立内部类的对象. 6 * 7 * 一把用于 ...