理解NLTK二元组和三元组的搭配得分

27

背景:

我想比较一些单词对,看哪个单词对在美式英语中更有可能出现。我的计划是使用NLTK中的搭配功能来评分单词对,得分较高的单词对最有可能出现。

方法:

我用Python和NLTK编写了以下代码(为简洁起见省略了若干步骤和导入):

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

结果:

我随后使用两组单词对检查了结果,其中一组应该高度可能共现,另一组则不应该(“烤腰果”和“汽油腰果”)。但我惊讶地发现这两组单词的得分相同:

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

在我的测试中,我本来期望“烤腰果”比“汽油腰果”得分更高。

问题:

  1. 我是否误解了搭配用法?
  2. 我的代码是否有误?
  3. 如果是的话,我假设得分应该不同是错误的吗?为什么?

非常感谢您提供的任何信息或帮助!


另外一点评论:将所有4个单词组合在一起,即“烤腰果汽油腰果”,结果相似,因为所有的二元分数都是相同的。 - ccgillett
1个回答

34

NLTK的搭配文档对我来说似乎相当不错。http://www.nltk.org/howto/collocations.html

你需要为评分器提供一些实际的大型语料库。这里有一个使用内置于NLTK中的Brown语料库的工作示例。运行大约需要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)

1
好的,这解释了我一些误解。有没有方便的方法来搜索一个二元组并获得相关得分?仍在寻找一个使用模式,让我检查给定的二元组是否相关。感谢您的答案,非常有帮助! - ccgillett
你可以使用现成的代码和大型语料库,并将分数保存在一个大的二元键字典中,或者维护更原始的单词和二元频率计数(nltk 将其称为 FreqDist),当你想比较特定的二元组时,将其馈入内置的二元评分器。 - Rob Neuhaus
1
谢谢!昨晚我使用自定义语料库得到了一个非常酷的解决方案。它在一些困难的主题上表现得很好。感谢你帮我解决问题! - ccgillett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接