我正在尝试编写一个程序,它将接受两个句子并检查它们是否相似。我不想使用成熟的解析器,而是使用我认为最常遇到的简单语法创建了一个解析器。现在,我的兴趣在于句子中的名词短语。检查标记为名词短语的子树是否相等很容易。我想对此添加更多内容,让用户决定是否接受缺失/不匹配的确定符(部分匹配)。
输出树的形式是(S(NP The/DT bag/NN) is/VBZ(JP blue/JJ)),这里我定义了语法名词短语(NP)和形容词短语(JP)
为了进行匹配,我考虑了一些路线:
- 删除相关树中的确定节点,然后进行比较
- 将所有确定节点的值更改为一个公共(public)值,比如 X
- 列出除标记为“DT”的所有叶节点
我是 python 的新手,在这里遇到了一些问题:
如果我编写一个递归函数来遍历名词短语树,直到到达带有限定词的叶子,我无法修改原始树中的值,因为它只是传递值。
我发现的关于 nltk 树的唯一删除函数是需要删除节点相对于树根的确切索引,格式如 [0,0] 如果它是根节点最左边 child 的最左边 child 。这很难获得,因为对于每个节点,它很可能涉及一个随着树的高度增长的整数列表
我创建了一个列表列表,其中每个列表都包含一个名词短语的所有叶子,不包括限定词,并比较了这些。
所以,我的问题是,
如何从 NLTK 树中删除一个节点,而不先获取它的 [0,0,1,0,...] 形式的索引?
如何在不使用索引的情况下再次修改叶值?(我想使用递归函数,每当函数遇到我想修改的叶时,我都想修改它)
如果这些都不可能,我怎样才能获得叶子的索引?我对此感到困惑。 Nltk 树有一个 treeposition 函数,但这只适用于子树。与其他节点相比,Python 是否认为叶子是不同的类型?因为 treeposition 不适用于我的叶子。这可能是因为我的叶子是元组而不仅仅是字符串,但我不知道如何更改它,因为这是 pos 标记器的输出。那么有没有什么方法可以替换我的叶子,它是 [the/DT] 形式的元组和 (DT the) 形式的子树?再次定义递归过程不会修改原始树。
有什么建议/意见吗?
最佳答案
好的,让我们一一解答您的问题。
tree = Tree.parse("(S (NP The/DT bag/NN) is/VBZ (JP blue/JJ))")
删除一个节点:
tree.remove(Tree('JP', ['blue/JJ']))
tree.remove('is/VBZ')
修改一个值。您可以通过获取树成员的索引来做到这一点(记住,它继承了列表):
tree.index('is/VBZ')
但同样,这不是一个好方法。
遍历叶子的最佳方法是使用 tree.leaves()
获取叶子,然后使用 tree.leaf_treeposition(index)
获取索引,并使用它们就地修改/删除叶子。
关于python - 比较两个相似的、不相同的 NLTK 树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19402971/