2013-01-23 15 views
21

Vorrei una funzione di libreria Python che converta/converta in diverse parti del discorso. talvolta deve output multipli parole ("coder" e "codice" sono entrambi sostantivi dal verbo "codice", uno è soggetto l'altro è l'oggetto)Convertire le parole tra le forme verbale/sostantivo/aggettivo

# :: String => List of String 
print verbify('writer') # => ['write'] 
print nounize('written') # => ['writer'] 
print adjectivate('write') # => ['written'] 

i prevalentemente interessa verbi < => sostantivi , per un programma di appunti che voglio scrivere. cioè posso scrivere "caffeina antagonizza A1" o "la caffeina è un antagonista A1" e con alcuni NLP può capire che significano la stessa cosa. (So ​​che non è facile, e che prenderà il PNL che analizza e non si limita a taggare, ma voglio creare un prototipo).

domande simili ... Converting adjectives and adverbs to their noun forms (questa risposta steli solo fino al POS radice. Voglio andare tra i POS.)

ps chiamato conversione in linguistica http://en.wikipedia.org/wiki/Conversion_%28linguistics%29

+1

Non so se si può fare questo, ma date un'occhiata al NLTK. http://nltk.org/ –

+0

Come gestirai casi ambigui? Ad esempio, 'diguise' può essere un verbo o un nome, a seconda del contesto. –

+0

ok: 'nounize ('travestimento') == ['travestimento']' e 'verbify ('travestimento') == ['travestimento']' e 'aggettivo ('travestimento') == ['travestito'] ' –

risposta

3

Capisco che questo doesn Non rispondo alla tua intera domanda, ma ne risponde gran parte. Vorrei controllare http://nodebox.net/code/index.php/Linguistics#verb_conjugation Questa libreria python è in grado di coniugare i verbi e riconoscere se una parola è un verbo, un sostantivo o un aggettivo.

ESEMPIO CODICE

print en.verb.present("gave") 
print en.verb.present("gave", person=3, negate=False) 
>>> give 
>>> gives 

Può anche classificare parole.

print en.is_noun("banana") 
>>> True 

Il download è nella parte superiore del collegamento.

+0

sì, l'ho visto qui, ma fa solo cose all'interno (non attraverso) POS http://stackoverflow.com/questions/3753021/using-nltk-and-wordnet-how-do-i-convert-simple-tense -verb-in-suo-presente-passato? RQ = 1 –

3

Un approccio potrebbe essere quello di utilizzare un dizionario di parole con i relativi tag POS e una mappatura di wordform. Se ottieni o crei un tale dizionario (che è del tutto possibile se hai accesso ai dati di qualsiasi dizionario convenzionale, poiché tutti i dizionari elencano i tag POS della parola, così come i moduli di base per tutti i moduli derivati), puoi usare qualcosa come la seguente:

def is_verb(word): 
    if word: 
     tags = pos_tags(word) 
     return 'VB' in tags or 'VBP' in tags or 'VBZ' in tags \ 
       or 'VBD' in tags or 'VBN' in tags: 

def verbify(word): 
    if is_verb(word): 
     return word 
    else: 
     forms = [] 
     for tag in pos_tags(word): 
      base = word_form(word, tag[:2]) 
      if is_verb(base): 
       forms.append(base) 
     return forms 
12

Questo è più un approccio euristico. L'ho appena codificato così appelli per lo stile. Usa il derivationally_related_forms() da wordnet. Ho implementato la denominazione. Suppongo che la verbisa funzioni analoga. Da opere quello che ho provato abbastanza bene:

from nltk.corpus import wordnet as wn 

def nounify(verb_word): 
    """ Transform a verb to the closest noun: die -> death """ 
    verb_synsets = wn.synsets(verb_word, pos="v") 

    # Word not found 
    if not verb_synsets: 
     return [] 

    # Get all verb lemmas of the word 
    verb_lemmas = [l for s in verb_synsets \ 
        for l in s.lemmas if s.name.split('.')[1] == 'v'] 

    # Get related forms 
    derivationally_related_forms = [(l, l.derivationally_related_forms()) \ 
            for l in verb_lemmas] 

    # filter only the nouns 
    related_noun_lemmas = [l for drf in derivationally_related_forms \ 
          for l in drf[1] if l.synset.name.split('.')[1] == 'n'] 

    # Extract the words from the lemmas 
    words = [l.name for l in related_noun_lemmas] 
    len_words = len(words) 

    # Build the result in the form of a list containing tuples (word, probability) 
    result = [(w, float(words.count(w))/len_words) for w in set(words)] 
    result.sort(key=lambda w: -w[1]) 

    # return all the possibilities sorted by probability 
    return result 
