我需要一些关于Hadoop中Mapreduce作业的帮助。我有以下问题。我有一个包含多个文档+文档类别的大型数据集。我需要计算每个类别的文档中每个术语的卡方值。这意味着,我需要每个类别每个术语的出现次数+每个类别的文档数量。
我的方法是有一个Mapreduce作业,它计算每个类别的每个单词的出现次数:
输入映射器:(docId,TextOfDocument) - >({term,category},docID)Reducer :( term,{category,NumberOfOccurences})
这个问题是,我丢失了每个类别的文档数量的信息,我将在下一个Job中计算卡方值。
我想到了以下解决方案:
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:只是标识符,可以帮助这两种不同类型的密钥相互混合。
在你的缩减阶段,你应该像字数统计经典问题一样,只计算和排序输出:
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
C_AFFIX和CT_AFFIX可以帮助每种类型的每个输出记录彼此相邻。