我有一个输入文件(大小约为 31GB),其中包含消费者对某些产品的评论,我正在尝试对这些产品进行词形还原并找到相应的词条计数。该方法有点类似于 Hadoop 提供的 WordCount 示例。我总共有 4 个类来执行处理:StanfordLemmatizer [包含用于从斯坦福的 coreNLP 包 v3.3.0 进行词形还原的好东西]、WordCount [驱动程序]、WordCountMapper [映射器] 和 WordCountReducer [缩减器]。
我已经在原始数据集的一个子集(以 MB 为单位)上测试了该程序,它运行良好。不幸的是,当我在大小为 ~31GB 的完整数据集上运行作业时,作业失败了。我检查了作业的系统日志,它包含以下内容:
java.lang.OutOfMemoryError: Java heap space at edu.stanford.nlp.sequences.ExactBestSequenceFinder.bestSequence(ExactBestSequenceFinder.java:109) [...]
关于如何处理这个问题有什么建议吗?
注意:我使用的是预配置了 hadoop-0.18.0 的 Yahoo 虚拟机。我还尝试了此线程中提到的分配更多堆的解决方案:out of Memory Error in Hadoop
WordCountMapper 代码:
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.MapReduceBase;
import org.apache.hadoop.mapred.Mapper;
import org.apache.hadoop.mapred.OutputCollector;
import org.apache.hadoop.mapred.Reporter;
public class WordCountMapper extends MapReduceBase
implements Mapper<LongWritable, Text, Text, IntWritable> {
private final IntWritable one = new IntWritable(1);
private final Text word = new Text();
private final StanfordLemmatizer slem = new StanfordLemmatizer();
public void map(LongWritable key, Text value,
OutputCollector output, Reporter reporter) throws IOException {
String line = value.toString();
if(line.matches("^review/(summary|text).*")) //if the current line represents a summary/text of a review, process it!
{
for(String lemma: slem.lemmatize(line.replaceAll("^review/(summary|text):.", "").toLowerCase()))
{
word.set(lemma);
output.collect(word, one);
}
}
}
}
最佳答案
您需要使正在处理的各个单元(即 map-reduce 中的每个 Map 作业)的大小合理。第一个单位是您提供给 StanfordCoreNLP 的 annotate() 调用的文档的大小。您在此处提供的整段文本将在内存中进行标记和处理。在标记化和处理的形式中,它比它在磁盘上的大小大一个数量级。因此,文档大小需要合理。例如,您可能一次传递一个消费者评论(而不是 31GB 的文本文件!)
其次,向下一级,词性标注器(在词形还原之前)一次标注一个句子,它使用大型临时动态编程数据结构来标注一个句子,其大小可能大 3 个数量级比句子。所以,单个句子的长度也需要合理。如果有很长的文本或垃圾没有分成句子,那么你也可能在这个级别有问题。一种简单的解决方法是使用 pos.maxlen
属性来避免 POS 标记超长句子。
附注当然,如果您只需要词形还原器,则不应运行您未使用的注释器,例如 parse、dcoref。
关于运行 Hadoop 作业时出现 java.lang.OutOfMemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20247185/