这可能是一个愚蠢的问题,但如何将解析树作为NLP解析器(如Stanford NLP)的输出进行迭代?它都是嵌套的方括号,既不是array
,也不是dictionary
,也不是我使用过的任何其他集合类型。
(ROOTn (Sn (PP (IN As)n (NP (DT an) (NN accountant)))n (NP (PRP I))n (VP (VBP want)n (Sn (VP (TO to)n (VP (VB make)n (NP (DT a) (NN payment))))))))
Stanford Parser的这种特殊输出格式被称为"括号内解析(树)"。它应该被读取为具有的图形
- 单词作为节点(例如as、an、accounter)
- 短语/从句作为标签(例如S、NP、VP)
- 边按层次进行链接
- 通常解析的TOP或根节点是幻觉
ROOT
(在这种情况下,您可以将其读取为有向无循环图(DAG),因为它是单向和非循环的)
有一些库可以读取方括号解析,例如在NLTK
的nltk.tree.Tree
中(http://www.nltk.org/howto/tree.html):
>>> from nltk.tree import Tree
>>> output = '(ROOT (S (PP (IN As) (NP (DT an) (NN accountant))) (NP (PRP I)) (VP (VBP want) (S (VP (TO to) (VP (VB make) (NP (DT a) (NN payment))))))))'
>>> parsetree = Tree.fromstring(output)
>>> print parsetree
(ROOT
(S
(PP (IN As) (NP (DT an) (NN accountant)))
(NP (PRP I))
(VP
(VBP want)
(S (VP (TO to) (VP (VB make) (NP (DT a) (NN payment))))))))
>>> parsetree.pretty_print()
ROOT
|
S
______________________|________
| | VP
| | ________|____
| | | S
| | | |
| | | VP
| | | ________|___
PP | | | VP
___|___ | | | ________|___
| NP NP | | | NP
| ___|______ | | | | ___|_____
IN DT NN PRP VBP TO VB DT NN
| | | | | | | | |
As an accountant I want to make a payment
>>> parsetree.leaves()
['As', 'an', 'accountant', 'I', 'want', 'to', 'make', 'a', 'payment']
请注意,如果您对树中由类似正则表达式的规则标识的特定节点感兴趣,您可以使用这个非常非常手工的类来使用类似正则表达式匹配器提取所有此类节点:
http://nlp.stanford.edu/nlp/javadoc/javanlp/edu/stanford/nlp/trees/tregex/TregexPattern.html