使用对数概率的复杂化 - 朴素贝叶斯文本分类器

Complication using log-probabilities - Naive Bayes text classifier

我正在 Python 中从头开始构建朴素贝叶斯文本 classifier 并且我知道,在遇到概率非常小的乘积时,对概率使用对数是不错的选择。

现在的问题是,我使用的数学函数对这些极小概率的乘积求和。

具体来说,我正在尝试计算给定混合成分 (class) 在所有 classes 中的总词概率。

简单地将这些总概率的对数相加是不正确的,因为总和的对数不等于对数之和。

举个例子,假设我有 3 classes,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。

由于我无法用日志轻松解决这个问题(因为前面的总结)我完全没有头绪

任何帮助将不胜感激。

你的问题似乎是关于事物的数学方面而不是它的编码。 我还没有完全弄清楚你的问题是什么,但日志的总和等于产品的日志。不知道这是否有帮助.. 此外,您正在为每个 j 计算一个 prob_product 但您只是使用最后一个(并且您正在重新初始化它)。你打算做两件事之一:要么在 j 循环之前初始化它,要么在递增 j 之前使用它。最后,我认为您不需要初始化 sum 除非这是您未在此处显示的另一个循环的一部分。

这就是我现在的全部。 对不起,很长post,没有代码。

High school algebra 告诉你:

log(A*B*....*Z) = log(A) + log(B) + ... + log(Z) != log(A + B + .... + Z)

我认为您最好将所有内容都保存在日志中。第一部分计算乘积的对数只是将项的对数相加。第二位,计算对数指数总和的对数有点棘手。

一种方法是将每个产品的日志存储在一个数组中,然后您需要一个函数,给定一个包含 n 个元素的数组 L,它将计算

S = log( sum { i=1..n | exp( L[i])})

一种方法是找到 L 的最大值,比如说 M;一点代数显示

S = M + log( sum { i=1..n | exp( L[i]-M)})

L[i]-M 中的每一项都是非正的,因此不会发生溢出。下溢不是问题,因为它们 exp 将 return 0。至少其中一个(L[i] 为 M 的那个)将为零,因此 exp 将为 1,我们将得到一些结果我们可以传递给日志。换句话说,公式的计算将没有问题。

如果你有函数 log1p (log1p(x) = log(1+x)) 那么你可以通过省略(只有一个!)i 来获得一些准确性,其中 L[i] == M 来自总和,并将总和传递给 log1p 而不是 log.