2

Ecco una funzione che è in teoria in grado di convertire le parole tra sostantivo/verbo/aggettivo/avverbio forma che ho aggiornato da here (originariamente scritto da bogs, I credi) per essere compatibile con nltk 3.2.5 ora che synset.lemmas e sysnset.name sono funzioni.

from nltk.corpus import wordnet as wn 

# Just to make it a bit more readable 
WN_NOUN = 'n' 
WN_VERB = 'v' 
WN_ADJECTIVE = 'a' 
WN_ADJECTIVE_SATELLITE = 's' 
WN_ADVERB = 'r' 


def convert(word, from_pos, to_pos):  
    """ Transform words given from/to POS tags """ 

    synsets = wn.synsets(word, pos=from_pos) 

    # Word not found 
    if not synsets: 
     return [] 

    # Get all lemmas of the word (consider 'a'and 's' equivalent) 
    lemmas = [] 
    for s in synsets: 
     for l in s.lemmas(): 
      if s.name().split('.')[1] == from_pos or from_pos in (WN_ADJECTIVE, WN_ADJECTIVE_SATELLITE) and s.name().split('.')[1] in (WN_ADJECTIVE, WN_ADJECTIVE_SATELLITE): 
       lemmas += [l] 

    # Get related forms 
    derivationally_related_forms = [(l, l.derivationally_related_forms()) for l in lemmas] 

    # filter only the desired pos (consider 'a' and 's' equivalent) 
    related_noun_lemmas = [] 

    for drf in derivationally_related_forms: 
     for l in drf[1]: 
      if l.synset().name().split('.')[1] == to_pos or to_pos in (WN_ADJECTIVE, WN_ADJECTIVE_SATELLITE) and l.synset().name().split('.')[1] in (WN_ADJECTIVE, WN_ADJECTIVE_SATELLITE): 
       related_noun_lemmas += [l] 

    # Extract the words from the lemmas 
    words = [l.name() for l in related_noun_lemmas] 
    len_words = len(words) 

    # Build the result in the form of a list containing tuples (word, probability) 
    result = [(w, float(words.count(w))/len_words) for w in set(words)] 
    result.sort(key=lambda w:-w[1]) 

    # return all the possibilities sorted by probability 
    return result 


convert('direct', 'a', 'r') 
convert('direct', 'a', 'n') 
convert('quick', 'a', 'r') 
convert('quickly', 'r', 'a') 
convert('hunger', 'n', 'v') 
convert('run', 'v', 'a') 
convert('tired', 'a', 'r') 
convert('tired', 'a', 'v') 
convert('tired', 'a', 'n') 
convert('tired', 'a', 's') 
convert('wonder', 'v', 'n') 
convert('wonder', 'n', 'a') 

Come potete vedere di seguito, non funziona così bene. Non è in grado di passare da una forma di aggettivo a una di avverbio (il mio obiettivo specifico), ma fornisce risultati interessanti in altri casi.

>>> convert('direct', 'a', 'r') 
[] 
>>> convert('direct', 'a', 'n') 
[('directness', 0.6666666666666666), ('line', 0.3333333333333333)] 
>>> convert('quick', 'a', 'r') 
[] 
>>> convert('quickly', 'r', 'a') 
[] 
>>> convert('hunger', 'n', 'v') 
[('hunger', 0.75), ('thirst', 0.25)] 
>>> convert('run', 'v', 'a') 
[('persistent', 0.16666666666666666), ('executive', 0.16666666666666666), ('operative', 0.16666666666666666), ('prevalent', 0.16666666666666666), ('meltable', 0.16666666666666666), ('operant', 0.16666666666666666)] 
>>> convert('tired', 'a', 'r') 
[] 
>>> convert('tired', 'a', 'v') 
[] 
>>> convert('tired', 'a', 'n') 
[('triteness', 0.25), ('banality', 0.25), ('tiredness', 0.25), ('commonplace', 0.25)] 
>>> convert('tired', 'a', 's') 
[] 
>>> convert('wonder', 'v', 'n') 
[('wonder', 0.3333333333333333), ('wonderer', 0.2222222222222222), ('marveller', 0.1111111111111111), ('marvel', 0.1111111111111111), ('wonderment', 0.1111111111111111), ('question', 0.1111111111111111)] 
>>> convert('wonder', 'n', 'a') 
[('curious', 0.4), ('wondrous', 0.2), ('marvelous', 0.2), ('marvellous', 0.2)] 

Spero che questo è in grado di salvare una persona un po 'di problemi

Problemi correlati