【问题标题】:Get entities from NLTK.tree result从 NLTK.tree 结果中获取实体
【发布时间】:2014-10-07 10:38:09
【问题描述】:

我的原句是

海啸地震也与薄层的存在有关 沿地壳最上部的俯冲沉积岩层 板界面,被认为存在于重要区域 海洋地壳顶部的地形,以及传播的地方 朝上倾方向,可能到达海底。

我将句子传递给斯坦福 NLP 并得到了漂亮的解析树:

(ROOT (S (NP (NN Tsunami) (NNS地震)) (VP (VBP)) (ADVP (RB 也))(VP(VBN被)(VP(VBN联)(PP(TO))(NP(NP(DT)) (NN 存在)) (PP (IN of) (NP (NP (DT a) (JJ 薄) (NN 层)) ​​(PP (IN 的) (S (VP (VBN 俯冲) (NP (NP (JJ 沉积) (NN 岩石)) (PP) (IN沿)(NP(NP(NP(DT))(JJS最上)(NN部分))(PP(IN) (NP (DT) (NN 板) (NN 接口))) (, ,) (UCP (RB as) (S (VP (VBZ 是) (VP (VBN 认为) (S (VP (TO 到) (VP (VB 是) (ADJP (JJ) 当前) (PP (IN in) (NP (NP (NNS 地区)) (PP (IN)) (NP (JJ 显着) (NN 地形)))))) (PP (IN at) (NP (NP (DT the)) (NN 顶部))(PP(IN)(NP(DT)(JJ海洋)(NN地壳))))))))))(,,) (CC 和) (SBAR (WHADVP (WRB where)) (S (NP (NN 传播)) (VP (VBD) 是) (PP (IN in) (NP (DT an) (JJ 上倾) (NN 方向))) (, ,) (ADVP (RB可能)))))))))(S(VP(VBG到达)(NP(DT))(NN 海底)))))))))))))))))(..)))

然后我将上面的字符串提供给 NLTK.Tree:

pasrsd_tree = NLTK.Tree.fromstring(parsetree_string)

结果还不错:

