我的数据包括 n-length
向量 integer/real
数字。数据通常为gb级别,向量的特征大小大于100。我要计算每个向量特征的不同元素。例如,如果我有如下数据:
1.13211 22.33 1.00 ... 311.66
1.13211 44.44 4.52 ... 311.66
1.55555 22.33 5.11 ... 311.66
我想要这样的结果 (2,2,3,...,1)
只有一个向量。因为向量的第一个特征有两个不同的值,第二个特征有两个不同的值,以此类推。
我认为使用mapreduce的方法是,从mapper发送值(“$val$+{feature\u vector\u num}”,1)。例如像 (1.13211+1,1) or (2.33+2,1)
. 在reducer中,只需对它们进行总结,很可能是第二个Map器和reducer,将上一步的所有reducer结果打包。
问题是,如果我有大小为n的数据,在我的解决方案中,它发送到reducer的大小将是 |V| * N
在最坏的情况下( |V|
是特征向量的长度),这也是同时减少的数量和关键点的数量。因此,对于大数据来说,这是一个相当糟糕的解决方案。
你有什么建议吗?谢谢
2条答案
按热度按时间6ss1mwsb1#
我同意lejlot的观点,即使用其他方法(如hash-map等内存算法)而不是m/r,1gb的可解性会更好。
但是,如果你的问题是2-3个数量级以上,或者你只是想练习m/r,这里有一个可能的解决方案:
第一阶段
制图器
参数:
输入键:不相关(对于textinputformat,我认为它是longwritable,表示文件中的位置,但您可以只使用writable)
输入值:由空格分隔的向量分量的单行(1.13211 22.33 1.00。。。311.66)
输出键:一对<intwritable,doublewritable>,其中intwritable保存组件的索引,doublewritable保存组件的值。google for hadoop示例,特别是secondarysort.java,它演示了如何实现一对intwritable。您只需要使用doublewriteable作为第二个组件重写它。
输出值:不相关,可以使用nullwritable
Map器函数
标记值
对于每个令牌,发出<intwritable,doublewritable>键(您可以为此创建一个自定义的可写对类)和nullwritable值
减速机
该框架将使用<intwritable,doublewritable>对作为密钥调用reducer,每个密钥变化只调用一次,有效地进行重复数据消除。例如,<1,1.13211>键只出现一次。
参数
输入键:对<intwritable,doublewritable>
输入值:不相关(可写或可空写)
输出键:intwritable(组件索引)
输出值:intwritable(索引对应的计数)
减速器设置
初始化int[]计数器数组,数组大小等于向量维数。
减速机功能
从key.getfirst()获取索引
索引的增量计数:计数器[索引]++
异径管清理
对于counters数组emit中的每个计数,数组的索引(作为键)和计数器的值。
第2阶段
这是一个微不足道的,只有当你有多个减速机在第一阶段需要。在这种情况下,上面计算的计数是部分的。您需要将多个减速机的输出合并为一个输出。您需要设置一个reducer作业,其中reducer只会为相应的索引累积计数。
制图器
无操作
减速机
参数
输入键:intwritable(位置)
输入值:intwritable(部分计数)
输出键:intwritable(位置)
输出值:intwritable(总计数)
减速机功能
对于每个输入键
int计数器=0
迭代这些值
计数器+=值
发出输入键(作为键)和计数器(作为值)
结果输出文件“part-r-00000”应该有n条记录,其中每条记录是一对按位置排序的值(位置和不同计数)。
xqkwcwgp2#
在不考虑任何实现细节(mapreduce与否)的情况下,我将使用每个特性的哈希表(可能在redis中)分两步完成。
第一步将列出所有值和相应的计数。
第二个将遍历每个向量,查看元素在hastable中是否唯一。如果你有一些误差,并希望轻内存占用,我甚至会去与布鲁姆过滤器。
这两个步骤被简单地并行化。