2016-01-30 8 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 

Kiedy uruchomić powyższy kod, to daje następujący wynik na zdaniu „zgasić światło” -NLTK ViterbiParser zawodzi w parsowania słowa, które nie są w regule PCFG

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

jednak , podnosi się następujący błąd w zdaniu: „Proszę wyłączyć światła” -

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

buduję ViterbiParser dostarczając mu wolną gramatyki probabilistyczny kontekstowe. Działa dobrze w analizie zdań, które mają słowa, które są już w regułach gramatyki. Nie analizuje zdań, w których Parser nie widział tego słowa w regułach gramatycznych. Jak obejść to ograniczenie?
Mam na myśli to assignment.

+0

Czy nie ma sposobu na wygładzenie prawdopodobieństwa? – L3viathan

Odpowiedz

7

Po pierwsze, spróbuj użyć (i) nazw i (ii) jednoznacznych nazw zmiennych, np:

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

Jeśli spojrzymy na gramatykę:

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

Aby rozwiązać nieznane słowo kwestie, nie jesteśmy kilka opcji:

  • Użyj wildcard węzłów innych terminali, aby zastąpić nieznane słowa. Znaleźć jakiś sposób, aby zastąpić słowa, że ​​gramatyka nie pokrywają z check_coverage() z wildcard, następnie analizować zdanie z zamiennika

    • to zazwyczaj zmniejszyć dokładność parser, chyba że zostały specjalnie trenować PCFG z gramatyki który obsługuje nieznane słowa, a symbol wieloznaczny jest nadzbiorem nieznanych słów.
  • Wróć do pliku produkcyjnego gramatyki, że masz przed utworzeniem uczenia się PCFG z learn_pcfg.py i dodać wszystkie możliwe słowa w produkcji terminali.

  • Dodaj nieznanych słów w swojej gramatyki pcfg a następnie renormalize ciężary, biorąc pod uwagę zarówno bardzo małych masach do nieznanych słów (można także spróbować inteligentnych technik wygładzania/interpolacji)

Od tego to pytanie o pracę domową nie udzielę odpowiedzi z pełnym kodem. Ale powyższe wskazówki powinny wystarczyć, aby rozwiązać problem.

+0

Odpowiednim kanałem do zadawania pytań może być również bezpośrednio w Stackoverflow lub na https://groups.google.com/forum/?hl=pl#!forum/nltk-userslist. – alvas

Powiązane problemy