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

时间:2015-11-26 13:04:41

标签: python tree nltk

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

grant execute on sys.DBMS_LOB to <your_schema_name>

追踪树是那些通向形状叶子的树:*。*。 我现在想要删除所有作为跟踪树的子树。因此,对于此示例,结果应如下所示:

(VP (VBZ says) (SBAR (-NONE- *0*) (S-3 (-NONE- *T*))))

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

(VP (VBZ says))

但我不知道如何向上导航树,直到存在一个没有跟踪树的兄弟并从原始树中删除跟踪树。 我完全被困在这里,因为我才开始使用nltk ......

编辑:

以下是我希望能够处理的完整句子:

<(>(SINV(S-3(S(NP-SBJ-1(-NONE- * PRO *))(VP(VBG假设)(NP(DT))(NN post))(PP-TMP(IN) at)(NP(NP(DT)(NN年龄))(PP(IN)(NP(CD 35)))))))),(),(NP-SBJ-1(PRP he))(VP (VBD管理)(PP-MNR(IN by)(NP(NN一致)))(,,)(SBAR-ADV(IN as)(S(NP-SBJ(-NONE- * PRO *))(VP( VBZ是)(NP-PRD(DT)(NN规则))(PP-LOC(IN in)(NP(NNS大学))))))))(,,)(VP(VBZ说))(SBAR( -NONE- * 0 *)(S-3(-NONE- * T *))))(NP-SBJ(NP(NNP Warren)(NNP H。)(NNP Strother))(,,)(NP(NP) (DT a)(NN大学)(NN官方))(SBAR(WHNP-2(WP))(S(NP-SBJ-2(-NONE- * T *))(VP(VBZ))(VP( VBG研究)(NP(NP(DT a)(NN书))(PP(IN on)(NP(NNP先生)(NNP Hahn))))))))))(。))))

2 个答案:

答案 0 :(得分:1)

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

要识别应删除的内容,请注意nltk树是一种列表;所以要查看一个节点有多少个子节点,只需取其PARlrc photolrc 50 -0.04 100 1.130000 150 0.580000 200 0.850000 250 1.370000 300 1.370000 350 1.230000 400 2.040000 450 1.670000 500 1.790000 550 1.820000 600 1.768494 650 2.083641 700 1.998950 750 2.399018 800 2.289517 850 2.223104 900 2.329006 950 2.700987 1000 2.694792 1050 2.684530 1100 2.594925 1150 2.662429 1200 2.590890 1250 3.043056 1300 3.795076 1350 4.003595 1400 4.401325 1450 4.786757 1500 4.338971 1550 4.701821 1600 4.431703 1650 4.392877 1700 4.642945 1750 4.429018 1800 3.638166 1850 2.879107 。当你找到一个跟踪叶子时,只要父母只有一个孩子,就向上移动树;然后删除子树。这应该涵盖所有内容,因为如果一个节点支配两个跟踪树而没有别的,它将在你删除第一个后只包含一个: - )

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

len()

答案 1 :(得分:0)

这是第二个解决方案,使用Tree.leaf_treeposition()将叶子索引映射到树路径(基于this answer的叶子扫描,由@ b3000建议)。再次向后扫描树以允许就地编辑。随便挑选。

查找父级使用&#34;树位置&#34;是一个要遵循的分支的元组;所以,如果postn是&#34;位置&#34;节点npostn[:-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]