使用带标记的句子在NLTK中创建解析树

时间:2016-11-28 19:15:53

标签: python-3.x nltk parse-tree

使用the NLTK book中定义的方法,我想创建一个已经被POS标记的句子的解析树。根据我从上面链接的章节中理解的内容,您希望能够识别的任何单词都需要在语法中。这看起来很荒谬,因为有一个内置的POS标签,可以手工编写每个单词的词性完全冗余。我是否遗漏了允许这种解析方法的一些功能?

2 个答案:

答案 0 :(得分:3)

使用stanford解析器,不需要POS标记来获取树的解析,因为它已内置到模型中。 StanfordParser和模型无法开箱即用,需要下载。

大多数人在尝试使用NLTK中的StanfordParser

时都会看到此错误
>>> from nltk.parse import stanford
>>> sp = stanford.StanfordParser()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/anaconda3/lib/python3.5/site-packages/nltk/parse/stanford.py", line 51, in __init__
    key=lambda model_name: re.match(self._JAR, model_name)
  File "/home/user/anaconda3/lib/python3.5/site-packages/nltk/internals.py", line 714, in find_jar_iter
    raise LookupError('\n\n%s\n%s\n%s' % (div, msg, div))
LookupError: 

===========================================================================
  NLTK was unable to find stanford-parser\.jar! Set the CLASSPATH
  environment variable.

  For more information, on stanford-parser\.jar, see:
    <http://nlp.stanford.edu/software/lex-parser.shtml>
===========================================================================

要解决此问题,请将Stanford Parser下载到目录并解压缩内容。让我们在* nix系统/usr/local/lib/stanfordparser上使用示例目录。文件stanford-parser.jar必须与其他文件一起位于那里。

当所有文件都存在时,设置解析器和模型位置的环境变量。

>>> import os
>>> os.environ['STANFORD_PARSER'] = '/usr/local/lib/stanfordparser'
>>> os.environ['STANFORD_MODELS'] = '/usr/local/lib/stanfordparser'

现在,您可以使用解析器导出您所拥有的句子的可能解析,例如:

>>> sp = stanford.StanfordParser()
>>> sp.parse("this is a sentence".split())
<list_iterator object at 0x7f53b93a2dd8>
>>> trees = [tree for tree in sp.parse("this is a sentence".split())]
>>> trees[0] # example parsed sentence
Tree('ROOT', [Tree('S', [Tree('NP', [Tree('DT', ['this'])]), Tree('VP', [Tree('VBZ', ['is']), Tree('NP', [Tree('DT', ['a']), Tree('NN', ['sentence'])])])])])

返回iterator对象,因为给定句子可以有多个解析器。

答案 1 :(得分:1)

这是涉及两种不同的技术。您链接的章节是关于手写的无上下文语法,它通常有几十个规则,可以处理一小部分英语(或您覆盖的任何其他语言)。虽然可以在大量此类规则(以及其他技术)上创建大覆盖系统,但NLTK中的CFG实现仅用于教学或演示目的 - 换句话说,它是一个玩具。不要考虑将它用于通用解析。

对于解析真实文本,有像Stanford解析器这样的概率解析器(nltk在nltk.parse.stanford中有一个接口)。这些解析器通常在大型树库上进行训练,它们可以处理未知单词,正如您所期望的那样,它们可以将POS标记文本作为输入,或者进行自己的POS标记。

所有这一切都说,如果你有理由这样做,就不必调整NLTK的CFG机器来处理未知单词:在POS标签而不是单词上写下语法(例如,你和#39; d写NP => "DT" "NN",以便POS标签是终端);然后从你的标记句子中提取POS标签,在它们上面构建一个解析树,并将这些单词重新放入。(如果你的CFG包含混合终端和非终端的规则,这就不够了,例如{{1 }}。)