用Python从nltk树结构中提取特定的叶值



我对NLTK的树函数有一些疑问。我正试图从树状结构中提取一个特定的词,就像下面给出的那样。

test = Tree.parse('(ROOT(SBARQ(WHADVP(WRB How))(SQ(VBP do)(NP (PRP you))(VP(VB ask)(NP(DT a)(JJ total)(NN stranger))(PRT (RP out))(PP (IN on)(NP (DT a)(NN date)))))))')
print "Input tree: ", test
print test.leaves()
(SBARQ
    (WHADVP (WRB How))
    (SQ
      (VBP do)
      (NP (PRP you))
      (VP
        (VB ask)
        (NP (DT a) (JJ total) (NN stranger))
        (PRT (RP out))
        (PP (IN on) (NP (DT a) (NN date)))))))
['How', 'do', 'you', 'ask', 'a', 'total', 'stranger', 'out', 'on', 'a', 'date']

我可以使用leaves()函数找到所有单词的列表。有没有办法只得到一个特定的叶子?例如:我想只从NP短语中得到第一个/最后一个名词?答案应该是第一个名词是'stranger',最后一个名词是'date'。

虽然名词短语可以嵌套在其他类型的短语中,但我相信大多数语法总是在名词短语中包含名词。所以你的问题可能可以改写为:你如何找到第一个和最后一个名词?

你可以简单地得到所有的tuple的词和词性标签和过滤器像这样,

>>> [word for word,pos in test.pos() if pos=='NN']
['stranger', 'date']

在这个例子中只有2,所以你完成了。如果你有更多的名词,你只需在[0][-1]索引列表。


如果你正在寻找另一个可以在不同短语中使用的POS,但你只希望它在一个特定的短语中使用,或者如果你有一个奇怪的语法,允许名词在np之外使用,你可以这样做…

你可以找到'NP'subtrees

>>> NPs = list(test.subtrees(filter=lambda x: x.node=='NP'))
>>> NPs
[Tree('NP', [Tree('PRP', ['you'])]), Tree('NP', [Tree('DT', ['a']), Tree('JJ', ['total']), Tree('NN', ['stranger'])]), Tree('NP', [Tree('DT', ['a']), Tree('NN', ['date'])])]

继续缩小子树的范围,我们可以使用这个结果来查找'NN'单词,

>>> NNs_inside_NPs = map(lambda x: list(x.subtrees(filter=lambda x: x.node=='NN')), NPs)
>>> NNs_inside_NPs
[[], [Tree('NN', ['stranger'])], [Tree('NN', ['date'])]]

所以这是每个'NP'短语中所有'NN'listlist。在这种情况下,每个短语中恰好只有零个或一个名词。

现在我们只需要遍历'NP' s并获得所有单个名词的leaves(这实际上意味着我们只想访问Tree('NN', ['stranger'])'stranger'部分)。

>>> [noun.leaves()[0] for nouns in NNs_inside_NPs for noun in nouns]
['stranger', 'date']

最新更新