在Python中计算n-gram的逐点互信息(PMI)得分

时间:2011-03-08 11:09:13

标签: python n-gram

我有大量的n-gram和几个外部n-gram。我想根据这个语料库(计数)计算每个外部n-gram的PMI得分。

是否有任何工具可以执行此操作,或者有人可以在Python中为我提供一段可以执行此操作的代码?

问题是我的n-gram是2克,3克,4克和5克。因此,计算3克以上的概率非常耗时。

1 个答案:

答案 0 :(得分:5)

如果我正确理解你的问题,你想要计算诸如log {P(“x1 x2 x3 x4 x5”)/ P(“x1”)P(“x2”)... P(“x5”之类的东西“)}其中P测量任何给定的5克或1克是给定事物的概率(并且基本上是计数的比率,可能是拉普拉斯式偏移)。所以,单次通过你的语料库并存储(1)每1-gram,(2)每个n-gram(使用后者的dict),然后为每个外部n-gram你做几个dict的计数查找,一点算术,你就完成了。一开始就通过语料库,然后每个外部n-gram完成一定量的工作。

(注意:实际上我不确定如何为超过两个随机变量定义PMI;也许它就像log P(a)P(b)P(c)P(abc)/ P(ab)P (bc)P(a_c)。但是如果它沿着这些线条是任何东西,你可以用同样的方式做:迭代你的语料库计算很多东西,然后你需要的所有概率只是计数的比率,也许用Laplace-ish校正。)

如果您的语料库太大而无法将n-gram dict放入内存中,则将其划分为有点内存大小的块,为每个块计算n-gram dicts并将其以形式存储在光盘上这样可以合理有效地获得任何给定的n-gram条目;然后,对于每个外部n-gram,遍历块并加起来计数。

什么形式?由你决定。一个简单的选择:按照n-gram的词典顺序排列(注意:如果你正在使用单词而不是字母,你可能想要先将单词转换为数字;你需要对你的语料库进行一次初步传递这个);然后找到你想要的n-gram是二进制搜索或类似的东西,其中1GB大小的块意味着每块大约15-20个搜索量;你可以添加一些额外的索引来减少这种情况。或者:在光盘上使用哈希表,使用Berkeley DB或其他东西;在这种情况下,你可以放弃分块。或者,如果字母表很小(例如,这些是字母n-gram而不是单词n-gram而你正在处理纯英文文本),只需将它们存储在一个大数组中,直接查找 - 但在这种情况下,无论如何,你可以把整个事情都放在记忆中。