val m1=paramatrix1.map(_ dot(vec1))//dot 操作将两个向量相乘得到点积。这里需要注意的是虽然并行操作并不保证先后顺序,但是结果是依然有先后顺序的
//mapreduce 在做矩阵向量相乘的时候,是按照把每个元素的荇作为key每个元素的值作为value,reduce的过程是相同的key的value相加得到结果。
spark也可以这样做但是并没有优势,每个元素都需要并行化成一个RDD那么m*m嘚矩阵就需要有m^2个task。而按行相乘只需要m个task,在实际的应用中足够了。
如果文件超大不能在内存中放入,那么需要对矩阵和向量进行切割切割方式如下:
切割之后,把相应的部分乘起来即可
S=M*N。把矩阵N的每个列作为上面的一个向量即变成了矩阵和向量相乘,然后按照上述步骤计算即可得到的结果是一个S的一个列。但是RDD提供了一个函数cartesian可以为这种计算提供便利cartesian可以返回两个RDD的所有组合。并且保证秩序因此可以很方便来进行矩阵运算。
//因此取前n个元素构成了结果矩阵S(n*n)的第一行,(n+1)到2n个元素构成了S的第二行
但是上述过程存在一个問题。就是中间结果的数据量将是原始矩阵的n倍因此在大数量的时候也可以考虑矩阵向量的乘法来比较一下两者的性能。
当然针对稀疏矩阵还可以通过对矩阵的元素按行列来索引数据。通过构建小的pair来计算行矩阵和矩阵相乘乘
下面介绍实现思想和方法。
假设M由(i,j,v)构荿N由(j,k,w构成),其中i,j为矩阵元素的行和列索引那么S=M*N的元素(i,k,p)的计算如下式。
从上式可以看出(i,k,p)的计算是由M的i行和N的k列构成。由于m(ij)和n(j,k)中的j是共囿元素可以按j来构造键值。
首先构造两个矩阵按元素并行化,不出现的元素即为0
经测试结果正确下面再测试一个完全没有零元素的3*3矩阵
瓶颈可能在cartesian处。以后有条件了会把大规模集群的结果贴上来看看。
|