Hadoop Mapreduce计算大数据的不同向量元素

时间:2015-01-07 22:17:19

标签: hadoop mapreduce machine-learning cluster-computing

我的数据包含n-lengthinteger/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)这样的结果只有一个向量。由于矢量的第一个特征有2个不同的值,第二个特征中有2个不同的值等等。

我认为使用mapreduce的方法是,从mapper发送值(" $ val $ + {feature_vector_num}",1)。例如(1.13211+1,1) or (2.33+2,1)。在reducer中只需要总结它们,可能是第二个mapper和reducer来包装上一步的所有reducer结果。

问题是,如果我有大小为N的数据,使用我的解决方案,它的大小将被发送到reducer |V| * N在最坏的情况下,(|V|是特征向量的长度),这也是减速器的数量和同时的密钥数量。因此,对于大数据,这是一个非常糟糕的解决方案。

你有任何建议吗? 感谢

2 个答案:

答案 0 :(得分:2)

在不考虑任何实现细节(MapReduce与否)的情况下,我会分两步使用每个功能的哈希表(可能在Redis中)。

第一步将列出所有值和相应的计数。

然后第二个将遍历每个向量,并查看该元素在hastable中是否唯一。如果你有一些误差,并想要一个轻微的内存占用,我甚至会使用布隆过滤器。

这两个步骤非常平行。

答案 1 :(得分:1)

我同意lejlot的意思是1GB可以使用其他方法(例如哈希映射等内存算法)更好地解决,而不是使用m / r。

但是,如果你的问题大2-3个数量级,或者你只是想用m / r练习,这是一个可能的解决方案:

第1阶段

映射

PARAMS:

  • 输入密钥:无关紧要(对于TextInputFormat,我认为它是LongWritable 表示文件中的位置,但您可以使用Writable)
  • 输入值:单行,矢量分量用空格分隔(1.13211 22.33 1.00 ... 311.66)
  • 输出键:一对< IntWritable,DoubleWritable> 其中IntWritable包含组件的索引,DoubleWritable包含组件的值。 Google为hadoop示例,特别是SecondarySort.java,它演示了如何实现一对IntWritable。您只需要使用DoubleWritable作为第二个组件重写它。
  • 输出值:无关紧要,可以使用NullWritable

映射器功能

  • 标记值
  • 对于每个令牌,发出< IntWritable,DoubleWritable> key(您可以为其创建自定义可写对类)和NullWritable值

减速

该框架将使用< IntWritable,DoubleWritable>调用您的reducer。配对作为键,每个键变化只有一次,有效地进行重复数据删除。例如,< 1,1.13211>钥匙只会来一次。

PARAMS

  • 输入密钥:对< IntWritable,DoubleWritable>
  • 输入值:不相关(可写或NullWritable)
  • 输出键:IntWritable(组件索引)
  • 输出值:IntWritable(对应于索引的计数)

减速机设置

  • initialize int []计数器大小等于矢量维度的数组。

减速器功能

  • 从key.getFirst()
  • 获取索引
  • 索引的增量计数:计数器[index] ++

Reducer Cleanup

  • 对于计数器数组中的每个计数发出,数组的索引作为键,以及计数器的值。

第2阶段

这个很简单,只有在第一阶段有多个减速器时才需要。在这种情况下,上面计算的计数是部分的。 您需要将多个Reducer的输出组合成一个输出。 您需要设置单减速器作业,您的减速器将仅累积相应索引的计数。

映射

NO-OP

减速

PARAMS

  • 输入键:IntWritable(位置)
  • 输入值:IntWritable(部分计数)
  • 输出键:IntWritable(位置)
  • 输出值:IntWritable(总计数)

减速器功能

  • 表示每个输入键
    • int counter = 0
    • 迭代值
      • counter + = value
    • 发出输入键(作为键)和计数器(作为值)

结果输出文件“part-r-00000”应该有N条记录,其中每条记录是按位置排序的一对值(位置和不同的计数)。