Python 如何使用nltk去除ptb解析树中的-NONE-和*T*-i?

Python 如何使用nltk去除ptb解析树中的-NONE-和*T*-i?,python,nltk,parse-tree,Python,Nltk,Parse Tree,我处理penn tree bank v2树,经常遇到“服务”子树,如这些(以及其他几种类型) 我可以手动添加许多规则来进一步细化我实际使用的节点(使用标记和令牌进行解析,而不使用“哦,看那里”链接或“这里一定有一个节点”——就像斯坦福解析器返回的那些规则一样),但我通常会留下一些服务节点或巨大的间隙和“裁剪的分支”(比如,如果删除上面的-NONE-节点,那么SBAR将完全没有子节点,这很奇怪) 我想知道是否可以从nltk.corpus import ptb;ptb.parsed_sents()

我处理penn tree bank v2树,经常遇到“服务”子树,如这些(以及其他几种类型)

我可以手动添加许多规则来进一步细化我实际使用的节点(使用标记和令牌进行解析,而不使用“哦,看那里”链接或“这里一定有一个节点”——就像斯坦福解析器返回的那些规则一样),但我通常会留下一些服务节点或巨大的间隙和“裁剪的分支”(比如,如果删除上面的
-NONE-
节点,那么
SBAR将完全没有子节点,这很奇怪)


我想知道是否可以从nltk.corpus import ptb;ptb.parsed_sents()的
输出中删除除实际解析(单词、标记、标点符号)之外的所有内容
one and for all?

删除任何只支配跟踪的子树。在下面,我迭代了子树,但实际检查了它们的子树;这使得通过修改包含空子树的节点来删除空子树变得很容易

for sub in some_tree.subtrees():
    for n, child in enumerate(sub):
        if isinstance(child, str):
            continue
        if all(leaf.startswith("*") for leaf in child.leaves()):
            del sub[n]  # Delete this child
我使用了
leaf.startswith(“*”)
作为检测跟踪的简单标准。必要时用您自己的替换它

编辑:由于要删除所有仅包含标记为
-NONE-
的子树的节点,并且每个子树只控制一个叶,请使用以下测试:

    if len(list(child.subtrees(filter=lambda x:x.label()=='-NONE-')))==len(child.leaves()):
        del sub[n]

多亏了下面的
@alexsis
答案,现在我知道这些东西叫做traces和co-indexes
在包中。

关于
-NONE-
的事情呢?问题是,我不知道这些服务节点的所有种类;我只给出了一个具体的例子,如果您的删除标准是删除每个
-NONE-
节点以及因此变为空的每个更高的节点,那么您应该修改标准a相应地,如果这个标记总是出现在高度为1的情况下,那就很容易了:删除所有支配
-NONE-
节点的子树,就像它的叶子一样多。非常感谢你提供了一个具体的答案,@alexis!这非常有用,不过,我提到的问题没有什么不同;我想知道除了解析它之外,我是否可以去掉所有的东西如果,事先不知道“其他一切”是什么:)因为事实证明有一堆这样的跟踪和联合索引,如果你删除了一些,其他的会保留下来。不过,这是一个非常有用的开头片段!我不确定你的反对意见是什么:从
树库
语料库中可以看出,所有跟踪都由
-NONE-
节点控制,因此新标准应该删除所有只包含跟踪的子树。无论如何,如果您发现的函数符合您的要求,请务必使用它。不过,它所做的与简单地删除只跟踪的子树完全不同。事实上,您的答案本身就包含了值得注意的伟大技巧:查看所有子树的叶子。