我正在尝试编写一个程序,它将接受两个句子并检查它们是否相似。我不想使用一个成熟的解析器,并使用我认为我最常遇到的简单语法创建一个。现在,我的兴趣在于句子中的名词短语。检查标记为名词短语的子树的相等性是很容易的。我想为此添加更多内容,并让用户决定是否接受缺失/不匹配的确定器(部分匹配)。
输出树的形式(S(NP / DT bag / NN)是/ VBZ(JP blue / JJ)),其中我定义了语法名词短语(NP)和形容词短语(JP)< / p>
为了进行匹配,我考虑过几条路线:
我是python的新手,我在这里面临一些问题:
如果我写一个递归函数来遍历名词短语树,直到它到达带有限定词的叶子,我无法修改原始树中的值,因为它只传递了值。
我找到的关于nltk树的唯一删除函数是一个需要相对于树的根删除节点的确切索引的函数,格式如[0,0] if它是根节点最左边的子节点的最左边的子节点。这很难获得,因为它很可能涉及一个随着树的高度而增长的整数列表,每个节点
我创建了一个列表列表,其中每个列表都包含一个名词短语中除了确定者之外的所有叶子,并进行了比较。
所以,我的问题是,
如何在不首先获取[0,0,1,0,...]形式的索引的情况下从NLTK树中删除节点?
如何在不使用索引的情况下修改叶值?(我想使用递归函数,每当函数命中我要修改的叶子时,我想修改它)
如果这些不可能,我怎样才能获得叶子的索引?我很难过。 Nltk树具有树位功能,但这仅适用于子树。与其他节点相比,Python是否认为叶子是不同的类型?因为树位不适合我的叶子。这可能是因为我的叶子是元组而不仅仅是字符串,但我不知道如何改变它,因为这是pos标记器的输出。那么是否有某种方式替换我的叶子,这是形式[/ DT]的形式元组与形式的子树(DT)?再次定义递归过程不会修改原始树。
有任何建议/意见吗?
答案 0 :(得分:3)
好的,让我们一个一个地解决你的问题。
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成员的索引来实现这一点(记住,它继承了列表):
tree.index('is/VBZ')
但同样,这不是一个好方法。
遍历树叶的最佳方法是使用tree.leaves()
获取树叶,然后按tree.leaf_treeposition(index)
获取索引,并使用这些来就地修改/删除树。强>