前文

《利用Hadoop实现超大矩阵相乘之我见(一)》中我们所介绍的方法有着“计算过程中文件占用存储空间大”这个缺陷,本文中我们着重解决这个问题。

矩阵相乘计算思想

传统的矩阵相乘方法为行、列相乘的方式,即利用左矩阵的一行乘以右矩阵的一列。不过该方法针对稀疏矩阵相乘,会造成过多的无效计算,降低计算效率。为了解决这个问题,本发明采用列、行相乘计算方式,即利用左矩阵的一列中的元素与右矩阵对应行中的所有元素依次相乘,该方法有效避免了稀疏矩阵相乘过程中产生的无效计算。具体计算过程示意图如图1所示。

图1 列、行矩阵相乘计算示意图

数据预处理

为了便于Map-Reduce模型对矩阵元素进行处理,所有的矩阵元素都存储在文本文件中,一行记录代表一个矩阵元素,针对稀疏矩阵,0元素不纳入输入文本。如图2所示。

图2 输入的矩阵元素

图3 预处理后的矩阵元素

我们对图2进行举例说明,假如一行记录为:。则其代表左矩阵第一行第二列的元素值为

在一个Map过程中,我们对每一行输入数据进行预处理,若一行记录代表左矩阵元素,则提取列号作为Key值,剩余信息组成Value值;若一行记录代表右矩阵元素,则提取行号作为Key值,剩余信息组成Value值,如图3所示。之所以这样做,是为了下一步在Reduce过程中能够按照Key值统计左矩阵第Key列极其对应右矩阵第Key行中的元素。

统计与分段

当矩阵规模大到一定程度时,内存可能会碰到加载不了左矩阵的一列或右矩阵的一行元素的问题。为了提高矩阵相乘运算的可扩展性,本发明提出了对左矩阵元素按列进行分段,对右矩阵元素按行进行分段的方法,这样,单个计算节点就可以加载左矩阵的一段与右矩阵的一段至内存进行相乘运算,突破了内存的限制。分段相乘示意图如图4所示。

图4 矩阵分段相乘示意图

接下来我们结合图4来说明Reduce阶段如何来完成统计与分段工作。Reduce阶段首先将所有Key相同的Value集合在一起,形成一个Value-List。若Key为k,那么Value-List则代表了左矩阵第k列与右矩阵第k行的所有元素,这些元素时混合在一起的。在Reduce阶段,我们第一轮遍历Value-List,获得左矩阵第k列的元素个数为Mk,右矩阵第k行的元素个数为Nk。接下来我们通过第二轮遍历对左矩阵第k列、右矩阵第k行的元素进行分段操作,假设每个分段包含w个元素,则左矩阵第k列被分为段,右矩阵被分为段。

图5 分布式缓存存储矩阵分段信息

本发明将L矩阵中第k列中第i个分段表示成如下格式:

代表该分段在接下来的过程中总共需要个拷贝,element_list表示该分段中的元素集合。

同理,R矩阵中第k行中第j个分段表示成如下格式:

为了便于后续Map-Reduce过程的处理,我们将每一个分段都存储在磁盘文件中,文件中的一样代表一个分段。同时,我们将两个矩阵中的具体分段信息存储在分布式缓存中,有利于解决后续步骤中不同节点间的通信与数据查询问题。具体存储格式如图5所示。

图5中代表矩阵L中第1列的元素个数为M1,每个分段的元素个数为w,所以对该列的分段数目为;同理表示矩阵R中第1行的元素个数为N1,每个分段的元素个数为w,所以对该行的分段数目为

拷贝任务分发——Map迭代算法

Map迭代算法

如图4所示,我们需要将两个矩阵中的分段一一对应相乘。我们做如下举例:由于矩阵L中的第k列中的第i段需要与矩阵R中第k行中的所有段依次相乘,所以需要将L中第k列第i段的内容拷贝份;同理,R中第k行中的每一个分段需要拷贝份。当然,拷贝工作是通过Map-Reduce来完成的,现在的问题是,若两个矩阵中每一个分段需要拷贝的数量都很大,则一个Map对每行记录都需要执行好多遍拷贝工作,大大延长了Map执行的时间,同时,可能使得很多计算节点没有参与运算。

