2016-01-30 10 views
12
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 

Wenn ich den obigen Code ausführen, es wird die folgende Ausgabe für den Satz erzeugt, „das Licht aus“ -NLTK ViterbiParser nicht Worte in Parsen, die nicht in der PCFG Regel sind

(S (VP (VB turn) (PRT (RP off)) (NP (DT the) (NNS lights)))) (p=2.53851e-14)

jedoch es stellt sich die folgende Fehler für den Satz „bitte schalten sie das Licht“ -

ValueError: Grammar does not cover some of the input words: u"'please'"

ich ein ViterbiParser bin Gebäude durch eine probabilistische kontextfreie Grammatik zu liefern. Es funktioniert gut beim Parsen von Sätzen mit Wörtern, die bereits in den Regeln der Grammatik enthalten sind. Es kann keine Sätze analysieren, in denen der Parser das Wort in den Grammatikregeln nicht gesehen hat. Wie umgehen Sie diese Einschränkung?
Ich beziehe mich auf diese assignment.

+0

Gibt es keine Möglichkeit, Ihre Wahrscheinlichkeiten zu glätten? – L3viathan

Antwort

7

versuchen Erstens zu verwenden (i) Namensräume und (ii) eindeutige Variablennamen, zB:

>>> 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)] 

Wenn wir die Grammatik aussehen:

>>> 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'". 

Um das unbekannte Wort zu beheben Probleme, da sind mehrere Optionen:

  • Verwenden Sie wildcard Nicht-Terminals, um die unbekannten Wörter zu ersetzen. Einen Weg finden, um die Worte zu ersetzen, die die Grammatik nicht decken von check_coverage() mit den wildcard, analysieren dann den Satz mit der Wildcard

    • dies wird in der Regel der Genauigkeit des Parsers verringern, wenn Sie speziell die PCFG mit einer Grammatik trainieren das behandelt unbekannte Wörter und die Wildcard ist eine Obermenge der unbekannten Wörter.
  • auf Ihre Grammatik Produktionsdatei, die Sie haben Gehen Sie zurück, bevor das Erlernen der PCFG mit learn_pcfg.py und hinzufügen alle möglichen Wörter in den Terminal-Produktionen zu schaffen.

  • Fügen Sie die unbekannten Wörter in Ihre PCFG Grammatik und renormieren dann die Gewichte, da entweder sehr kleine Gewichte an die unbekannten Wörter (auch smarter Glättung/Interpolationsverfahren versuchen kann)

Da diese ist eine Hausaufgabenfrage, die ich mit dem vollen Code nicht beantworten werde. Aber die obigen Hinweise sollten ausreichen, um das Problem zu lösen.

+0

Der passende Kanal zum Stellen einer Frage wäre entweder direkt in Stackoverflow oder in der https://groups.google.com/forum/?hl=de#!forum/nltk-users-Liste. – alvas