Извлечение поддеревьев с использованием Stanford Tregex - PullRequest
0 голосов
/ 08 июля 2011

Я создал класс для извлечения поддеревьев с помощью Tregex. Я использовал некоторые фрагменты кода из «TregexPattern.java», так как я не хочу, чтобы программа использовала консольные команды.

В общем, имея дерево для предложения, я хочу извлечь определенное поддерево (без взаимодействия с пользователем).

пока что я сделал следующее:

package edu.stanford.nlp.trees.tregex;
import edu.stanford.nlp.ling.StringLabelFactory;
import edu.stanford.nlp.trees.*;
import java.io.*;
import java.util.*;
public abstract class Test {
    abstract TregexMatcher matcher(Tree root, Tree tree, Map<String, Tree> namesToNodes, VariableStrings variableStrings);
    public TregexMatcher matcher(Tree t) {
        return matcher(t, t, new HashMap<String, Tree>(), new VariableStrings());
    }
    public static void main(String[] args) throws ParseException, IOException {
        String encoding = "UTF-8";
        TregexPattern p = TregexPattern.compile("NP < NN & <<DT"); //"/^MWV/" or "NP < (NP=np < NNS)"
        TreeReader r = new PennTreeReader(new StringReader("(VP (VP (VBZ Try) (NP (NP (DT this) (NN wine)) (CC and) (NP (DT these) (NNS snails)))) (PUNCT .))"), new LabeledScoredTreeFactory(new StringLabelFactory()));
        Tree t = r.readTree();
        treebank = new MemoryTreebank();
        treebank.add(t);
        TRegexTreeVisitor vis = new TRegexTreeVisitor(p, encoding);
        **treebank.apply(vis);  //line 26**
        if (TRegexTreeVisitor.printMatches) {
            System.out.println("There were " + vis.numMatches() + " matches in total.");
        }
    }
    private static Treebank treebank; // used by main method, must be accessible
    static class TRegexTreeVisitor implements TreeVisitor {
        private static boolean printNumMatchesToStdOut = false;
        static boolean printNonMatchingTrees = false;
        static boolean printSubtreeCode = false;
        static boolean printTree = false;
        static boolean printWholeTree = false;
        static boolean printMatches = true;
        static boolean printFilename = false;
        static boolean oneMatchPerRootNode = false;
        static boolean reportTreeNumbers = false;
        static TreePrint tp;
        PrintWriter pw;
        int treeNumber = 0;
        TregexPattern p;
        //String[] handles;
        int numMatches;
        TRegexTreeVisitor(TregexPattern p, String encoding) {
            this.p = p;
            //this.handles = handles;
            try {
                pw = new PrintWriter(new OutputStreamWriter(System.out, encoding), true);
            } catch (UnsupportedEncodingException e) {
                System.err.println("Error -- encoding " + encoding + " is unsupported.  Using ASCII print writer instead.");
                pw = new PrintWriter(System.out, true);
            }
            // tp.setPrintWriter(pw);
        }
        public void visitTree(Tree t) {
            treeNumber++;
            if (printTree) {
                pw.print(treeNumber + ":");
                pw.println("Next tree read:");
                tp.printTree(t, pw);
            }
            TregexMatcher match = p.matcher(t);
            if (printNonMatchingTrees) {
                if (match.find()) {
                    numMatches++;
                } else {
                    tp.printTree(t, pw);
                }
                return;
            }
            Tree lastMatchingRootNode = null;
            while (match.find()) {
                if (oneMatchPerRootNode) {
                    if (lastMatchingRootNode == match.getMatch()) {
                        continue;
                    } else {
                        lastMatchingRootNode = match.getMatch();
                    }
                }
                numMatches++;
                if (printFilename && treebank instanceof DiskTreebank) {
                    DiskTreebank dtb = (DiskTreebank) treebank;
                    pw.print("# ");
                    pw.println(dtb.getCurrentFile());
                }
                if (printSubtreeCode) {
                    pw.println(treeNumber + ":" + match.getMatch().nodeNumber(t));
                }
                if (printMatches) {
                    if (reportTreeNumbers) {
                        pw.print(treeNumber + ": ");
                    }
                    if (printTree) {
                        pw.println("Found a full match:");
                    }
                    if (printWholeTree) {
                        tp.printTree(t, pw);
                    } else {
                        **tp.printTree(match.getMatch(), pw);  //line 108**
                    }
                    // pw.println();  // TreePrint already puts a blank line in
                } // end if (printMatches)
            } // end while match.find()
        } // end visitTree
        public int numMatches() {
            return numMatches;
        }
    } // end class TRegexTreeVisitor
}

но выдает следующую ошибку:

Exception in thread "main" java.lang.NullPointerException
        at edu.stanford.nlp.trees.tregex.Test$TRegexTreeVisitor.visitTree(Test.java:108)
        at edu.stanford.nlp.trees.MemoryTreebank.apply(MemoryTreebank.java:376)
        at edu.stanford.nlp.trees.tregex.Test.main(Test.java:26)
Java Result: 1

Любые модификации или идеи?

1 Ответ

1 голос
/ 12 июля 2011

NullPointerException обычно является индикатором ошибки в программном обеспечении.

У меня была такая же задача в прошлом. Предложение было проанализировано с помощью анализатора зависимостей. Я решил поместить получающееся дерево разбора в XML (DOM) и выполнять над ним запросы XPath.

Для повышения производительности вам не нужно помещать xml в строку, просто сохраняйте всю структуру XML как DOM в памяти (например, http://www.ibm.com/developerworks/xml/library/x-domjava/).

Использование XPath для запроса древовидной структуры данных дало мне следующие преимущества:

  1. Загрузка / сохранение / передача результатов разбора предложения легко.
  2. Надежный синтаксис / возможности XPath.
  3. Многие знают XPath (каждый может настроить ваш запрос).
  4. XML и XPath являются кроссплатформенными.
  5. Множество стабильных реализаций библиотек XPath и XML / DOM.
  6. Возможность использования XSLT.
  7. Интеграция с существующим конвейером на основе XML XSLT + XPath -> XSD -> Выполнить действия (например, пользователи указали свой адрес электронной почты и действие, что с ним делать где-то внутри свободного текста). жалоба) .
...