图6 Map迭代拷贝任务分发算法

为了解决上述问题,本发明提出了“Map迭代拷贝任务分发算法”来对每条记录(每个分段)的拷贝任务进行分发,这样有效的控制每个节点对每个分段的拷贝数量,同时更有效的使得更多的节点参与拷贝运算工作。

为了便于每条数据知道自己需要拷贝的分数,我们对公式(1)、(2)进行简单的修改:

式(3)中代表该记录(分段)需要拷贝份,拷贝标识号为1至;同理解释式(4)。

这里,我们结合图7进行举例说明,假设…1#10000…是式(3)或式(4)的缩写形式,代表一条记录需要拷贝10000份,同时假设所有分段需拷贝的份数都是10000,那么初始时,将有N个节点参与拷贝工作。为了使得更多的计算节点参与拷贝工作,我们设计了此Map迭代拷贝任务分发算法。假设分发扩展率为10,则经过一次迭代后,文件大小扩大了约10倍,则大约有10*N个计算节点将参与拷贝工作,依次类推,三次迭代后,约有1000*N个计算节点参与拷贝工作,当有1000*N个节点参与拷贝工作时,每条记录被拷贝的最大份数为10,如图7所示。

迭代次数控制

在现实大矩阵相乘中,由于大部分情况下矩阵都为稀疏矩阵,那么每行每列包含的元素个数就不一样,所以每个分段需拷贝的份数都不确定。这样我们就需要计算Map迭代过程的迭代次数,依次来控制Map迭代的过程。在此,我们利用图5所示存储在分布式缓存中的各个分段信息来得到最大分段数目,同时结合分发扩展率n,利用公式(5)来计算Map迭代的次数,依次来控制Map迭代过程。

最后计算模块

完成记录的拷贝工作后,我们还需要两轮Map-Reduce过程完成矩阵的运算。

第一轮Map-Reduce——分段拷贝与对应

在此轮中,我们首先在Map阶段完成分发到的拷贝任务,若图(7)中的….2191#2200…格式符合式(3),则其原本的形态为:

在Map中执行拷贝工作后记录样式为:

k−i−2191   element_list

k−i−2192   element_list

......

k−i−2199   element_list

k−i−2200   element_list

若图(7)中的….2191#2200…格式符合式(3),则其原本的形态为:

在Map中执行拷贝工作后记录样式为:

k−2191-j   element_list

k−2192-j   element_list

......

k−2199-j   element_list

k−2200-j   element_list

经过此轮Map阶段,每个key(拷贝后每条记录的前半部分)对应两个Value,也就是L矩阵中的一个段与R矩阵中的一个段,同一个key的两个Value将在该轮的Reduce阶段进行汇合,汇合后如下所示:

代表L矩阵第k列第i个分段,代表R矩阵第k行第j个分段,然后在下一轮Map-Reduce进行如图(4)所示的两个段的相乘工作。

第二轮Map-Reduce——相乘并汇总

Map阶段对每条记录进行相乘运算,即将L中每个元素依次与R中每个元素相乘,若element_list_(L,k,i)中某个元素Li,k与element_list_(R,k,j)中某个元素Rk,j相乘,则结果记录成“i-j value”格式。 然后每个Map结束后执行combine操作,combine操作与该轮Reduce操作一样,执行相同key的value相加,便得到了最终的矩阵运算结果。

 推荐一个自己业余时间开发的网盘搜索引擎,360盘搜www.360panso.com

某研究开发中心云计算组     小周       

