11
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 the) (NNS点灯)))) (p=2.53851e-14)

ただし、「ライトを消してください」という文に対して次のエラーが発生します-

ValueError: 文法が入力単語の一部をカバーしていません: u"'please'"

確率的文脈自由文法を提供することで ViterbiParser を構築しています。これは、すでに文法規則に含まれている単語を含む文を解析する際にうまく機能します。パーサーが文法規則で単語を認識していない文の解析に失敗します。この制限を回避するにはどうすればよいですか?
私はこの課題に言及しています。

4

1 に答える 1

6

まず、(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非終端ノードを使用して、未知の単語を置き換えます。check_coverage()文法でカバーされていない単語を に置き換える方法を見つけてからwildcard、ワイルドカードを使用して文を解析します

    • 不明な単語を処理する文法で PCFG を特別にトレーニングしておらず、ワイルドカードが不明な単語のスーパーセットである場合を除き、これは通常、パーサーの精度を低下させます。
  • PCFG の学習を作成する前に持っている文法生成ファイルに戻り、可能なすべての単語を端末生成に追加しlearn_pcfg.pyます。

  • 不明な単語を pcfg 文法に追加し、重みを再正規化して、不明な単語に非常に小さな重みを与えます (よりスマートな平滑化/補間手法を試すこともできます)。

これは宿題の質問なので、完全なコードで答えることはしません。しかし、上記のヒントは問題を解決するのに十分なはずです.

于 2016-01-30T21:20:14.320 に答える