【问题标题】:Creating a full nltk parse tree from a list of nltk subtrees in python 3.5从 python 3.5 中的 nltk 子树列表创建完整的 nltk 解析树
【发布时间】:2023-03-09 03:14:01
【问题描述】:

我有从解析历史中派生的子树列表,格式如下:

解析历史:

parse = [('S', 0), ('NP', 1), ('Det', 0), ('N', 0), ('VP', 1), ('V', 4), ('NP', 2), ('NP', 0), ('PN', 1), ('NP', 1), ('Det', 0), ('N', 3)]

列表中的每个元组都有一个语法字典的键,其中包含规则列表。元组中的第二项是该给定键的规则索引。

语法是:

grammar = {'S': [['NP', 'VP']],
               'NP': [['PN'], ['Det', 'N']],
               'VP': [['V'], ['V', 'NP', 'NP']],
               'PN': [['John'], ['Mary'], ['Bill']],
               'Det': [['the'], ['a']],
               'N': [['man'], ['woman'], ['drill sergeant'], ['dog']],
               'V': [['slept'], ['cried'], ['assaulted'],
                     ['devoured'], ['showed']]}

子树的列表是:

[Tree('S', ['NP', 'VP']), Tree('NP', ['Det', 'N']), Tree('Det', ['the']), Tree('N', ['man']), Tree('VP', ['V', 'NP', NP]), Tree('V', ['showed']), Tree('NP', ['PN']), Tree('PN', ['Mary']), Tree('NP', ['Det', 'N']), Tree('Det', ['the']), Tree('N', ['dog'])]

我使用以下代码创建了子树列表:

for item in parse:
        apple = Tree(item[0], grammar[item[0]][item[1]])
        trees.append(apple)

打印树时得到的输出(我知道这不是正确的方法,但它至少显示了子树)如下:

(S NP VP)
(NP Det N)
(Det the)
(N man)
(VP V NP)
(V showed)
(NP NP NP)
(NP PN)
(PN Mary)
(NP Det N)
(Det the)
(N dog)

感谢您的帮助!

::编辑::

正确的输出应该是这样的:

(S(NP(Det the)(N man))(VP(V showed)(NP(PN Mary))(NP(Det the)(N dog))))

【问题讨论】:

  • 请显示您尝试生成的树。
  • @alexis 树应该如下所示: (S(NP(Det the)(N man))(VP(V shown)(NP(NP(PN Mary))(NP(Det the )(N 狗)))))
  • 把它放在你的问题中。
  • 非常好。现在您的问题提供了足够的信息以供理解和回答。
  • 下面是你制作树的方法:你的每棵迷你树都有两根弦作为叶子。将它们替换为您在解析历史记录中应用下一条规则时构建的树。处理它,您可能会发现从下到上组装树更容易,这就是@randomsurfer 的回答说您需要递归地进行组装的原因。您可以使用该代码作为起点。但要努力。我不知道这个作业是为了你自己的教育还是为了你自己的教育,但它对你没有任何好处。

标签: python parsing tree nltk subtree


【解决方案1】:

需要递归构建树,但需要区分终端和非终端。顺便提一句。您的解析序列似乎错误。我破解了这个:

def build_tree(parse):
  assert(parse)
  rule_head = parse[0][0]
  rule_body = grammar[rule_head][parse[0][1]]
  tree_body = []
  rest = parse[1:]
  for r in rule_body:
    if non_term(r):
        (subtree,rest) = build_tree(rest)
        tree_body.append(subtree)
    else:
        tree_body.append(r)

  return (tree(rule_head,tree_body), rest)

【讨论】:

  • 这个更好看吗? [('S', 0), ('NP', 1), ('Det', 0), 'scan', ('N', 0), 'scan', ('VP', 1), ( 'V', 4), 'scan', ('NP', 2), ('NP', 0), ('PN', 1), 'scan', ('NP', 1), ('Det ', 0), '扫描', ('N', 3), '扫描']
  • 我的意思是您的初始输入似乎是错误的。尝试递归构建一棵树,你会发现它错在哪里
  • 检测终端很容易:它们不是grammar中的键。
  • @randomsurfer_123 你能解释一下:if non_term(r): 下的部分是如何工作的吗?我不明白子树部分。谢谢
  • @GianpaulRachiele 基本上你需要为非终端构建一个子树,在这个过程中它会消耗你的一堆子树桩。所以递归应该返回你刚刚构建的树,以及输入的剩余部分,这样你就可以在下一个非终端上递归。
猜你喜欢
  • 1970-01-01
  • 2018-07-10
  • 2019-12-09
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 2013-10-04
  • 1970-01-01
  • 2016-08-18
相关资源
最近更新 更多