利用Hadoop实现超大矩阵相乘之我见(二)的更多相关文章

  1. 利用Hadoop实现超大矩阵相乘之我见(一)

    前记 最近,公司一位挺优秀的总务离职,欢送宴上,她对我说“你是一位挺优秀的程序员”,刚说完,立马道歉说“对不起,我说你是程序员是不是侮辱你了?”我挺诧异,程序员现在是很低端,很被人瞧不起的工作吗?或许 ...

  2. Java实现矩阵相乘问题

    1 问题描述 1.1实验题目 设M1和M2是两个n×n的矩阵,设计算法计算M1×M2 的乘积. 1.2实验目的 (1)提高应用蛮力法设计算法的技能: (2)深刻理解并掌握分治法的设计思想: (3)理解 ...

  3. java 写一个 map reduce 矩阵相乘的案例

    1.写一个工具类用来生成 map reduce 实验 所需 input 文件 下面两个是原始文件 matrix1.txt 1 2 -2 0 3 3 4 -3 -2 0 2 3 5 3 -1 2 -4 ...

  4. 利用Cayley-Hamilton theorem 优化矩阵线性递推

    平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...

  5. POJ 2246 Matrix Chain Multiplication(结构体+栈+模拟+矩阵相乘)

    题意:给出矩阵相乘的表达式,让你计算需要的相乘次数,如果不能相乘,则输出error. 思路: 参考的网站连接:http://blog.csdn.net/wangjian8006/article/det ...

  6. MapReduce实现矩阵相乘

    矩阵相乘能够查看百度百科的解释http://baike.baidu.com/view/2455255.htm?fr=aladdin 有a和b两个矩阵 a:                1   2   ...

  7. Python+MapReduce实现矩阵相乘

    算法原理 map阶段 在map阶段,需要做的是进行数据准备.把来自矩阵A的元素aij,标识成p条<key, value>的形式,key="i,k",(其中k=1,2,. ...

  8. python版 mapreduce 矩阵相乘

    参考张老师的mapreduce 矩阵相乘. 转载请注明:来自chybot的学习笔记http://i.cnblogs.com/EditPosts.aspx?postid=4541939 下面是我用pyt ...

  9. Java实验项目四——多线程矩阵相乘算法的设计

    Program:多线程矩阵相乘算法的设计 Description:利用多线程实现矩阵相乘,因为各个线程的运算互不影响, 所以不用使用锁,代码如下: thread.OperateMatrix类,实现矩阵 ...

随机推荐

  1. C++多继承

    1.继承的三种方式: 公有继承(public),私有继承(private),保护继承(protected)三种继承方式的说明,如下表所示: 特征 公有继承 保护继承 私有继承 公有成员变成 派生类的公 ...

  2. SQL存储过程相关信息查看转

    原文地址:http://www.cnblogs.com/minideas/archive/2009/10/29/1591891.html   --1.查看所有存储过程与函数      exec sp_ ...

  3. Java 笔试题集锦

    1.Java 不需要使用构造函数来创建对象的方法有哪些? 2.Java 创建多线程有哪些方法?你最喜欢哪一个?为什么? 3.Java

  4. OpenJudge计算概论-简单算术表达式求值

    /*===================================== 简单算术表达式求值 总时间限制: 1000ms 内存限制: 65536kB 描述 2位正整数的简单算术运算(只考虑整数运 ...

  5. JavaScript中类的实现机制

    理解类的实现机制在前面已经讲过,在JavaScript中可以使用function关键字来定义一个“类”.现在介绍如何为类添加成员.其过程很简单,在函数内通过this指针引用的变量或者方法都会成为类的成 ...

  6. 结合Scikit-learn介绍几种常用的特征选择方法

    特征选择(排序)对于数据科学家.机器学习从业者来说非常重要.好的特征选择能够提升模型的性能,更能帮助我们理解数据的特点.底层结构,这对进一步改善模型.算法都有着重要作用. 特征选择主要有两个功能: 减 ...

  7. xshell 5连接linux服务器的技巧

    1.用sttp 方式连接服务器,命令识别不了,用ssh方式才能有效

  8. redis 服务访问密码设定

    1. 更改redis.conf配置 # requirepass foobared 去掉注释,foobared改为 自己的password , 我测试的时候用的是 redis-password 2.启动 ...

  9. [hadoop] WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

    hadoop 启动后,有警告信息: WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform ...

  10. css字体文件

    ├── glyphicons-halflings-regular.eot├── glyphicons-halflings-regular.svg├── glyphicons-halflings-reg ...