我在Python中从零开始构建Naive Bayes文本分类器,我知道,在遇到概率非常小的乘积时,使用概率的对数是一个不错的选择。
现在的问题是,我使用的数学函数总和超过这些极小概率的乘积。
具体而言,我试图计算所有类别中混合成分(类)的总词概率。
简单地将这些总概率的日志相加是不正确的,因为总和的日志不等于日志的总和。
举个例子,假设我有3个班级,2000个单词和50个文件。 然后我有一个名为wordprob的单词概率矩阵,有2000行和3列。
此示例中的总词概率算法如下所示:
sum = 0
for j in range(0,3):
prob_product = 1
for i in words: #just the index of words from my vocabulary in this document
prob_product = prob_product*wordprob[i,j]
sum = sum + prob_product
最终发生的事情是,由于许多小概率相互乘以,prob_product在许多次迭代中变为0。
由于我无法通过日志轻松解决这个问题(因为前面的总结),我完全无能为力。
非常感谢任何帮助。
答案 0 :(得分:3)
我认为您最好将所有内容保存在日志中。计算产品日志的第一部分就是加上条款的日志。第二位,计算日志的指数总和的日志有点棘手。
一种方法是将产品的每个日志存储在一个数组中,然后你需要一个函数,给定一个带有n个元素的数组L,将计算
S = log( sum { i=1..n | exp( L[i])})
这样做的一种方法是找到L的最大值,比如说;一个小代数显示
S = M + log( sum { i=1..n | exp( L[i]-M)})
每个术语L [i] -M都是非正的,因此不会发生溢出。下溢不是问题,因为它们将返回0.至少其中一个(L [i]是M的那个)将为零,因此它的exp将是一个,我们最终会得到一些我们可以传递给它的东西登录。换句话说,对公式的评估将没有问题。
如果你有函数log1p(log1p(x)= log(1 + x))那么你可以通过省略(只有一个!)i得到一些准确度,其中L [i] == M来自总和,并且将总和传递给log1p而不是log。
答案 1 :(得分:1)
你的问题似乎在数学方面而不是编码。 我还没弄清楚你的问题是什么,但是日志的总和等于产品的日志。不知道这有帮助.. 此外,您正在计算每个j的一个prob_product,但您只是使用最后一个(并且您正在重新初始化它)。你打算做两件事之一:在j循环之前初始化它或在增加j之前使用它。最后,我不认为你需要初始化sum,除非这是你没有在这里显示的另一个循环的一部分。
这就是我现在拥有的一切。 对不起,很长的帖子,没有代码。
答案 2 :(得分:0)
log(A*B*....*Z) = log(A) + log(B) + ... + log(Z) != log(A + B + .... + Z)