Получить определенные узлы из дерева синтаксического анализа

Я работаю над проектом, связанным с разрешением анафоры с помощью алгоритма Хоббса. Я проанализировал свой текст с помощью синтаксического анализатора Stanford, и теперь я хотел бы манипулировать узлами, чтобы реализовать свой алгоритм.

На данный момент я не понимаю, как:

  • Доступ к узлу на основе его POS-тега (например, мне нужно начать с местоимения — как мне получить все местоимения?).

  • Используйте посетителей. Я немного новичок в Java, но в C++ мне нужно было реализовать функтор Visitor, а затем работать с его крючками. Однако я не смог найти много для структуры дерева Стэнфордского парсера. Это джграфт? Если это так, не могли бы вы дать мне несколько указателей на фрагменты кода?


person Tex    schedule 06.05.2012    source источник


Ответы (2)


Ответ @dhg работает нормально, но вот еще два варианта, о которых также может быть полезно знать:

  • Класс Tree реализует Iterable. Вы можете перебирать все узлы Tree или, строго говоря, поддеревья, возглавляемые каждым узлом, в предварительном обходе с помощью:

    for (Tree subtree : t) { 
        if (subtree.label().value().equals("PRP")) {
            pronouns.add(subtree);
        }
    }
    
  • Вы также можете получить только узлы, которые удовлетворяют некоторому (потенциально довольно сложному шаблону), используя tregex, который ведет себя скорее как java.util.regex, разрешая сопоставление шаблонов по деревьям. У вас будет что-то вроде:

    TregexPattern tgrepPattern = TregexPattern.compile("PRP");
    TregexMatcher m = tgrepPattern.matcher(t);
    while (m.find()) {
        Tree subtree = m.getMatch();
        pronouns.add(subtree);
    }
    
person Christopher Manning    schedule 08.05.2012
comment
Благодарю вас! Мне достаточно метода .children(), чтобы написать на нем итератор BFS, но на будущее: почему я не совместим с jgrapht? Я читал, что вы использовали эту библиотеку для построения своей древовидной структуры, поэтому я подумал, что так и должно быть! Последнее, что мне нужно, это пометить слово тегом POS — скажем, у меня есть t = (PRP he). С помощью t.label().value() я могу получить PRP, как мне его получить? Еще раз спасибо! знак равно - person Tex; 09.05.2012
comment
Класс Tree не использует jgrapht. (Несмотря на то, что он был модифицирован различными способами, такими как реализация Iterable, класс Tree изначально был написан для JDK 1.1, до того, как появился jgrapht, и в некотором смысле показывает его возраст....) Ранее мы использовали jgrapht для наших графов зависимостей. , но недавно отошли от него. У нас сложилось впечатление, что многие люди предпочитают меньше библиотечных зависимостей. Чтобы получить слово, вы опускаетесь на один уровень subtree.firstChild().label().value(). - person Christopher Manning; 09.05.2012

Вот простой пример, который анализирует предложение и находит все местоимения.

private static ArrayList<Tree> findPro(Tree t) {
    ArrayList<Tree> pronouns = new ArrayList<Tree>();
    if (t.label().value().equals("PRP"))
        pronouns.add(t);
    else
        for (Tree child : t.children())
            pronouns.addAll(findPro(child));
    return pronouns;
}

public static void main(String[] args) {

    LexicalizedParser parser = LexicalizedParser.loadModel();
    Tree x = parser.apply("The dog walks and he barks .");
    System.out.println(x);
    ArrayList<Tree> pronouns = findPro(x);
    System.out.println("All Pronouns: " + pronouns);

}

Это печатает:

    (ROOT (S (S (NP (DT The) (NN dog)) (VP (VBZ walks))) (CC and) (S (NP (PRP he)) (VP (VBZ barks))) (. .)))
    All Pronouns: [(PRP he)]
person dhg    schedule 07.05.2012
comment
Благодарю вас! Не могли бы вы дать мне больше информации о посещении этого дерева? Например, является ли t.children() посещением BFS? - person Tex; 07.05.2012
comment
@Davide: children возвращает только дочерние элементы, поэтому вам нужно самостоятельно построить обход DFS или BFS. См. документацию по API. - person Fred Foo; 07.05.2012
comment
Еще один вопрос: я получаю тег POS с помощью t.label().value(). Как мне получить настоящее слово? то есть, скажем, у меня есть t = (PRP he). С помощью t.label().value() я могу получить PRP, как мне его получить? - person Tex; 07.05.2012
comment
@Tex вы можете получить, получив t.children().get(i).value() ... он - person swapyonubuntu; 05.07.2015