Tree('ROOT', [Tree('S', [Tree('NP', [Tree('NN', ['Tsunami']), Tree('NNS', ['earthquakes'])]), Tree('VP', [Tree('VBP', ['have']), 树('ADVP', [Tree('RB', ['also'])]), Tree('VP', [Tree('VBN', ['been']), Tree('VP', [Tree('VBN', ['linked']), Tree('PP', [Tree('TO', ['to']), Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('NN', ['presence'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [树('NP',[树('DT',['a']),树('JJ',['瘦']),树('NN', ['layer'])]), Tree('PP', [Tree('IN', ['of']), Tree('S', [Tree('VP', [Tree('VBN', ['subducted']), Tree('NP', [Tree('NP', [Tree('JJ', ['sedimentary']), Tree('NN', ['rock'])]), Tree('PP', [Tree('IN', ['沿']), 树('NP', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJS', ['uppermost']), Tree('NN', ['part'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('DT', ['the']), Tree('NN', ['plate']), Tree('NN', ['interface'])])])]), Tree(',', [',']), 树('UCP',[树('RB',['as']),树('S',[树('VP',[树('VBZ', ['is']), Tree('VP', [Tree('VBN', ['thought']), Tree('S', [Tree('VP', [Tree('TO', ['to']), Tree('VP', [Tree('VB', ['be']), Tree('ADJP', [Tree('JJ', ['present']), Tree('PP', [Tree('IN', ['in']), Tree('NP', [Tree('NP', [Tree('NNS', ['areas'])]), Tree('PP', [Tree('IN', ['of']), 树('NP',[树('JJ',['显着']),树('NN', ['topography'])])])])])]), Tree('PP', [Tree('IN', ['at']), Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('NN', ['top'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['oceanic']), Tree('NN', ['crust'])])])])])])])])])])]), Tree(',', [',']), Tree('CC', ['and']), Tree('SBAR', [Tree('WHADVP', [Tree('WRB', ['where'])]), Tree('S', [Tree('NP', [Tree('NN', ['propagation'])]), 树('VP',[树('VBD',['was']),树('PP',[树('IN',['in']), Tree('NP', [Tree('DT', ['an']), Tree('JJ', ['up-dip']), Tree('NN', ['direction'])])]), Tree(',', [',']), Tree('ADVP', [Tree('RB', ['可能'])])])])])])])])]), Tree('S', [Tree('VP', [Tree('VBG', ['reaching']), Tree('NP', [Tree('DT', ['the']), Tree('NN', ['海底'])])])])])])])])])])])])])]), Tree('.', ['.'])])])

我的问题是,给定 pared_tree,我怎样才能获得像 top of the oceanic crust、a thin layer 这样的左级实体?

我在想解析树的层次可能有用,但是当我看树层次时我真的迷路了,不知道该怎么做。

我主要基于 Python,斯坦福 NLP 结果是使用 Python 包装器获得的 (https://bitbucket.org/torotoki/corenlp-python)。

谁能帮助我,也许可以指出一些方向?

【问题讨论】:

    标签: python tree nltk


    【解决方案1】:

    您可以尝试提取标记为NP 的子树:

    >>> from nltk import Tree
    >>> parsed_tree = Tree('ROOT', [Tree('S', [Tree('NP', [Tree('NN', ['Tsunami']), Tree('NNS', ['earthquakes'])]), Tree('VP', [Tree('VBP', ['have']), Tree('ADVP', [Tree('RB', ['also'])]), Tree('VP', [Tree('VBN', ['been']), Tree('VP', [Tree('VBN', ['linked']), Tree('PP', [Tree('TO', ['to']), Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('NN', ['presence'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('NP', [Tree('DT', ['a']), Tree('JJ', ['thin']), Tree('NN', ['layer'])]), Tree('PP', [Tree('IN', ['of']), Tree('S', [Tree('VP', [Tree('VBN', ['subducted']), Tree('NP', [Tree('NP', [Tree('JJ', ['sedimentary']), Tree('NN', ['rock'])]), Tree('PP', [Tree('IN', ['along']), Tree('NP', [Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('JJS', ['uppermost']), Tree('NN', ['part'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('DT', ['the']), Tree('NN', ['plate']), Tree('NN', ['interface'])])])]), Tree(',', [',']), Tree('UCP', [Tree('RB', ['as']), Tree('S', [Tree('VP', [Tree('VBZ', ['is']), Tree('VP', [Tree('VBN', ['thought']), Tree('S', [Tree('VP', [Tree('TO', ['to']), Tree('VP', [Tree('VB', ['be']), Tree('ADJP', [Tree('JJ', ['present']), Tree('PP', [Tree('IN', ['in']), Tree('NP', [Tree('NP', [Tree('NNS', ['areas'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('JJ', ['significant']), Tree('NN', ['topography'])])])])])]), Tree('PP', [Tree('IN', ['at']), Tree('NP', [Tree('NP', [Tree('DT', ['the']), Tree('NN', ['top'])]), Tree('PP', [Tree('IN', ['of']), Tree('NP', [Tree('DT', ['the']), Tree('JJ', ['oceanic']), Tree('NN', ['crust'])])])])])])])])])])]), Tree(',', [',']), Tree('CC', ['and']), Tree('SBAR', [Tree('WHADVP', [Tree('WRB', ['where'])]), Tree('S', [Tree('NP', [Tree('NN', ['propagation'])]), Tree('VP', [Tree('VBD', ['was']), Tree('PP', [Tree('IN', ['in']), Tree('NP', [Tree('DT', ['an']), Tree('JJ', ['up-dip']), Tree('NN', ['direction'])])]), Tree(',', [',']), Tree('ADVP', [Tree('RB', ['possibly'])])])])])])])])]), Tree('S', [Tree('VP', [Tree('VBG', ['reaching']), Tree('NP', [Tree('DT', ['the']), Tree('NN', ['seafloor'])])])])])])])])])])])])])]), Tree('.', ['.'])])])
    
    >>> np = [" ".join(i.leaves()) for i in parsed_tree.subtrees() if i.label() == 'NP']
    >>> np
    ['Tsunami earthquakes', 'the presence of a thin layer of subducted sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly reaching the seafloor', 'the presence', 'a thin layer of subducted sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly reaching the seafloor', 'a thin layer', 'sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly', 'sedimentary rock', 'the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly', 'the uppermost part of the plate interface', 'the uppermost part', 'the plate interface', 'areas of significant topography', 'areas', 'significant topography', 'the top of the oceanic crust', 'the top', 'the oceanic crust', 'propagation', 'an up-dip direction', 'the seafloor']
    

    但这会产生很多噪音,所以假设没有一个单词是一个短语:

    >>> np_mwe
    ['Tsunami earthquakes', 'the presence of a thin layer of subducted sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly reaching the seafloor', 'the presence', 'a thin layer of subducted sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly reaching the seafloor', 'a thin layer', 'sedimentary rock along the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly', 'sedimentary rock', 'the uppermost part of the plate interface , as is thought to be present in areas of significant topography at the top of the oceanic crust , and where propagation was in an up-dip direction , possibly', 'the uppermost part of the plate interface', 'the uppermost part', 'the plate interface', 'areas of significant topography', 'significant topography', 'the top of the oceanic crust', 'the top', 'the oceanic crust', 'an up-dip direction', 'the seafloor']
    

    还是很吵,假设名词短语不应该包含逗号(不一定是真的但有用的技巧):

    >>> np_mwe_nocomma = [j for j in [" ".join(i.leaves()) for i in parsed_tree.subtrees() if i.label() == 'NP'] if j.count(' ') > 0 and j.count(',') == 0]
    >>> np_mwe_nocomma
    ['Tsunami earthquakes', 'the presence', 'a thin layer', 'sedimentary rock', 'the uppermost part of the plate interface', 'the uppermost part', 'the plate interface', 'areas of significant topography', 'significant topography', 'the top of the oceanic crust', 'the top', 'the oceanic crust', 'an up-dip direction', 'the seafloor']
    

    现在我们很容易看到子树中的子树,所以我们选择取更大的子树:

    >> x = []
    >>> for i in sorted(np_mwe_nocomma, key=len, reverse=True):
    ...     for j in x:
    ...             if i in j:
    ...                     continue
    ...     print i
    ...     x.append(i)
    ... 
    the uppermost part of the plate interface
    areas of significant topography
    the top of the oceanic crust
    significant topography
    Tsunami earthquakes
    the plate interface
    an up-dip direction
    the uppermost part
    the oceanic crust
    sedimentary rock
    the presence
    a thin layer
    the seafloor
    

    我不确定这是否能满足您的需求,但您对“实体”的定义需要更具体,否则解析器标记的几乎所有 NP 都可以是“实体”

    【讨论】:

    • 谢谢,您的回答真的很有帮助,也很鼓舞人心。
    猜你喜欢
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 1970-01-01
    • 2012-09-24
    相关资源
    最近更新 更多