Преобразование слов между глаголом/существительным/прилагательными

Мне нужна функция библиотеки python, которая преобразует/преобразует разные части речи. иногда он должен выводить несколько слов (например, "кодер" и "код" - оба существительные из глагола "в код", один - субъект другого объекта)

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

В основном я забочусь о глаголах <= > существительных, для программы заметок, которую я хочу написать. то есть я могу написать "антагонисты кофеина A1" или "кофеин является антагонистом A1", и с некоторыми НЛП он может понять, что они означают одно и то же. (я знаю, что это нелегко, и что это займет НЛП, который анализирует и не просто тегирует, но я хочу взломать прототип).

подобные вопросы... Преобразование прилагательных и наречий в их существительные формы (этот ответ относится только к корневому POS. Я хочу перейти между POS.)

ps называется преобразование в лингвистике http://en.wikipedia.org/wiki/Conversion_%28linguistics%29

Ответ 1

Это более эвристический подход. Я только что закодировал его так, чтобы придумать стиль. Он использует деривационно-зависимые_формы() из wordnet. Я реализовал nounify. Думаю, verbify работает аналогично. Из того, что я тестировал, работает очень хорошо:

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

Я понимаю, что это не отвечает на весь ваш вопрос, но он отвечает на большую его часть. Я бы проверить http://nodebox.net/code/index.php/Linguistics#verb_conjugation Эта библиотека python способна сопрягать глаголы и распознавать, является ли слово глаголом, существительным или прилагательным.

ПРИМЕР КОДА

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

Он также может классифицировать слова.

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

Загрузка находится вверху ссылки.

Ответ 3

Один подход может заключаться в использовании словаря слов с их тегами POS и сопоставления wordforms. Если вы получаете или создаете такой словарь (что вполне возможно, если у вас есть доступ к любым обычным словарным данным, так как все словарные словарные словарные словарные слова POS-тегов, а также базовые формы для всех производных форм), вы можете использовать что-то вроде следующего:

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

Ответ 4

Вот функция, которая теоретически может преобразовывать слова между существительным/глаголом/прилагательным/формой наречия, которые я обновил из здесь ( изначально написанный bogs, я считаю), чтобы соответствовать nltk 3.2.5, теперь synset.lemmas и sysnset.name являются функциями.

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

Как вы можете видеть ниже, это не так здорово. Он не может переключаться между прилагательным и формой наречия (моя конкретная цель), но он дает некоторые интересные результаты в других случаях.

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

надеюсь, что это может спасти кого-то немного неприятностей.