In primo luogo, cercare di utilizzare (i) spazi dei nomi e (ii) i nomi delle variabili inequivocabili, ad esempio:
>>> 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)]
Se guardiamo la grammatica:
>>> 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'".
Per risolvere la parola sconosciuta problemi, ci sono diverse opzioni:
Utilizzare i nodi non-terminali wildcard
per sostituire le parole sconosciute. Trovare un modo per sostituire le parole che la grammatica non coprire dal check_coverage()
con l'wildcard
, quindi analizzare la frase con il carattere jolly
- questo di solito diminuisce la precisione del parser meno che non abbia espressamente allenare il PCFG con una grammatica che gestisce le parole sconosciute e il carattere jolly è un superset delle parole sconosciute.
Torna al file produzione grammaticale che si ha prima di creare l'apprendimento della PCFG con learn_pcfg.py
e aggiungere tutte le parole possibili nelle produzioni terminali.
Aggiungere le parole sconosciute nella tua grammatica PCFG e poi rinormalizzare i pesi, data o molto piccoli pesi alle parole sconosciute (si può provare anche più intelligenti tecniche di levigatura/interpolazione)
Dal momento che questo è una domanda sui compiti a casa. Non darò la risposta con il codice completo. Ma i suggerimenti sopra dovrebbero essere sufficienti per risolvere il problema.
Non c'è modo di attenuare le probabilità? – L3viathan