Spark 中的本地矩阵的行列索引为整数,而元素值为双精度(double)型。所有值均存储在单个节点上。MLlib 支持如下矩阵类型。
密集矩阵:其各元素以列优先顺序存储在单个双精度数组中。
稀疏矩阵:其各非零元素以列优先顺序存储为 CSC 格式。比如,如下大小为(3, 2)的密集矩阵存储在一维数组[2.0, 3.0, 4.0, 1.0, 4.0, 5.0]中:
2.0 3.0
4.0 1.0
4.0 5.0
以下例子说明了这两种矩阵的创建:
val dMatrix: Matrix = Matrices.dense(2, 2, Array(1.0, 2.0, 3.0, 4.0))
println("dMatrix: \n" + dMatrix)
val sMatrixOne: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3),
Array(0, 2, 1), Array(5, 6, 7))
println("sMatrixOne: \n" + sMatrixOne)
val sMatrixTwo: Matrix = Matrices.sparse(3, 2, Array(0, 1, 3),
Array(0, 1, 2), Array(5, 6, 7))
println("sMatrixTwo: \n" + sMatrixTwo)
其输出如下:
[info] Running linalg.matrix.SparkMatrix
dMatrix:
1.0 3.0
2.0 4.0
sMatrixOne:
3 x 2 CSCMatrix
(0,0) 5.0
(2,1) 6.0
(1,1) 7.0 【请不要纠结(2,1)6.0以及(1,1)7.0,通过三行两列的存储,他们就能还原成3*3列的矩阵,下面的(1,1)6.0和(2,1)7.0也是一样】
sMatrixTwo:
3 x 2 CSCMatrix
(0,0) 5.0
(1,1) 6.0
(2,1) 7.0
密集矩阵:其各元素以列优先顺序存储在单个双精度数组中。
稀疏矩阵:其各非零元素以列优先顺序存储为 CSC 格式。比如,如下大小为(3, 2)的密集
矩阵存储在一维数组[2.0, 3.0, 4.0, 1.0, 4.0, 5.0]中:
2.0 3.0
4.0 1.0
4.0 5.0
IndexedRowMatrix:与 RowMatrix 类似,但以行而非列为索引。该索引可用于检索行以及执行连接(join)操作。如下代码演示了创建一个带相应行索引的 4×3 的IndexedMatrix 方法。
CoordinateMatrix:该类矩阵以坐标表(COO,coordinated list)格式将各元素分布式地存储在一个 RDD 中。COO 保存了一个(row, column, value)三元组的列表。各元素依次按行索引和列索引排序过,以提升随机访问性能。当需要增量式增删来构建一个矩阵时,这种格式很有优势。
9.3矩阵操作
矩阵支持的操作有多种。
按元素加法。已知两个矩阵 a 和 b,将它们相加,(a + b),意味着将两个矩阵相同位置好的元素相加
Breeze 中代码为:
val a = DenseMatrix((1,2),(3,4))
val b = DenseMatrix((2,2),(2,2))
val c = a + b
println("a: \n" + a)
println("b: \n" + b)
println("a + b : \n" + c)
其输出为:
a:
1 2
3 4
b:
2 2
2 2
a + b :
3 4
5 6
按元素乘法。即将两个矩阵各相同位置上的元素相乘。
在 Breeze 中代码为:
a :* b
val d = a*b
println("Dot product a*b : \n" + d)
其输出为:
Dot product a*b :
6 6
14 14
6,6,14,14是这么得来的 (1,2)*(2,2),(1,2)*(2,2)【也就是a矩阵第一行1,2元素乘以b矩阵的第一列元素(2,2)=1*2+2*2=6,第一行第二列元素也是1*2+2*2,第二行第一列是3*2+4*2=14,第二行第二列也一样】,以此类推,就是,6,6,14,14
10.函数
要定义一个如函数这样的数学对象,需要先明白什么是集合(set)。集合是若干无序对象的集,比如 S = {4, 4, 3, 3, 2, 2, 1, 1, 0}。如果集合 S 并非无限,则用|S|来表示其元素的个数,即集合的势(cardinality)。如果 A 和 B 都是有限集合,则有| A → B | = |A| → |B|,即笛卡儿积(Cartesian product)。
对于 A 中的每一个输入元素,一个函数会将其对应到另一集合 B 中的某一个输出元素。A 称为函数的定义域(domain),B 则称为值域(codomain)。函数是若干(x, y)对的集合,其中 x 各不相同。
比如,定义域为{1, 2, 3, …}的函数,其两倍输入操作对应的集合为{(1, 2), (2, 4),(3, 6), …} 又如,输入变量数为 2 且定义域均为{1, 2, 3, …}的函数,其对应的集合为{((1,1),1),((1,2),2), …, ((2,1),2),((2,2),4),((2,3),6),…,((3,1),3),((3,2),6),((3,3),9),…}。
给定输入对应的输出称为该输入的映射。q 在函数 f 上的映射表示为 f(q)。如果 f(q) = s,则称 q 经 f 映射为 s ,写作 q → s。包含所有输出的集合称为值域。可用 f: D → F 来表示函数 f 是一个定义域和值域分别为 D 和 F 的函数。