2014-06-28 3 views
1

J'essaie d'obtenir un grand nombre de documents traités avec MapReduce, l'idée est de diviser les fichiers en documents dans mapper et d'appliquer les annotateurs stanford coreNLP dans la phase de réduction. J'ai un pipeline assez simple (standard) de "tokenize, ssplit, pos, lemma, ner", et le réducteur appelle simplement une fonction qui applique ces annotateurs aux valeurs passées par le réducteur et renvoie les annotations (comme Liste des chaînes), cependant la sortie qui est générée est garbage.Appel de l'API StanfordCoreNLP avec un travail MapReduce

J'ai observé que le travail renvoie la sortie attendue si j'appelle la fonction d'annotation depuis le mappeur, mais cela bat tout le jeu de parallélisme. En outre, le travail renvoie la sortie attendue lorsque j'ignore les valeurs obtenues dans le réducteur et que j'applique simplement les annotateurs sur une chaîne factice.

Cela indique probablement qu'il y a un problème de sécurité de thread dans le processus, mais je ne suis pas en mesure de comprendre où, ma fonction d'annotation est synchronisée et le pipeline est privé final.

Quelqu'un peut-il fournir des indications sur la façon dont cela peut être résolu?

-Angshu

EDIT:

C'est ce que mon réducteur ressemble, espérons que cela ajoute plus de clarté

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()));    
     } 
    } 
} 

Et voici le code pour obtenir des extraits:

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); 
     } 
    } 
+0

Je pense que vous devez donner plus de détails (comme votre code) sur votre implémentation. – Daniel

+0

mis en place mon code, apprécierait des pointeurs. – Angshu

+0

Basé sur la mise en œuvre, je pense que s'il y a un problème, il devrait être dans le premier code (le code pour MapReduce). Est-ce que cela fonctionne bien quand au lieu de l'annotation de Stanford vous appelez une fonction triviale? – Daniel

Répondre

0

J'ai résolu le problème, en fait le problème était avec l'encodage de texte dans le fichier que j'étais Ading de (en le convertissant au texte a causé d'autres corruptions je suppose) qui causaient des problèmes dans la tokenisation et déversant des ordures. Je nettoie la chaîne d'entrée et j'applique un codage UTF-8 strict et les choses fonctionnent bien maintenant.

+0

Sélectionnez le comme réponse! :) – Daniel

Questions connexes