使用NLTK书中定义的方法,我希望创建一个已被POS标记的句子的解析树。根据我从上面链接的章节中所理解的,任何你想要识别的单词都需要在语法中。这似乎是荒谬的,因为有一个内置的POS标签,会使手写部分的词性为每个词完全多余。我是不是缺少了一些允许这样做的解析方法的功能?
发布于 2016-11-28 13:32:46
这是两种不同的技术。您链接到的章节是关于不带上下文的手写语法,它通常有几十条规则,可以处理一小部分英语(或您所涵盖的任何其他语言)。虽然可以在大量这样的规则(加上其他技术)的基础上创建一个大范围的系统,但NLTK中的CFG实现只是为了教学或演示--换句话说,它是一个玩具。甚至不要考虑将其用于一般用途的解析。
对于解析真实文本,有一些概率解析器,比如斯坦福解析器( nltk在nltk.parse.stanford
中有一个接口)。这类解析器通常在大型树桩上进行培训,它们可以处理未知的单词,正如您所预期的那样,它们要么以POS标记的文本作为输入,要么进行它们自己的POS标记。
尽管如此,如果您有理由这样做,那么就不难调整NLTK的CFG机器来处理未知的单词:在POS标记上而不是在单词上编写语法(例如,您将编写NP => "DT" "NN"
,以便POS标记成为终端);然后从标记语句中提取POS标记,在它们之上构建一个解析树,并将这些单词放回。(如果CFG包含混合终端和非终端的规则,比如"give" NP "to" NP
,这是不够的。)
发布于 2016-11-29 05:13:54
使用斯坦福解析器,无需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>
===========================================================================
要解决这个问题,请将斯坦福分析器下载到一个目录并解压内容。让我们在*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
对象,因为给定句子可以有多个解析器。
https://stackoverflow.com/questions/40851783
复制相似问题