Как извлечь глаголы и все соответствующие им наречия из текста?

Используя ngram в Python, моя цель — найти глаголы и соответствующие им наречия из входного текста. Что я сделал:

Введите текст: ""Он странно говорит. Лошадь может быстро бегать. Там большое дерево. Солнце красивое. Место хорошо оформлено. Они странно разговаривают. Она быстро бегает. Она много говорит. Джек бегает медленно». Код: -

`finder2 = BigramCollocationFinder.from_words(wrd for (wrd,tags) in posTagged if tags in('VBG','RB','VBN',))
scored = finder2.score_ngrams(bigram_measures.raw_freq)
print sorted(finder2.nbest(bigram_measures.raw_freq, 5))`

Из моего кода я получил вывод: [('talking', 'greatly'), ('talking', 'weirdly'), ('weirdly', 'talking'),('runs','fast'),('runs','slow')], который представляет собой список глаголов и соответствующих им наречий.

Что я ищу:

Я хочу выяснить глагол и все соответствующие наречия из этого. Например ('talking'- 'greatly','weirdly),('runs'-'fast','slow')etc.


person SOUBHIK RAKSHIT    schedule 27.01.2016    source источник
comment
Если вы ищете глаголы и наречия, почему заголовок вашего поста посвящен подлежащим и дополнениям? Пожалуйста, отредактируйте вопрос, чтобы вы могли получить разумные ответы.   -  person alexis    schedule 27.01.2016


Ответы (2)


У вас уже есть список всех биграмм глагол-наречие, поэтому вы просто спрашиваете, как объединить их в словарь, который дает все наречия для каждого глагола. Но сначала давайте воссоздадим ваши биграммы более прямым способом:

pairs = list()
for (w1, tag1), (w2, tag2) in nltk.bigrams(posTagged):
    if t1.startswith("VB") and t2 == "RB":
        pairs.append((w1, w2))

Теперь о вашем вопросе: мы создадим словарь с наречиями, которые следуют за каждым глаголом. Я буду хранить наречия в наборе, а не в списке, чтобы избавиться от дублирования.

from collections import defaultdict
consolidated = defaultdict(set)
for verb, adverb in pairs:
    consolidated[verb].add(adverb)

defaultdict предоставляет пустой набор для глаголов, которые раньше не встречались, поэтому нам не нужно проверять их вручную.

В зависимости от деталей вашего задания вы также можете сложить глаголы по падежам и лемматизировать так, чтобы наречия из «Опрометчиво ехал» и «Я вел осторожно» записывались вместе:

wnl = nltk.stem.WordNetLemmatizer()
...
for verb, adverb in pairs:
    verb = wnl.lemmatize(verb.lower(), "v")
    consolidated[verb].add(adverb)
person alexis    schedule 31.01.2016
comment
Огромное спасибо за помощь. Это мне очень помогло. - person SOUBHIK RAKSHIT; 02.02.2016
comment
Вы знаете, как представить эти результаты в матричной форме? Строка будет (verb, adv1, adv2, adv3) такой. - person SOUBHIK RAKSHIT; 02.02.2016
comment
Просто напечатайте каждый key, value в словаре как key, list(value) (поскольку значение является набором). - person alexis; 02.02.2016

Я думаю, что вы теряете информацию, которая вам понадобится для этого. Вам нужно каким-то образом сохранить данные о частях речи, чтобы биграммы, такие как ('weirdly', 'talking'), могли быть обработаны правильным образом.

Возможно, средство поиска биграмм может принимать помеченные кортежи слов (я не знаком с nltk). Или вам, возможно, придется прибегнуть к созданию внешнего индекса. Если это так, что-то вроде этого может работать:

part_of_speech = {word:tag for word,tag in posTagged}
best_bigrams = finger2.nbest(... as you like it ...)

verb_first_bigrams = [b if part_of_speech[b[1]] == 'RB' else (b[1],b[0]) for b in best_bigrams]

Затем, с глаголами впереди, вы можете преобразовать его в словарь, список списков или что-то еще:

adverbs_for = {}
for verb,adverb in verb_first_bigrams:
    if verb not in adverbs_for:
        adverbs_for[verb] = [adverb]
    else:
        adverbs_for[verb].append(adverb)
person aghast    schedule 27.01.2016
comment
Это провал, если одно и то же слово встречается как глагол и существительное: не говорите только о разговоре. - person alexis; 28.01.2016
comment
Я думаю, что что-то не так в этом коде. finder2 = BigramCollocationFinder.from_words(wrd for (wrd,tag) in posTagged if tag in ('VB','VBN','RB','VBD')) best_bigrams = finder2.nbest(bigram_measures.raw_freq, 10) verb_first_bigrams = [b if pos[b[1]] == 'RB' else (b[1],b[0]) for b in best_bigrams] print verb_first_bigrams adverbs_for = {} for verb,adverb in verb_first_bigrams: if verb not in adverbs_for: adverbs_for[verb] = [adverb] else: adverbs_for[verb].append(adverb) print adverbs_for - person SOUBHIK RAKSHIT; 28.01.2016
comment
Вывод этого кода выглядит следующим образом: {'talking': ['weirdly', 'decorated'], 'decorated': ['well'], 'run': ['well', 'weirdly']} это неправильно. - person SOUBHIK RAKSHIT; 28.01.2016
comment
Почему это не правильно? Глаголы являются ключами к словарю, наречия находятся в списках для каждого соответствующего глагола. Теперь ты можешь делать с ними все, что захочешь, не так ли? - person aghast; 28.01.2016
comment
@alexis Верно, но в этом случае ОП фильтрует только глаголы и наречия. В общем случае, вероятно, было бы лучше хранить данные тега как можно дольше. Но мы не знаем, какую проблему он на самом деле решает... - person aghast; 28.01.2016
comment
@Остин, посмотри сюда {говорю: странно, украшено}. "украшенный" - это не наречие. Так что это неправильно. Вы абсолютно правы, что глаголы являются ключами, а наречия находятся в списках для каждого соответствующего глагола. Но здесь за этим не следят, и посмотрите, они из разных предложений. - person SOUBHIK RAKSHIT; 28.01.2016
comment
И с этим {бежать : странно} невозможно.. Но это приходит на выходе. Если будет легче держать метки, то нет проблем.. - person SOUBHIK RAKSHIT; 28.01.2016
comment
@SOUBHIKRAKSHIT Я думаю, что проблема заключается в следующем: finder2 = BigramCollocationFinder.from_words(wrd for (wrd,tags) in posTagged if tags in('VBG','RB','VBN',)) Если у вас есть куча текста, и вы говорите фильтру просто вытащить наречия и глаголы, вы получите список наречий и глаголов, несколько случайным образом. Я думаю, вам нужно сначала разделить текст на предложения. - person aghast; 28.01.2016
comment
@SOUBHIK, ты пробовал? Вы упускаете суть: при вводе talk/VB the/D talk/NN существительное talk заменит глагол talk в словаре part_of_speech, и вы больше никогда его не увидите. Его не будет для выбора фильтра. Ваш подход неверен. - person alexis; 29.01.2016
comment
@alexis хорошая мысль на самом деле. Но другое дело, что такие предложения, как он быстро бежит, быстро помечены JJ, хотя это наречие. Пусть сделает это в качестве основного шага, а потом придумает способ избавиться от этих неясностей. Если вы предложите другой способ, я обязательно над ним поработаю. - person SOUBHIK RAKSHIT; 29.01.2016
comment
@Остин Спасибо за ваши предложения. Я пытаюсь найти способ с этим. - person SOUBHIK RAKSHIT; 29.01.2016
comment
@SOUBHIK, работа с неправильными (или неудобными) POS-тегами находится на совершенно другом уровне, чем ожидание только одного POS-тега на слово. Этот ответ должен быть исправлен, чтобы иметь дело с большим количеством из них. - person alexis; 29.01.2016