2015-05-26 24 views
11

Było wiele MaltParser i/lub NLTK pytania związane z:Parsing kilka zdań z MaltParser użyciu NLTK

Teraz istnieje bardziej ustabilizowane wersja MaltParser API w NLTK: https://github.com/nltk/nltk/pull/944 ale istnieją problemy, jeśli chodzi o analizowanie wielu zdań w tym samym czasie.

Przetwarzanie jedno zdanie w danym momencie wydaje się w porządku:

_path_to_maltparser = '/home/alvas/maltparser-1.8/dist/maltparser-1.8/' 
_path_to_model= '/home/alvas/engmalt.linear-1.7.mco'  
>>> mp = MaltParser(path_to_maltparser=_path_to_maltparser, model=_path_to_model) 
>>> sent = 'I shot an elephant in my pajamas'.split() 
>>> sent2 = 'Time flies like banana'.split() 
>>> print(mp.parse_one(sent).tree()) 
(pajamas (shot I) an elephant in my) 

Ale parsowania listę zdań nie zwraca obiekt DependencyGraph:

_path_to_maltparser = '/home/alvas/maltparser-1.8/dist/maltparser-1.8/' 
_path_to_model= '/home/alvas/engmalt.linear-1.7.mco'  
>>> mp = MaltParser(path_to_maltparser=_path_to_maltparser, model=_path_to_model) 
>>> sent = 'I shot an elephant in my pajamas'.split() 
>>> sent2 = 'Time flies like banana'.split() 
>>> print(mp.parse_one(sent).tree()) 
(pajamas (shot I) an elephant in my) 
>>> print(next(mp.parse_sents([sent,sent2]))) 
<listiterator object at 0x7f0a2e4d3d90> 
>>> print(next(next(mp.parse_sents([sent,sent2])))) 
[{u'address': 0, 
    u'ctag': u'TOP', 
    u'deps': [2], 
    u'feats': None, 
    u'lemma': None, 
    u'rel': u'TOP', 
    u'tag': u'TOP', 
    u'word': None}, 
{u'address': 1, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 2, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'I'}, 
{u'address': 2, 
    u'ctag': u'NN', 
    u'deps': [1, 11], 
    u'feats': u'_', 
    u'head': 0, 
    u'lemma': u'_', 
    u'rel': u'null', 
    u'tag': u'NN', 
    u'word': u'shot'}, 
{u'address': 3, 
    u'ctag': u'AT', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'AT', 
    u'word': u'an'}, 
{u'address': 4, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'elephant'}, 
{u'address': 5, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'in'}, 
{u'address': 6, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'my'}, 
{u'address': 7, 
    u'ctag': u'NNS', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NNS', 
    u'word': u'pajamas'}, 
{u'address': 8, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'Time'}, 
{u'address': 9, 
    u'ctag': u'NNS', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NNS', 
    u'word': u'flies'}, 
{u'address': 10, 
    u'ctag': u'NN', 
    u'deps': [], 
    u'feats': u'_', 
    u'head': 11, 
    u'lemma': u'_', 
    u'rel': u'nn', 
    u'tag': u'NN', 
    u'word': u'like'}, 
{u'address': 11, 
    u'ctag': u'NN', 
    u'deps': [3, 4, 5, 6, 7, 8, 9, 10], 
    u'feats': u'_', 
    u'head': 2, 
    u'lemma': u'_', 
    u'rel': u'dep', 
    u'tag': u'NN', 
    u'word': u'banana'}] 

Dlaczego jest to, że nie stosując parse_sents() zwrócić wartość iterable z parse_one?

mogę jednak po prostu leniwy i zrobić:

_path_to_maltparser = '/home/alvas/maltparser-1.8/dist/maltparser-1.8/' 
_path_to_model= '/home/alvas/engmalt.linear-1.7.mco'  
>>> mp = MaltParser(path_to_maltparser=_path_to_maltparser, model=_path_to_model) 
>>> sent1 = 'I shot an elephant in my pajamas'.split() 
>>> sent2 = 'Time flies like banana'.split() 
>>> sentences = [sent1, sent2] 
>>> for sent in sentences: 
>>> ... print(mp.parse_one(sent).tree()) 

Ale to nie jest rozwiązanie szukam. Moje pytanie brzmi: jak odpowiedzieć na pytanie, dlaczego parse_sent() nie zwróci numeru należącego do parse_one(). i jak można to naprawić w kodzie NLTK?


Po @NikitaAstrakhantsev odpowiedział Próbowałem wyprowadza drzewo składniowy teraz, ale wydaje się mylić i umieszcza oba zdania w jedno przed analizowania go.

# Initialize a MaltParser object with a pre-trained model. 
mp = MaltParser(path_to_maltparser=path_to_maltparser, model=path_to_model) 
sent = 'I shot an elephant in my pajamas'.split() 
sent2 = 'Time flies like banana'.split() 
# Parse a single sentence. 
print(mp.parse_one(sent).tree()) 
print(next(next(mp.parse_sents([sent,sent2]))).tree()) 

[out]:

(pajamas (shot I) an elephant in my) 
(shot I (banana an elephant in my pajamas Time flies like)) 

z kodu wydaje się robić coś dziwnego: https://github.com/nltk/nltk/blob/develop/nltk/parse/api.py#L45

Dlaczego jest to, że parser klasa abstrakcyjna w NLTK jest potrząsanie dwa zdania do jeden przed analizą? Czy nieprawidłowo dzwonię pod numer parse_sents()? Jeśli tak, jaki jest prawidłowy sposób wywołania parse_sents()?

Odpowiedz

5

Jak widzę w twoich próbki kodu, nie zadzwonić tree() w tej linii

>>> print(next(next(mp.parse_sents([sent,sent2])))) 

podczas mów tree() we wszystkich przypadkach z parse_one().

przeciwnym razie nie widzę, dlaczego to może się zdarzyć: parse_one() metoda ParserI nie jest uwzględniana w MaltParser a wszystko to robi jest po prostu wywołanie parse_sents() o MaltParser patrz the code.

Upd:The line you're talking about nie nazywa, bo parse_sents() jest przesłonięta w MaltParser i jest bezpośrednio nazywa.

Jedyne, co mam teraz, to że java lib maltparser nie działa poprawnie z plikiem wejściowym zawierającym kilka zdań (mam na myśli this block - gdzie uruchamiany jest java). Być może oryginalny analizator słodu zmienił format i teraz nie jest to '\n\n'. Niestety, nie mogę uruchomić tego kodu samodzielnie, ponieważ maltparser.org jest wyłączony na drugi dzień. Sprawdziłem, czy plik wejściowy ma oczekiwany format (zdania są oddzielone podwójną linią końcową), więc jest bardzo mało prawdopodobne, że opakowanie Pythona scala zdania.

+0

Dziękuję! Teraz wyprowadza drzewo, ale jest to niewłaściwe drzewo, zobacz zaktualizowane pytanie. – alvas

+0

Zaktualizowałem moją odpowiedź, ale nie z rozwiązaniem - tylko uwagi –

+0

Znalazłem błąd !!! Jestem sooo ślepy https://github.com/alvations/nltk/blob/patch-1/nltk/parse/malt.py#L56 "yield" \ n \ n'' był w niewłaściwym wcięciu !!! gosh ... – alvas