2014-12-21 12 views
6

Sto cercando di ottenere la somiglianza tra una singola parola e ogni parola in una frase utilizzando NLTK.NLTK converti la frase con token per sincronizzare il formato

NLTK può ottenere la somiglianza tra due parole specifiche come mostrato di seguito. Questo metodo richiede che venga fornito un riferimento specifico alla parola, in questo caso è 'dog.n.01' dove dog è un nome e vogliamo utilizzare la prima definizione (01) NLTK.

dog = wordnet.synset('dog.n.01') 
cat = wordnet.synset('cat.n.01') 
print dog.path_similarity(cat) 
>> 0.2 

Il problema è che ho bisogno di ottenere la parte di informazioni vocali da ogni parola nella frase. Il pacchetto NLTK ha la capacità di ottenere le parti del discorso per ogni parola in una frase come mostrato di seguito. Tuttavia, queste parti vocali ('NN', 'VB', 'PRP' ...) non corrispondono al formato che il synset assume come parametro.

text = word_tokenize("They refuse to permit us to obtain the refuse permit") 
pos_tag(text) 
>> [('They', 'PRP'), ('refuse', 'VBP'), ('to', 'TO'), ('permit', 'VB'), ('us', 'PRP'), ('to', 'TO'), ('obtain', 'VB'), ('the', 'DT'), ('refuse', 'NN'), ('permit', 'NN')] 

IS è possibile per ottenere lo synset dati formattati da pos_tag() si traduce in NLTK? Con synset formattato intendo il formato come dog.n.01

risposta

9

è possibile utilizzare una semplice funzione di conversione:

from nltk.corpus import wordnet as wn 

def penn_to_wn(tag): 
    if tag.startswith('J'): 
     return wn.ADJ 
    elif tag.startswith('N'): 
     return wn.NOUN 
    elif tag.startswith('R'): 
     return wn.ADV 
    elif tag.startswith('V'): 
     return wn.VERB 
    return None 

Dopo codifica una frase si può legare una parola all'interno della frase con uno synset di utilizzare questa funzione. Ecco un esempio:

from nltk.stem import WordNetLemmatizer 
from nltk import pos_tag, word_tokenize 

sentence = "I am going to buy some gifts" 
tagged = pos_tag(word_tokenize(sentence)) 

synsets = [] 
lemmatzr = WordNetLemmatizer() 

for token in tagged: 
    wn_tag = penn_to_wn(token[1]) 
    if not wn_tag: 
     continue 

    lemma = lemmatzr.lemmatize(token[0], pos=wn_tag) 
    synsets.append(wn.synsets(lemma, pos=wn_tag)[0]) 

print synsets 

Risultato: [synset ('be.v.01'), synset ('travel.v.01'), synset ('buy.v.01'), synset ('gift.n.01')]

+0

Ho trovato questo esempio di 'lesk', ma il tuo codice sembra dare risultati migliori, mi chiedo perché questo sia (solo curioso): http://www.nltk.org/ howto/wsd.html –

+1

Lesk non funziona molto bene. L'unica ragione per cui questo codice potrebbe funzionare meglio è perché ottiene la prima sincronizzazione. In wordnet i synset sono ordinati per frequenza. In altre parole, il primo synset è il più probabile se non teniamo conto del contesto. – bogs

1

È possibile utilizzare la forma alternativa di wordnet.synset:

wordnet.synset('dog', pos=wordnet.NOUN) 

Avrai ancora bisogno di tradurre i tag offerti da pos_tag in quelli supportati da wordnet.sysnset - sfortunatamente, non conosco un dizionario pre-costruito che lo faccia, quindi (a meno che mi manchi l'esistenza di una tabella di corrispondenza di questo tipo) dovrai costruirne uno tuo (puoi farlo una volta e metterlo da parte per il successivo ricarico).

Vedi http://www.nltk.org/book/ch05.html, sottocapitolo 1, su come ottenere aiuto su un insieme di tag specifica - ad esempio nltk.help.upenn_tagset('N.*') confermerà che l'insieme di tag UPenn (che credo sia quello di default usata da pos_tag) usa 'N' seguita da qualcosa per identificare le varianti di cosa synset vedranno come wordnet.NOUN.

Non ho provato http://www.nltk.org/_modules/nltk/tag/mapping.html ma è potrebbe essere essere proprio quello che richiede - provarlo!

Problemi correlati