2015-05-26 10 views
11

Ci sono stati molti MaltParser e/o NLTK domande relative:Parsing più frasi con MaltParser utilizzando NLTK

Ora, c'è una versione più stabile di MaltParser API NLTK: https://github.com/nltk/nltk/pull/944 ma ci sono problemi quando si tratta di analisi più frasi allo stesso tempo.

Parsing una frase alla volta sembra che vada bene:

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

Ma l'analisi di un elenco di frasi non restituisce un oggetto 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'}] 

Perché è che l'utilizzo parse_sents() non lo fanno restituire un iterable di parse_one?

ho potuto però, appena ottenere pigro e fare:

_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()) 

Ma questa non è la soluzione che sto cercando. La mia domanda è come rispondere perché il parse_sent() non restituisce un iterable di parse_one(). e come potrebbe essere risolto nel codice NLTK?


Dopo @NikitaAstrakhantsev risposto, ho provato emette un albero sintattico, ma ora sembra essere confuso e mette entrambe le frasi in una prima di analizzarlo.

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

Dal codice sembra stia facendo qualcosa di strano: https://github.com/nltk/nltk/blob/develop/nltk/parse/api.py#L45

Perché è che la classe astratta parser in NLTK è swooshing due frasi in uno prima di analizzare? Sto chiamando lo parse_sents() in modo errato? In tal caso, qual è il modo corretto per chiamare parse_sents()?

risposta

5

Per come la vedo nei tuoi esempi di codice, non si chiama tree() in questa linea

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

mentre si chiami tree() in tutti i casi con parse_one().

Altrimenti non vedo il motivo per cui potrebbe accadere: parse_one() metodo ParserI non viene sostituito in MaltParser e tutto ciò che fa è semplicemente chiamando parse_sents() di MaltParser, vedere the code.

Upd:The line you're talking about non si chiama, perché parse_sents() è ignorate da MaltParser e si chiama direttamente.

L'unica ipotesi che ho ora è che java lib maltparser non funziona correttamente con il file di input contenente diverse frasi (intendo this block - dove viene eseguito java). Forse il parser malt originale ha cambiato il formato e ora non è '\n\n'. Sfortunatamente, non posso eseguire questo codice da solo, perché maltparser.org non funziona per il secondo giorno. Ho controllato che il file di input ha un formato previsto (le frasi sono separate dalla doppia endline), quindi è molto improbabile che il wrapper python unisca le frasi.

+0

Grazie !! Ora emette l'albero ma è un albero sbagliato, vedi domanda aggiornata. – alvas

+0

Ho aggiornato la mia risposta, ma non con la soluzione - solo osservazioni –

+0

Trovato l'errore !!! Sono così cieco https://github.com/alvations/nltk/blob/patch-1/nltk/parse/malt.py#L56 il 'yield '\ n \ n'' era nel trattino sbagliato !!! gosh ... – alvas