我想实现Good-Turing平滑方法,这将改善我的语言模型。
让我们从理论开始(为简单起见,考虑一下unigram模型)。
有一个语料库(例如文学作品或任何大文本)。通过它我们正在建立一个语言模型。在我们构建它之后,我们可以找到该单词出现的概率。我使用MLE(最大似然估计)创建了这个模型,其具有高度的困惑值(构建模型的质量值,高值很差)。
我找到了一种使用Good-Turing平滑来改善它的方法:
这里:
P - the probability of use of the word
c - the number of use of the word
N_c - the count words with a frequency - c
N - the count words in the corpus
我在Python 3上的代码:
def good_turing(tokens):
N = len(tokens) + 1
C = Counter(tokens)
N_c = Counter(list(C.values()))
assert(N == sum([k * v for k, v in N_c.items()]))
default_value = N_c[1] / N
model = defaultdict(lambda: default_value)
types = C.keys()
B = len(types)
for _type in types:
c = C[_type]
model[_type] = (c + 1) * N_c[c + 1] / (N_c[c] * N) # Exception - "math domain error"
return model
这里有问题:
频率为c + 1的单词不能出现在语料库中,所以我们尝试 取log(0)并得到Math Domain Error
如何在平滑后计算最常用词的概率?
在阅读了几篇文章之后,我对这个主题的研究得出了以下公式的构建:
所以主要问题是:如何获得 E 功能? 我发现了这个:
但我不知道如何在scipy等中搜索 a 和 b 系数。