使用MapReduce作业调用StanfordCoreNLP API

时间:2014-06-28 14:51:25

标签: java mapreduce nlp stanford-nlp hadoop2

我正在尝试使用MapReduce处理大量文档,其目的是将文件拆分为mapper中的文档,并在reducer阶段应用stanford coreNLP注释器。

我有一个相当简单(标准)的" tokenize,ssplit,pos,lemma,ner"的管道,而reducer只调用一个函数,将这些注释器应用于reducer传递的值并返回注释(作为字符串列表),但生成的输出是垃圾。

我观察到如果我从mapper中调用注释函数,作业将返回预期的输出,但这会击败整个并行游戏。当我忽略reducer中获得的值时,作业返回预期的输出,只需在虚拟字符串上应用注释器。

这可能表明在这个过程中存在一些线程安全问题,但是我无法弄清楚我的注释函数在哪里同步,管道是私有的最终版本。

有人可以提供一些指示,说明如何解决这个问题吗?

-Angshu

编辑:

这就是我的减速机的样子,希望这会增加清晰度

public static class Reduce extends MapReduceBase implements Reducer<Text, Text, Text, Text> {
    public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, Text> output, Reporter reporter) throws IOException {
        while (values.hasNext()) {
            output.collect(key, new Text(se.getExtracts(values.next().toString()).toString()));             
        }
    }
}

这是获取摘录的代码:

final StanfordCoreNLP pipeline; 
public instantiatePipeline(){
    Properties props = new Properties();
    props.put("annotators", "tokenize, ssplit, pos, lemma, ner");

}


synchronized List<String> getExtracts(String l){
    Annotation document = new Annotation(l);

    ArrayList<String> ret = new ArrayList<String>();

    pipeline.annotate(document);

    List<CoreMap> sentences = document.get(SentencesAnnotation.class);
    int sid = 0;
    for(CoreMap sentence:sentences){
        sid++;
        for(CoreLabel token: sentence.get(TokensAnnotation.class)){
            String word = token.get(TextAnnotation.class);
            String pos = token.get(PartOfSpeechAnnotation.class);
            String ner = token.get(NamedEntityTagAnnotation.class);
            String lemma = token.get(LemmaAnnotation.class);

            Timex timex = token.get(TimeAnnotations.TimexAnnotation.class);

            String ex = word+","+pos+","+ner+","+lemma;
            if(timex!=null){
                ex = ex+","+timex.tid();
            }
            else{
                ex = ex+",";
            }
            ex = ex+","+sid;
            ret.add(ex);
        }
    }

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,实际上问题在于我正在读取的文件中的文本编码(将其转换为Text会导致进一步的损坏),这会导致令牌化和溢出垃圾问题。我正在清理输入字符串并应用严格的UTF-8编码,现在工作正常。