Понимание коллокационной оценки NLTK для биграмм и триграмм - PullRequest
23 голосов
/ 31 декабря 2011

Справочная информация:

Я пытаюсь сравнить пары слов, чтобы увидеть, какая пара «встречается чаще» в американском английском, чем другая пара.Я планировал / должен был использовать средства коллокации в NLTK для оценки пар слов, причем наиболее вероятной была пара с более высокой оценкой.

Подход:

Я кодировалв Python, используя NLTK (несколько шагов и импорт для краткости удалены):

bgm    = nltk.collocations.BigramAssocMeasures()
finder = BigramCollocationFinder.from_words(tokens)
scored = finder.score_ngrams( bgm.likelihood_ratio  )
print scored

Результаты:

Затем я проверил результаты, используя 2 пары слов, одно изкоторые с большой вероятностью могут происходить одновременно, и одна пара, которая не должна происходить («жареные кешью» и «кешью бензина»).Я был удивлен, увидев одинаковое количество слов:

[(('roasted', 'cashews'), 5.545177444479562)]
[(('gasoline', 'cashews'), 5.545177444479562)]

Я ожидал, что в моем тесте «жареные кешью» наберут больше, чем «бензиновые кешью».

Вопросы:

  1. Я неправильно понимаю использование словосочетаний?
  2. Мой код неверен?
  3. Мое предположение, что оценки должны отличаться, иесли да, то почему?

Большое спасибо за любую информацию или помощь!

1 Ответ

31 голосов
/ 31 декабря 2011

Документ о коллаборациях NLTK мне кажется довольно хорошим. http://www.nltk.org/howto/collocations.html

Вам нужно дать секретарю какой-нибудь значительный корпус для работы. Вот рабочий пример использования корпуса Брауна, встроенного в NLTK. Для запуска требуется около 30 секунд.

import nltk.collocations
import nltk.corpus
import collections

bgm    = nltk.collocations.BigramAssocMeasures()
finder = nltk.collocations.BigramCollocationFinder.from_words(
    nltk.corpus.brown.words())
scored = finder.score_ngrams( bgm.likelihood_ratio  )

# Group bigrams by first word in bigram.                                        
prefix_keys = collections.defaultdict(list)
for key, scores in scored:
   prefix_keys[key[0]].append((key[1], scores))

# Sort keyed bigrams by strongest association.                                  
for key in prefix_keys:
   prefix_keys[key].sort(key = lambda x: -x[1])

print 'doctor', prefix_keys['doctor'][:5]
print 'baseball', prefix_keys['baseball'][:5]
print 'happy', prefix_keys['happy'][:5]

Вывод кажется разумным, хорошо работает для бейсбола, меньше для доктора и счастлив.

doctor [('bills', 35.061321987405748), (',', 22.963930079491501), 
  ('annoys', 19.009636692022365), 
  ('had', 16.730384189212423), ('retorted', 15.190847940499127)]

baseball [('game', 32.110754519752291), ('cap', 27.81891372457088), 
  ('park', 23.509042621473505), ('games', 23.105033513054011), 
  ("player's",    16.227872863424668)]

happy [("''", 20.296341424483998), ('Spahn', 13.915820697905589), 
 ('family', 13.734352182441569), 
 (',', 13.55077617193821), ('bodybuilder', 13.513265447290536)
...