2017-06-09 3 views
0

Ich versuche mein eigenes Sentiment-Analyse-Modell für corenlp zu trainieren. Ich möchte dies in Java-Code (nicht von der Befehlszeile) tun, also kopierte ich Stücke von https://github.com/stanfordnlp/CoreNLP/blob/master/src/edu/stanford/nlp/sentiment/BuildBinarizedDataset.java, um die Daten vorzubereiten, und dann einige Stücke von https://github.com/stanfordnlp/CoreNLP/blob/master/src/edu/stanford/nlp/sentiment/SentimentTraining.java kopieren, um das eigentliche Training zu tun. Ich kondensierte, um den Code der früheren Verbindung, Zeilen 171-226 ein bisschen in meinem eigenen Code (zu verstehen, was los ist), in die folgenden:CoreNLP Sentiment Trainingsdaten im falschen Format

String text = IOUtils.slurpFileNoExceptions(inputPath); 
    String[] chunks = text.split("\\n\\s*\\n+"); // need blank line to 
    for (String chunk : chunks) { 
     if (chunk.trim().isEmpty()) { 
      continue; 
     } 
     String[] lines = chunk.trim().split("\\n"); 
     String sentence = lines[0]; 
     StringReader sin = new StringReader(sentence); 
     DocumentPreprocessor document = new DocumentPreprocessor(sin); 
     document.setSentenceFinalPuncWords(new String[] { "\n" }); 
     List<HasWord> tokens = document.iterator().next(); 
     Integer mainLabel = new Integer(tokens.get(0).word()); 
     tokens = tokens.subList(1, tokens.size()); 
     Map<Pair<Integer, Integer>, String> spanToLabels = Generics.newHashMap(); 
     for (int i = 1; i < lines.length; ++i) { 
      extractLabels(spanToLabels, tokens, lines[i]); 
     } 
     Tree tree = parser.apply(tokens); 
     Tree binarized = binarizer.transformTree(tree); 
     Tree collapsedUnary = transformer.transformTree(binarized); 
     if (sentimentModel != null) { 
      Trees.convertToCoreLabels(collapsedUnary); 
      SentimentCostAndGradient scorer = new SentimentCostAndGradient(sentimentModel, null); 
      scorer.forwardPropagateTree(collapsedUnary); 
      setPredictedLabels(collapsedUnary); 
     } else { 
      setUnknownLabels(collapsedUnary, mainLabel); 
     } 
     Trees.convertToCoreLabels(collapsedUnary); 
     collapsedUnary.indexSpans(); 
     for (Map.Entry<Pair<Integer, Integer>, String> pairStringEntry : spanToLabels.entrySet()) { 
      setSpanLabel(collapsedUnary, pairStringEntry.getKey(), pairStringEntry.getValue()); 
     } 

     //trainingTrees.add(collapsedUnary); 
     System.out.println("Debugging collaped Unary:" + collapsedUnary); 
    } 

Die println gibt mir so etwas wie:

> Debugging collaped Unary:(ROOT (NP (DT The) (NNS performances)) (@S (VP (VBP are) (ADJP (RB uniformly) (JJ good))) (. .))) 

während von dem, was ich verstehe, ist es wie folgt aussehen soll (wie für das Format, leider einen anderen Satz hier zum Kopieren)):

(3 (2 (2 The) (2 Rock)) (4 (3 (2 is) (4 (2 destined) (2 (2 (2 (2 (2 

wie in https://mailman.stanford.edu/pipermail/java-nlp-user/2013-November/004308.html erklärt, stanford corenlp sentiment training set, How to train the Stanford NLP Sentiment Analysis tool usw.

Nichts passiert nach diesen Zeilen in BuildBinarizedDataset. Kann mir jemand sagen, wie man es ins richtige Format bringt? (. Hacking etwas zusammen fühlt mich hier ziemlich dumm, und es muss etwas, was ich bin fehlt)

dh die Fehler, die ich später bekommen, in SentimentTraining ist:

Exception in thread "main" java.lang.NumberFormatException: For input string: "DT" 
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
at java.lang.Integer.parseInt(Integer.java:580) 
at java.lang.Integer.valueOf(Integer.java:766) 
at edu.stanford.nlp.sentiment.SentimentUtils.attachLabels(SentimentUtils.java:37) 
at edu.stanford.nlp.sentiment.SentimentUtils.attachLabels(SentimentUtils.java:33) 
at edu.stanford.nlp.sentiment.SentimentUtils.attachLabels(SentimentUtils.java:33) 
at edu.stanford.nlp.sentiment.SentimentUtils.readTreesWithLabels(SentimentUtils.java:69) 
at edu.stanford.nlp.sentiment.SentimentUtils.readTreesWithGoldLabels(SentimentUtils.java:50) 
at de.dkt.eservices.esentimentanalysis.modules.CoreNLPSentimentAnalyzer.trainModel(CoreNLPSentimentAnalyzer.java:251) 
at de.dkt.eservices.esentimentanalysis.modules.CoreNLPSentimentAnalyzer.main(CoreNLPSentimentAnalyzer.java:306) 

was Sinn macht, da dass es eine Zahl erwartet, aber die Bezeichnung des Knotens in der Baumstruktur bekommt ...

Wäre dankbar für irgendwelche Hinweise hier!

Antwort

0

haben keine wirkliche Lösung gefunden, aber falls jemand läuft sonst in dieses Problem, hat folgendes den Trick:

public static Tree traverseTreeAndChangePosTagsToNumbers(Tree tree) { 

    for (Tree subtree : tree.getChildrenAsList()) { 
     if (subtree.label().toString().matches("\\D+")) { 
      subtree.label().setValue("2"); 

     }if (Integer.parseInt(subtree.label().toString())<0||Integer.parseInt(subtree.label().toString())>4){ 
      subtree.label().setValue("2"); 
     } 
     if (!(subtree.isPreTerminal())) { 
      traverseTreeAndChangePosTagsToNumbers(subtree); 
     } 
    } 

    return tree; 
} 

Nicht wirklich eine anständige Lösung, da es die Möglichkeit, nicht anerkennen zu schaffen Spielraum für Sentiment (dh Annotationen von Subphrasen in der Struktur, da die Anzahl der Subphrasen immer 2 (neutral) ist), so basiert Sentiment immer auf dem Wert für den gesamten Satz/Baum, aber zumindest beseitigt es den Syntaxfehler.

Verwandte Themen