例如,我得到了一棵小树(显然它只是一个子树):
(VP (VBZ says) (SBAR (-NONE- *0*) (S-3 (-NONE- *T*))))痕迹树是指那些导致叶子形状的树:*。*。我现在要删除所有的子树,这是一个跟踪树。因此,对于这个示例,结果应该如下所示:
(VP (VBZ says))到目前为止,我提取了所有的叶子:
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))()(。))
发布于 2015-11-29 00:24:32
叶子是有规律的字符串,所以它们对导航树没有帮助。扫描树并寻找高度为2的子树。
要识别应该删除的内容,请注意nltk树是一种列表;因此,要查看节点有多少子节点,只需取其len()即可。找到跟踪叶时,只要父树只有一个子树,就向上移动;然后删除子树。这应该涵盖所有内容,因为如果一个节点主导了两个跟踪树,而没有其他的,那么在删除第一个:-)之后,它将只包含一个跟踪树。)
下面还有一个窍门:删除节点会混淆for-循环,因为分支列表会变短。为了防止物体在删除前移动,我们向后扫描树。
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()]发布于 2015-11-29 21:31:58
下面是第二种解决方案,使用Tree.leaf_treeposition()将叶索引映射到树路径(@b 3000建议的基于this answer的叶扫描)。再一次,对树进行反向扫描,以便进行就地编辑。选你所选。
查找父节点使用的事实是,“树位置”是要遵循的分支的元组;因此,如果postn是节点n的“位置”,则postn[:-1]是n的父节点的位置。这样,甚至不需要ParentedTree。
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]https://stackoverflow.com/questions/33939486
复制相似问题