繁体   English   中英

NLTK ViterbiParser无法解析不在PCFG规则中的单词

[英]NLTK ViterbiParser fails in parsing words that are not in the PCFG rule

import nltk
from nltk.parse import ViterbiParser

def pcfg_chartparser(grammarfile):
    f=open(grammarfile)
    grammar=f.read()
    f.close()
    return nltk.PCFG.fromstring(grammar)

grammarp = pcfg_chartparser("wsjp.cfg")

VP = ViterbiParser(grammarp)
print VP
for w in sent:
    for tree in VP.parse(nltk.word_tokenize(w)):
        print tree

当我运行上面的代码时,它为句子产生以下输出,“关灯” -

(S(VP(VB转)(PRT(RP关))(NP(DT)(NNS灯))))(p = 2.53851e-14)

但是,它会引起句子的以下错误,“请关掉灯” -

ValueError:语法不包含一些输入词:u“'please'”

我正在通过提供概率上下文无关语法来构建ViterbiParser。 它适用于解析具有已经在语法规则中的单词的句子。 它无法解析Parser在语法规则中没有看到单词的句子。 如何解决这个限制?
我指的是这个任务

首先,尝试使用(i)名称空间和(ii)明确的变量名称,例如:

>>> from nltk import PCFG
>>> from nltk.parse import ViterbiParser
>>> import urllib.request
>>> response = urllib.request.urlopen('https://raw.githubusercontent.com/salmanahmad/6.863/master/Labs/Assignment5/Code/wsjp.cfg')
>>> wsjp = response.read().decode('utf8')
>>> grammar = PCFG.fromstring(wsjp)
>>> parser = ViterbiParser(grammar)
>>> list(parser.parse('turn off the lights'.split()))
[ProbabilisticTree('S', [ProbabilisticTree('VP', [ProbabilisticTree('VB', ['turn']) (p=0.002082678), ProbabilisticTree('PRT', [ProbabilisticTree('RP', ['off']) (p=0.1089101771)]) (p=0.10768769667270556), ProbabilisticTree('NP', [ProbabilisticTree('DT', ['the']) (p=0.7396712852), ProbabilisticTree('NNS', ['lights']) (p=4.61672e-05)]) (p=4.4236397464693323e-07)]) (p=1.0999324002161311e-13)]) (p=2.5385077255727538e-14)]

如果我们看一下语法:

>>> grammar.check_coverage('please turn off the lights'.split())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.4/dist-packages/nltk/grammar.py", line 631, in check_coverage
    "input words: %r." % missing)
ValueError: Grammar does not cover some of the input words: "'please'".

要解决未知单词问题,有几种选择

  • 使用wildcard非终端节点替换未知单词 找到一些方法用wildcard check_coverage()语法没有覆盖的check_coverage() ,然后使用wildcard解析句子

    • 这通常会降低解析器的准确性,除非您专门训练PCFG使用处理未知单词的语法,并且通配符是未知单词的超集。
  • 在使用learn_pcfg.py创建学习PCFG之前,回到您的语法生成文件,并在终端制作中添加所有可能的单词

  • 将未知单词添加到您的pcfg语法中,然后重新归一化权重 ,给予未知单词非常小的权重(您还可以尝试更智能的平滑/插值技术)

由于这是一个家庭作业问题,我不会用完整的代码给出答案。 但上述提示应足以解决问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM