使用Witten-Bell平滑法在nltk中使用ngramodel训练和评估二元/三元分布

2024-10-02 06:38:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用一组句子训练一个ngram模型,使用Witten-Bell平滑来估计看不见的ngram,然后用它来得到由该分布生成的测试集的对数可能性。我想做与这里的文档示例中几乎相同的事情:http://nltk.org/_modules/nltk/model/ngram.html,但是使用的是Witten-Bell平滑。下面是一些关于我想做的事情的玩具代码:

from nltk.probability import WittenBellProbDist
from nltk import NgramModel

est = lambda fdist, bins: WittenBellProbDist(fdist)
fake_train = [str(t) for t in range(3000)]
fake_test = [str(t) for t in range(2900, 3010)]

lm = NgramModel(2, fake_train, estimator = est)

print lm.entropy(fake_test)

不幸的是,当我尝试运行它时,我得到以下错误:

^{pr2}$

是什么导致了这个错误?据我所知,根据文档,我使用的一切都是正确的,当我使用Lidstone而不是Witten Bell时,这一切都很好。在

作为第二个问题,我有一些不连贯句子的数据。我怎样才能像字符串列表一样使用这些句子,或者做一些类似的事情来产生相同的分布呢?(也就是说,我当然可以使用一个包含所有句子的列表,并用一个虚拟标记分隔后面的句子,但这不会产生相同的分布。)一个地方的文档说允许使用字符串列表,但后来我发现了一个bug报告,其中文档被假定是被编辑的,以反映这是不允许的(当我尝试一个字符串列表时,我得到了一个错误)。在


Tags: 字符串from文档import列表错误事情fake
3条回答

2018年12月更新

nltk3.4包含了重新设计的ngram建模模块,可导入为nltk.lm

我会暂时远离NLTK的ngramodel。当前存在一个平滑错误,导致模型在n>;1时大大高估了可能性。这适用于包括WittenBellProbDist和LidstoneProbDist在内的所有估计器。我认为这个错误已经存在了几年了,这表明NLTK的这一部分没有经过很好的测试。在

参见: https://github.com/nltk/nltk/issues/367

它显然是almost 3 years的已知问题。ZeroDivisionError的原因是由于__init__中的以下行

if bins == None: 
    bins = freqdist.B() 
self._freqdist = freqdist 
self._T = self._freqdist.B() 
self._Z = bins - self._freqdist.B() 

每当没有指定bins参数时,它默认为None,因此self._Z实际上只是freqdist.B() - freqdist.B(),并且

^{pr2}$

减少到

self._P0 = freqdist.B() / 0.0

另外,如果将bins指定为大于freqdist.B()的任何值,则在执行这行代码时

print lm.entropy(fake_test)

您将收到NotImplementedError,因为在WittenBellProbDist类中

def discount(self): 
    raise NotImplementedError()

显然,discount方法也在NgramModel类的prob和{}中使用,因此您也无法调用它们。在

在不改变NLTK的情况下,解决这些问题的一种方法是从WittenBellProbDist继承并重写相关的方法。在

相关问题 更多 >

    热门问题