Convertir palabras entre formas verbales / sustantivas / adjetivas

Me gustaría una función de biblioteca de python que se traduzca / convierta en diferentes partes del habla. a veces debe mostrar varias palabras (por ejemplo, “codificador” y “código” son nombres del verbo “codificar”, uno es el sujeto, el otro es el objeto)

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

Principalmente me interesan los verbos sustantivos, para un progtwig de toma de notas que quiero escribir. es decir, puedo escribir “los antagonistas de la cafeína A1” o “la cafeína es un antagonista A1” y con un poco de PNL puede darse cuenta de que significan lo mismo. (Sé que no es fácil, y que tomará la PNL que analiza y no solo etiqueta, sino que quiero piratear un prototipo).

preguntas similares … Convertir adjetivos y adverbios a sus formas nominales (esta respuesta solo se deriva de la raíz POS. Quiero ir entre POS.)

ps llamado Conversión en lingüística http://en.wikipedia.org/wiki/Conversion_%28linguistics%29

Este es más un enfoque heurístico. Acabo de codificarlo, así que disculpas por el estilo. Utiliza las formas_delacionadas derivacionalmente () de wordnet. He implementado nounify. Supongo que las obras se verifican análogamente. De lo que he probado funciona bastante bien:

 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 

Aquí hay una función que, en teoría, es capaz de convertir palabras entre la forma de sustantivo / verbo / adjetivo / adverbio que actualicé desde aquí (originalmente escrito por bogs , creo) para cumplir con nltk 3.2.5 ahora que synset.lemmas y sysnset.name son funciones.

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

Como puedes ver a continuación, no funciona tan bien. Es incapaz de cambiar entre adjetivo y forma de adverbio (mi objective específico), pero da algunos resultados interesantes en otros casos.

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

Espero que esto sea capaz de salvar a alguien un poco de problemas

Entiendo que esto no responde a toda tu pregunta, pero sí responde a una gran parte de ella. Revisaría http://nodebox.net/code/index.php/Linguistics#verb_conjugation Esta biblioteca de Python puede conjugar verbos y reconocer si una palabra es un verbo, un sustantivo o un adjetivo.

CÓDIGO EJEMPLO

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

También puede categorizar palabras.

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

La descarga está en la parte superior del enlace.

Un enfoque puede ser usar un diccionario de palabras con sus tags POS y un mapeo de formas de palabras. Si obtiene o crea dicho diccionario (lo cual es bastante posible si tiene acceso a los datos de cualquier diccionario convencional, ya que todos los diccionarios enumeran las tags POS de la palabra, así como los formularios base para todas las formas derivadas), puede usar algo como lo siguiente:

 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