首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从nltk.trees中识别和删除跟踪树?

如何从nltk.trees中识别和删除跟踪树?
EN

Stack Overflow用户
提问于 2015-11-26 13:04:41
回答 2查看 2.1K关注 0票数 1

例如,我得到了一棵小树(显然它只是一个子树):

代码语言:javascript
复制
(VP (VBZ says) (SBAR (-NONE- *0*) (S-3 (-NONE- *T*))))

痕迹树是指那些导致叶子形状的树:*。*。我现在要删除所有的子树,这是一个跟踪树。因此,对于这个示例,结果应该如下所示:

代码语言:javascript
复制
(VP (VBZ says))

到目前为止,我提取了所有的叶子:

代码语言:javascript
复制
from nltk.tree import ParentedTree
import re

traceLeaves = []    

line = "( (VP (VBZ says) (SBAR (-NONE- *0*) (S-3 (-NONE- *T*)))))"
currTree = ParentedTree.fromstring(line, remove_empty_top_bracketing = True)
for leaf in currTree.leaves():
    if re.search('\*', leaf):
        traceLeaves.append(leaf)

但是,我不知道如何在树上导航,直到有一个兄弟姐妹,即没有跟踪树,并从原始树中删除跟踪树。我被困在这里因为我刚开始和nltk一起工作..。

编辑:

以下是我想要处理的完整句子:

(SINV (S-3 (S (NP 1 (-NONE- *PRO*)) (VP (VBG ) (NP (DT ) (NN Post) (PP-TMP ( at) (NP (NP (DT ) (NN年龄) (PP (IN )(NP (CD 35)) (NP-SBJ-1 (PRP he)) (VP (VBD管理) (PP-MNR ( IN ) (NP (NN共识) (,,) (SBAR-ADV (IN as) (S (NNS (-NN*PRO*) (VP (VBZ is) (NP -珠三角(DT ) (NN规则) (PP-LOC (IN )(NP)(NP(NNS)大学)) (VP (VBZ says) (SBAR (-NONE- **) (S-3 (-NONE- *T*) (NP (NNP Warren) (NNP H.)(NNP Strother) (,,) (NP (NP (DT a) (NN大学) (NN官员)) (SBAR (WHNP-2 (WP who)) (S (NP-SBJ-2 (-NP*T*) (VP (VBZ is) ) (VP (VBG研究)) (NP (NP (DT a) (NN Book) (PP (IN on) (NP先生))( (NNP Hahn))()(。))

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-11-29 00:24:32

叶子是有规律的字符串,所以它们对导航树没有帮助。扫描树并寻找高度为2的子树。

要识别应该删除的内容,请注意nltk树是一种列表;因此,要查看节点有多少子节点,只需取其len()即可。找到跟踪叶时,只要父树只有一个子树,就向上移动;然后删除子树。这应该涵盖所有内容,因为如果一个节点主导了两个跟踪树,而没有其他的,那么在删除第一个:-)之后,它将只包含一个跟踪树。)

下面还有一个窍门:删除节点会混淆for-循环,因为分支列表会变短。为了防止物体在删除前移动,我们向后扫描树。

代码语言:javascript
复制
for sub in reversed(list(t.subtrees())):
    if sub.height() == 2 and sub[0].startswith("*"):  # abbreviated test
        parent = sub.parent()
        while parent and len(parent) == 1:
            sub = parent
            parent = sub.parent()
        print(sub, "will be deleted")
        del t[sub.treeposition()]
票数 2
EN

Stack Overflow用户

发布于 2015-11-29 21:31:58

下面是第二种解决方案,使用Tree.leaf_treeposition()将叶索引映射到树路径(@b 3000建议的基于this answer的叶扫描)。再一次,对树进行反向扫描,以便进行就地编辑。选你所选。

查找父节点使用的事实是,“树位置”是要遵循的分支的元组;因此,如果postn是节点n的“位置”,则postn[:-1]n的父节点的位置。这样,甚至不需要ParentedTree

代码语言:javascript
复制
t = nltk.Tree.fromstring("(VP (VBZ says) (SBAR (-NONE- *0*) (S-3 (-NONE- *T*))))")

for ind, leaf in reversed(list(enumerate(t.leaves()))):
    if leaf.startswith("*") and leaf.endswith("*"):
        postn = t.leaf_treeposition(ind)
        parentpos = postn[:-1]
        while parentpos and len(t[parentpos]) == 1:
            postn = parentpos
            parentpos = postn[:-1]
        print(t[postn], "will be deleted")
        del t[postn]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33939486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档