如何在 Python 中获得二进制解析

Han*_*han 4 python nlp nltk

我有来自自然语言推理语料库(SNLImultiNLI)的数据,这些数据以这种形式出现:

'( ( Two ( blond women ) ) ( ( are ( hugging ( one another ) ) ) . ) )'
Run Code Online (Sandbox Code Playgroud)

它们应该是二叉树(有些不是很干净)。

我想把我自己的一些句子解析成这种格式。我怎样才能用 NLTK 或类似的方法做到这一点?

我找到了 StanfordParser,但我一直无法找到如何获得这种解析。

ale*_*xis 5

任何树都可以转换为保留其成分的二叉树。这是一个适用于nltk.Tree输入的简单解决方案:

from nltk import Tree
from functools import reduce

def binarize(tree):
    """
    Recursively turn a tree into a binary tree.
    """
    if isinstance(tree, str):
        return tree
    elif len(tree) == 1:
        return binarize(tree[0])
    else:
        label = tree.label()
        return reduce(lambda x, y: Tree(label, (binarize(x), binarize(y))), tree)
Run Code Online (Sandbox Code Playgroud)

如果您想要普通元组而不是Tree,请将最后一条return语句替换为:

return reduce(lambda x, y: (binarize(x), binarize(y)), tree)
Run Code Online (Sandbox Code Playgroud)

例子:

>>> t = Tree.fromstring('''(ROOT (S (NP (NNP Oracle))
    (VP (VBD had) (VP (VBN fought) (S (VP (TO to)
      (VP (VB keep) (NP (DT the) (NNS forms))
        (PP (IN from) (S (VP (VBG being) (VP (VBN released))))))))))))''')

>>> bt = binarize(t)

>>> print(t)
(ROOT
  (S
    (NP (NNP Oracle))
    (VP
      (VBD had)
      (VP
        (VBN fought)
        (S
          (VP
            (TO to)
            (VP
              (VB keep)
              (NP (DT the) (NNS forms))
              (PP (IN from) (S (VP (VBG being) (VP (VBN released))))))))))))
>>> print(bt)
(S
  Oracle
  (VP
    had
    (VP
      fought
      (VP
        to
        (VP (VP keep (NP the forms)) (PP from (VP being released)))))))
Run Code Online (Sandbox Code Playgroud)

这将确保二进制结构,但不一定是正确的结构。大覆盖解析器会生成非二进制分支,因为某些附件选择非常困难。(想想经典的“我用望远镜看到了女孩”;是物体内部的“带望远镜”的PP,还是VP的一部分?)。所以继续小心。