SPARK数据类型SPARSEMATRIX 解释

parseMatrix

Spark的mllib包中提供了机器学习的两种基本数据类型: DenseMatrix(稠密)和 SparseMatrix(稀疏),在初始化对象的时候可以使用Matrices伴生对象产生,先看下示例代码:

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))

// 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))

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))

// 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))

 

对于DenseMatrix的初始化参数不难理解,定义行数,列数以及所有元素值,(注,列式优先存储),然后并产生DenseMatrix矩阵;

而对于SparseMatrix的初始化参数有点难理解,并非是我们常见的三元组存储方式,可以先看看源码的定义:

SPARK数据类型SPARSEMATRIX 解释_第1张图片

关于参数numRows(行数),numCols(列数),rowIndices(行向索引),values(元素值),这些好理解,难懂的是colPtrs参数,这里通过一图来解释这个参数意义所在。

SPARK数据类型SPARSEMATRIX 解释_第2张图片

这样就容易理解多了。

 

 

 

SparkMLlib中关于矩阵的东西还是比较好理解的,不过在本地矩阵中,有个东西叫稀疏矩阵在理解方面可能会有些问题,所以单独提出来一下。

1.什么是稀疏矩阵?
这个东西我觉得百度说的挺清楚了,尤其是下面这张图很容易理解

左边这个叫稀疏矩阵,右边这个叫密集矩阵
简单的理解,就是0在矩阵中的数量是多还是少的事情。

2.Spark中的稀疏矩阵
SparkMLlib中的稀疏矩阵写法是这样的
val sm:Matrix = Matrices.sparse(3,2,Array(0,1,3), Array(0,2,1), Array(9,6,8))
这是一个3×2的即3行2列的矩阵写法
这个东西执行完是这样的

也就是 ((9,0),(0,8),(0,6)) 这样的矩阵
通过对比写法,我们很容易理解其中的参数 ,第一个3就是行数,第二个2是列数,第二个Array是非0元素所在行数,第三个Array是非0元素数值
那么,第一个Array是什么鬼?

3.第一个Array是什么鬼?
翻一下源码,是这么写的

说这个是colPointers
也就是列点,这是什么鬼?
源码中能看出,这是CSC写法,查一下CSC写法,对于colptr是这么解释的

是一个迭代器构造
那么再对比一下这个Array,至少有两个东西可以理解了,就是Array的第一个元素是0,表示迭代开始,最后一个元素3则表示非0元素的总数
那么中间值是什么?

4.中间值是什么?
我们改一下之前的参数,把 0,1,3改成0,2,3看看有什么变化

可以看到6的位置变化了,从第二列变到了第一列
那么可以肯定的是,这个位置代表的是第一列的点的数量
综合之前的分析,我们可以得到一个结论,这个Array是从0开始,1号位代表第一列元素个数,第二列代表第一列元素个数+第二列元素个数.
那么后续的会有什么变化呢?
再看源码写的矩阵

可以看到,这是一个累加过程,第一列有2个,第二列有1个,第三列有3个
Array中的元素写成了0,2,3,6

5.结论
这个写法就很好理解了,先圈出行数和列数,都标记为0,再将各元素按照所属行进行有序排列,先标记对角线,之后根据每列点数不同进行调整

有兴趣的可以自己在spark shell界面试一下
记得先import org.apache.spark.mllib.linalg.{Matrix, Matrices}
 

你可能感兴趣的:(SPARK数据类型SPARSEMATRIX 解释)