【问题标题】:How to navigate a nltk.tree.Tree?如何导航 nltk.tree.Tree?
【发布时间】:2013-02-12 21:17:08
【问题描述】:

我使用以下方法对句子进行了分块:

grammar = '''                                                                                                              
    NP:                                                                                                                    
       {<DT>*(<NN.*>|<JJ.*>)*<NN.*>}                                                                                       
     NVN:                                                                                                                  
       {<NP><VB.*><NP>}                                                                                                    
    '''
chunker = nltk.chunk.RegexpParser(grammar)
tree = chunker.parse(tagged)
print tree

结果如下:

(S
  (NVN
    (NP The_Pigs/NNS)
    are/VBP
    (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN))
  that/WDT
  formed/VBN
  in/IN
  1977/CD
  ./.)

但现在我一直在试图弄清楚如何导航。我希望能够找到 NVN 子树,并访问左侧的名词短语(“The_Pigs”)、动词(“are”)和右侧的名词短语(“a Bristol-based punk rock band”) .我该怎么做?

【问题讨论】:

  • 你能把叶子节点的完整语法贴出来,然后我可以给你一个清晰的例子吗?

标签: tree nltk


【解决方案1】:

试试:

ROOT = 'ROOT'
tree = ...
def getNodes(parent):
    for node in parent:
        if type(node) is nltk.Tree:
            if node.label() == ROOT:
                print "======== Sentence ========="
                print "Sentence:", " ".join(node.leaves())
            else:
                print "Label:", node.label()
                print "Leaves:", node.leaves()

            getNodes(node)
        else:
            print "Word:", node

getNodes(tree)

【讨论】:

【解决方案2】:

当然,您可以编写自己的深度优先搜索...但是有一种更简单(更好)的方法。如果您希望每个子树都以 NVM 为根,请使用 Tree 的子树方法并定义过滤器参数。

>>> print t
(S
    (NVN
        (NP The_Pigs/NNS)
        are/VBP
        (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN))
    that/WDT
    formed/VBN
    in/IN
    1977/CD
    ./.)
>>> for i in t.subtrees(filter=lambda x: x.node == 'NVN'):
...     print i
... 
(NVN
    (NP The_Pigs/NNS)
    are/VBP
    (NP a/DT Bristol-based/JJ punk/NN rock/NN band/NN))

【讨论】:

  • 在 Python 3.5 和 NLTK 3.2.2 中,lambda 函数应该使用节点的 label() 属性:filter=lambda x: x.label() == "NP"
【解决方案3】:

这是一个代码示例,用于生成带有标签“NP”的所有子树

def filt(x):
    return x.label()=='NP'

for subtree in t.subtrees(filter =  filt): # Generate all subtrees
    print subtree

对于兄弟姐妹,你可能想看看方法ParentedTree.left_siblings()

更多详情,这里有一些有用的链接。

http://www.nltk.org/howto/tree.html #一些基本用法和例子 http://nbviewer.ipython.org/github/gmonce/nltk_parsing/blob/master/1.%20NLTK%20Syntax%20Trees.ipynb#笔记本玩转这些方法

http://www.nltk.org/_modules/nltk/tree.html#all api with source

【讨论】:

    【解决方案4】:

    试试这个:

    for a in tree:
            if type(a) is nltk.Tree:
                if a.node == 'NVN': # This climbs into your NVN tree
                    for b in a:
                        if type(b) is nltk.Tree and b.node == 'NP':
                            print b.leaves() # This outputs your "NP"
                        else:
                            print b # This outputs your "VB.*"
    

    它输出这个:

    [('The_Pigs', 'NNS')]

    ('是', 'VBP')

    [('a', 'DT'), ('Bristol-based', 'JJ'), ('punk', 'NN'), ('rock', 'NN'), ('乐队', 'NN')]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-23
      • 2019-02-18
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多