Hadoop 的单词百分比程序

问题描述 投票:0回答:3

我正在开发著名的 WordCount 程序的一个稍微改进的版本,它应该输出该单词占书中的百分比。例如:

...
war 0.00002332423%
peace 0.0034234324%
...

基本上,我需要计算所有单词的数量,计算每个单词的出现次数,然后将这组值除以总数。所以至少应该有两个工作:

工作1

  • 获取
    input
    目录并生成两个输出目录:
    output1
    output2
  • Mapper:将
    (word, 1)
    对写入
    output1
    ,将
    ("total_count", 1)
    对写入
    output2
  • Reducer:将
    (word, n)
    中的
    output1
    相加,计算
    ("total_count", N)
     中的 
    output2
  • 的总数

工作2

  • output1
    output2
    作为输入文件夹,将结果写入
    output3
  • Mapper:不做任何事情,只是写下它得到的相同对
  • Reducer:取单个值除以
    total_count
    ,将结果写入
    output3

我的问题:

  1. 我想避免两次查看原始输入,这就是为什么我试图计算 Job1 中的字数和总计数。但我不明白如何避免混淆一个输出中的结果。我尝试过使用

    MultipleOutputs
    但在这种情况下,映射器的结果不会进入减速器。

  2. Job2需要多个输入,而且需要先读取

    output2
    ,因为没有总计数,从
    output1
    读取结果是没有用的。我觉得这是使用 MapReduce 的错误方式(我们不应该使用任何类型的同步),但没有看到正确的方式。

  3. Job2 中的 Mapper 没有做任何有用的事情,只会浪费处理器时间。

java hadoop mapreduce word-count
3个回答
2
投票

关于使用单个作业的想法:

total_count
可以从第一个作业的map阶段计算出来。其实已经算
MAP_OUTPUT_RECORDS
了。这是所有地图输出
(key, value)
对的总和。因此,如果您始终将 1 作为值,那么这个总和就是您想要的,即文档中的单词总数(包含重复)。

现在,我不知道你是否可以在减速器的配置中获得这个计数器。然后,您可以为每个单词输出

(word, wordCount/MAP_OUTPUT_RECORDS)
对。我认为你可以通过以下方式做到这一点:

新API:

context.getCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_OUTPUT_RECORDS").getValue();

旧 API:

reporter.getCounter("org.apache.hadoop.mapred.Task$Counter", "MAP_OUTPUT_RECORDS").getValue();

0
投票

一种非优化的方法是创建一个特殊的单词(如“00000”)并用它来计算所有单词的数量。映射器 1 会为其遇到的每个单词写出 (word, 1) 和 ("00000", 1)。然后,Reducer 1 将对所有单词进行计数并计算总数(“00000”的计数)。

下一个作业将有一个直通映射器,并且减速器将计算百分比。这里的技巧是(1)有一个减速器,(2)选择“00000”单词,以便它在所有其他单词之前排序。通过这种方式,总数首先传递到Reducer 2,并且对于所有后续的字数计数都是已知的。


0
投票

Yurii,可以帮我解决百分比词的问题吗?

我需要两项链接工作。

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.