2014-12-28 2 views
2

(1) Моя цель: извлечь левую и правую части произведения.Как извлечь элементы из tree.productions()

(2) Мой подход: Я использую синтаксический анализатор stanford и инструменты nltk для извлечения parsetree предложения. Мой код ниже: «NP VP»

corenlp_dir = "/home/corenlp-python/stanford-corenlp-full-2013-11-12/" 
parser = corenlp.StanfordCoreNLP(corenlp_path=corenlp_dir) 

result_json = json.loads(parser.parse("I have a tree.")) 
for sentence in result_json["sentences"]: 
    t = Tree.fromstring(sentence["parsetree"]) 
    print t.productions() # [ROOT -> S, S -> NP VP ., NP -> PRP, PRP -> 'I', VP -> VBP NP, VBP -> 'have', NP -> DT NN, DT -> 'a', NN -> 'tree', . -> '.'] 

    print t.productions()[1] # S -> NP VP . 
    print type(productions()[1]) # <class 'nltk.grammar.Production'> 

    for (i,child) in enumerate(t): 
     print (i,child) # (0, Tree('S', [Tree('NP', [Tree('PRP', ['I'])]), Tree('VP', [Tree('VBP', ['have']), Tree('NP', [Tree('DT', ['a']), Tree('NN', ['tree'])])]), Tree('.', ['.'])])) I can only get one tree. 

(3) Мой вопрос, как я могу продолжать извлекать элементы с обеих сторон каждого производства, такие как «S» и . Можно ли использовать какой-либо метод для решения этой проблемы?

Может ли кто-нибудь помочь мне и, возможно, указать на некоторые направления?

+0

Почему вы используете метод 'productions'? Похоже на то, что вы действительно хотите сделать, - это пересечь дерево. См. Метод ['productions'] (http://www.nltk.org/api/nltk.html#nltk.tree.Tree.productions) для примера того, как перемещаться по дереву NLTK. –

+0

@JonGauthier Что я хочу сделать, так это извлечь обе стороны производственного объекта, такие как '' S ''и' 'NP VP''. Я прочитал методы' productions', но до сих пор не знаю, как Пройдите дерево правильно. Не могли бы вы показать мне пример кода? – allenwang

+0

Экземпляры 'Tree' являются итерабельными. 'для child в t: # child - это экземпляр дерева, соответствующий ребру дерева t' –

ответ

2

nltk.Tree на самом деле является подклассом Python list, так что вы можете получить доступ к детям любого узла c по c[0], c[1], c[2] и т.д. Обратите внимание, что NLTK деревья явно не бинарный дизайн, поэтому ваше понятие «левый «и« право », возможно, придется применять где-то в контракте.

Предполагая, что дерево двоично, вы можете получить доступ к левому дочернему узлу узла с помощью c[0], а справа - с c[1]. Для вашей второй задачи:

Но я хочу, чтобы извлечь левую часть произведения и собрать правую часть всех постановок с той же левой стороной.

Если я правильно понимаю, вы можете перемещаться по дереву и создать dict, как вы идете, где ключи левые части и значения являются списками возможных постановок правых. Я не уверен, что объекты nltk.Tree являются хешируемыми/неизменяемыми (если нет, они не будут использоваться в качестве ключей dict), но вы можете использовать строчную форму объектов Tree в качестве ключей в любом случае.

+0

Спасибо за ваш положительный ответ. Вы имеете в виду, что в этой задаче мне не нужно использовать 'tree.productions()'. Просто пересекая дерево и используя индекс списка, чтобы получить обе стороны производства? – allenwang

+0

Этого должно быть достаточно, если вы не хотите учитывать все дерево ниже определенного узла, а не только метку самого узла. Если вы хотите захватить все поддерево под узлом, вы можете хранить ключи как 'str (c.productions())'. Опять же, я не уверен в вашем конкретном намерении/заявлении. –

+0

Спасибо за ваш ответ. Мое намерение заключается в том, что вы получаете левую сторону и собираете все правые части всех производств. Например, 'S -> NP VP, S -> NP ADVP VP, S->, S-> ...' Достаточно ясно, чтобы объяснить мое намерение? Вы уверены, что мне не нужны 'tree.productions()'? – allenwang

Смежные вопросы