3

我想在一组句子上训练一个 NgramModel,使用 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)

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

Traceback (most recent call last):
  File "ngram.py", line 8, in <module>
    lm = NgramModel(2, fake_train, estimator = est)
  File "/usr/lib/python2.7/dist-packages/nltk/model/ngram.py", line 63, in __init__
    self._model = ConditionalProbDist(cfd, estimator, len(cfd))
  File "/usr/lib/python2.7/dist-packages/nltk/probability.py", line 2016, in __init__
    **factory_kw_args)
  File "ngram.py", line 4, in <lambda>
    est = lambda fdist, bins: WittenBellProbDist(fdist)
  File "/usr/lib/python2.7/dist-packages/nltk/probability.py", line 1210, in __init__
    self._P0 = self._T / float(self._Z * (self._N + self._T))
ZeroDivisionError: float division by zero

是什么导致了这个错误?据我所知,我根据文档正确使用了所有内容,当我使用 Lidstone 而不是 Witten-Bell 时,这可以正常工作。

作为第二个问题,我有一组不相交的句子形式的数据。我怎样才能使用像字符串列表这样的句子,或者做一些等效的事情来产生相同的分布?(即,我当然可以只使用一个列表,其中包含所有句子,并用一个虚拟标记分隔后续句子,但这不会产生相同的分布。)一个地方的文档说允许字符串列表,但后来我发现了一个错误报告,其中文档应该被编辑以反映这是不允许的(当我只是尝试一个字符串列表时,我得到一个错误)。

4

3 回答 3

2

它显然是近 3 年的一个已知问题。的原因ZeroDivisionError是由于以下几行__init__

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

每当bins未指定参数时,它默认为Noneso self._Zis really just freqdist.B() - freqdist.B()and

self._P0 = self._T / float(self._Z * (self._N + self._T))

减少到,

self._P0 = freqdist.B() / 0.0

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

print lm.entropy(fake_test)

你会收到NotImplementedError,因为在WittenBellProbDist课堂上,

def discount(self): 
    raise NotImplementedError()

discount方法显然也用于类中prob和类中logprobNgramModel因此您也无法调用它们。

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

于 2013-04-02T08:13:27.053 回答
1

2018 年 12 月更新

NLTK 3.4 包含重新设计的 ngram 建模模块,可导入为nltk.lm

于 2016-07-06T05:16:17.917 回答
0

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

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

于 2013-04-09T17:27:58.350 回答