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

Cry*_*sie 6 python tree 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']
Run Code Online (Sandbox Code Playgroud)

我可以使用leaves()函数找到所有单词的列表.有没有办法获得特定的叶子?例如:我想从NP短语中获取第一个/最后一个名词?答案对于第一个名词是"陌生人"而​​对于最后一个名词是"日期".

Jar*_*red 11

尽管名词短语可以嵌套在其他类型的短语中,但我相信大多数语法总是在名词短语中使用名词.所以你的问题可能会改为:你怎么找到第一个和最后一个名词?

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

>>> [word for word,pos in test.pos() if pos=='NN']
['stranger', 'date']
Run Code Online (Sandbox Code Playgroud)

在这种情况下只有两个,所以你已经完成了.如果你有更多的名词,你只需将列表索引为[0]和[-1].


如果您正在寻找可以在不同短语中使用的另一个POS,但您只想在特定的一个中使用它,或者如果您有一个允许在NP之外使用名词的奇怪语法,您可以执行以下操作...

你可以找到subtrees,'NP'做

>>> 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'])])]
Run Code Online (Sandbox Code Playgroud)

继续缩小子树,我们可以使用这个结果来寻找'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'])]]
Run Code Online (Sandbox Code Playgroud)

所以这是一个list的list所有的第'NN'每个在s 'NP'短语.在这种情况下,每个短语中恰好只有零个或一个名词.

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

>>> [noun.leaves()[0] for nouns in NNs_inside_NPs for noun in nouns]
['stranger', 'date']
Run Code Online (Sandbox Code Playgroud)