我需要有关Hadoop中的Mapreduce作业的帮助。 我有以下问题。我有一个大型数据集,其中包含多个文档+该文档的类别。我需要计算每个类别的文档中每个术语的卡方值。这意味着,我需要每个类别每个术语的出现次数+每个类别的文档数量。
我的方法是拥有一个Mapreduce作业,该作业计算每个类别中每个单词的出现次数:
输入映射器:(docId,TextOfDocument)->({term,category},docID) 减速器:(术语,{category,NumberOfOccurences})
问题是,我松散了每个类别的文档数信息,这在我的下一个Job中需要用来计算卡方值。
我考虑了以下解决方案:
1)读取文档时,请使用每个类别的计数器存储每个类别的文档数。我认为这将是最好和最简单的解决方案。问题是,我不知道类别的数量,因此我将需要动态增加计数器的数量。我没有找到在Hadoop中执行此操作的方法(创建动态增加的计数器)吗?有办法,我该怎么办?
2)首先,运行作业并计算每个类别的文档数并以某种方式存储它。我不知道如何读取数据或存储在读取整个文档时可以方便地读取。
3)用数据类型的额外值对它进行分区,并对其进行计数。
有人可以帮我解决这个问题吗?哪种方法最好?还是有其他方法? 感谢您的帮助!
答案 0 :(得分:0)
我想最终我可以找到一种解决方案,可以一次计算出按类别分类的术语数和按类别分类的文档数。
在地图阶段,您应该提取所需的内容,然后输入和输出应如下所示:
<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可以帮助每种类型座位的每个输出记录彼此相邻。