MapReduce 矩阵乘法

一、对朴素简单直接方法

把m*n 和n*l的矩阵A和B相乘,这估计是最容易想到的方法了:

把A(m*n)的元素,每个发送l次,把B(n*l)的元素每个发送m次。将发送到一起的数据相乘求和,得到最后的结果。


优点:在知道坐标的情况下,这个过程就一轮mapreduce。
缺点:每个值要被发送多次。m*n 和n*l的矩阵,发送的元素有m*l*2次,比如100万的方正相乘,那么中间文件有100*100百万*百万的记录,这么多元素在网络上传输,结果你懂的。另外,这个并没有有效的避开0元素,也就是说对稀疏矩阵来说很浪费。而且必须要知道矩阵的下标和行列数。因为在map里需要用到。实际情况是,现实中的矩阵,并不一定都是用递增的整数来表示下标的。有可能是人名,帐号等。

上面的方法乍一看还ok,用小数据测试一下也是正确的,不过这个方法问题在于,reduce里收到的数据也许非常非常多,多到内存放不下。然后节点就heapSpace overFlow了。话说回来如果一定要在这个方法上改进,可以把map reduce分成两步。第一步还是和上面一样,但是key中再加一个字段k,表示,这是结果矩阵中坐标为(i,j)的元素的第k个用来求和的元素。k其实是A的列号和B的行号。这样上面的过程就变成 

A: key(1,1,1) value(a,1)  key(1,1,2) value(a,2)  key(1,1,3) value(a,3)
       key(1,2,1) value(a,1)  key(1,2,2) value(a,2) ..........
B:   key(1,1,1) value(b,1)    key(1,1,2) value(b,6) key(1,1,3) value(b,0)
      key(2,1,1) value(b,1)    key(2,1,2) value(b,6) ...........
然后在reduce中对元素求乘积 生成:
      key(1,1)  value= (a,1)*(b,1)   key(1,1)  value= (a,2)*(b,6)    key(1,1)  value= (a,3)*(b,0). 其实连元素来自A还是B都可以省了。
再来第二轮mapreduce,对上一步mapreduce的结果再group by,求和。这样改进之后,没有reduce内存溢出的问题。看起来像是多大的矩阵都可以计算,其实由于没能解决一个A或B的元素要发送很多次的问题,在计算超级大的矩阵的时候,这个方法还是完全不能用。

二、 分解成行和列来控制

观察上面的最细的矩阵乘法,如果矩阵是比较稀疏的,其实有很多东西就白白发送了,发出去在reduce里其实没有用到。也是这个原因导致中间文件急剧膨胀,如果矩阵超级大,即使在mapreduce里,也要跑相当长时间。再来回忆一下矩阵乘法,能发现一些规律。
假设现在有两个矩阵,分别是同现矩阵和用户评分矩阵,现在要把两个矩阵相乘来获得推荐分数。



通过观察,把A矩阵的一列和B矩阵的一行发送到同一个reduce中,然后在reduce中,对来自A的元算和来自B的元素做笛卡尔乘积,对笛卡尔乘积的结果再做一次mapReduce,对相应的坐标求和就可以得到结果矩阵的一个个元素了。
优点:相对与最细的矩阵乘法而言,大大压缩了中间文件的大小,对稀疏矩阵而言,避免了找不到对应元素而造成的浪费。在这个方法里,为0的元素不发送就行了。另外一个明显的优点就是,我用不着一定用数字来表示矩阵的坐标,是字符串也行。只要A矩阵的列坐标和B矩阵的行坐标对的上就行。
缺点:变成了两轮mapreduce才搞得定。另一个明显缺点是,在一个reduce的节点内存里面,未必放的下A的一行+B的一列。因为仅凭key不能区分数据是来自A矩阵还是B矩阵,最起码要往内存里读一次才知道怎么做笛卡尔乘积。当然写成一个文件放到reduce本地,然后再来算也行,不过这样有点低效了,不如直接在内存里来的快。这样其实还是限制了这个方法的范围,我觉得1百万乘以1百万的稀疏矩阵用这个方法来做还是撑的住的,当然得看矩阵稀疏程度。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MapReduce矩阵乘法是一种通过使用Map和Reduce函数来实现的矩阵乘法算法。该算法需要满足左矩阵的列数与右矩阵的行数相等的条件。首先,我们需要将两个矩阵分别存储在不同的文件中,然后使用Map函数来读取这些文件,并将它们拆分成适当的键值对。每个键值对由一个元素的索引作为键,以及该元素的值作为值。接下来,通过对两个矩阵的对应元素进行乘法运算,我们可以得到中间结果。最后,使用Reduce函数来将中间结果合并,并生成最终的结果矩阵。 需要注意的是,在处理大型矩阵时,内存溢出可能会成为一个问题。因此,为了处理大矩阵的运算,可以采用其他转换方式,比如行列相乘运算、分块矩阵运算、基于最小粒度相乘的算法等方式来减少内存压力。另外,由于这些代码通常是演示代码,所以可能缺少一些错误数据过滤的部分。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [MapReduce实现矩阵乘法](https://blog.csdn.net/conansix/article/details/39958957)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [大数据Mapreduce编程——矩阵乘法](https://blog.csdn.net/qq_46138648/article/details/123180935)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值