动态计数器 Hadoop

Dynamic counter Hadoop

我在 Hadoop 中的 Mapreduce 作业方面需要一些帮助。 我有以下问题。我有一个包含多个文档+文档类别的大型数据集。我需要计算每个类别文档中每个术语的卡方值。这意味着,我需要每个类别每个术语的出现次数 + 每个类别的文档数量。

我的方法是有一个 Mapreduce 作业,它计算每个类别的每个单词的出现次数:

输入映射器:(docId, TextOfDocument) -> ({term, category}, docID) 减速机:(术语,{category,NumberOfOccurences})

这样做的问题是,我丢失了每个类别的文档数量信息,我在下一个作业中需要这些信息来计算卡方值。

我想到了以下解决方案:

1) 在读取文档时,使用每个类别的计数器来存储每个类别的文档数。我认为这将是最好和最简单的解决方案。问题是,我不知道类别的数量,因此我需要动态增加计数器的数量。我没有找到在 Hadoop 中执行此操作的方法(创建动态增加的计数器)?有什么办法吗?我该怎么做?

2) 首先,运行 一个作业并计算每个类别的文档数量并以某种方式存储它。我不知道如何检索数据或存储是否方便我可以在阅读整个文档时阅读。

3) 用数据类型的额外值以某种方式对其进行分区并以某种方式对其进行计数。

谁能帮我解决这个问题?哪种方法最好?或者还有其他方法吗? 感谢您的帮助!

我想我终于可以找到一个解决方案来一次性计算每个类别的术语计数和每个类别的文档数量。

在你的地图阶段,你应该提取你需要的东西然后你的输入和输出应该是这样的:

<docId, TextOfDocument> --> 
1. "<C_AFFIX+category+C_AFFIX, 1>" 
2. "<CT_AFFIX+category+term+CT_AFFIX, 1>"

C_AFFIX 和 CT_AFFIX:只是标识符,以帮助避免这两种不同类型的键相互混淆。

并且在你的 reduce 阶段,你应该像字数统计经典问题一样,只对输出进行计数和排序:

int sum = 0;
for (IntWritable val : values) {
  sum += val.get();
}
result.set(sum);
context.write(key, result);

C_AFFIX 和 CT_AFFIX 可以帮助每个类型的每个输出记录彼此相邻。