实施朴素贝叶斯文本分类,但我总是得到零
Implementing Naive Bayes text categorization but I keep getting zeros
我正在使用朴素贝叶斯进行文本分类,这就是我为指定类别中的每个术语创建初始权重的方式:
- term1:类别 A
中文档的术语 1 exists/number 的次数
- term2:类别 A
中文档的术语 2 exists/number 的次数
term3:类别A
中文档的term 3 exists/number的次数
term1:类别 B
中文档的术语 1 exists/number 的次数
- term2:类别 B
中文档的术语 2 exists/number 的次数
- term3:类别 B
中文档的术语 3 exists/number 的次数
对于新的测试文档,我根据测试文档中是否存在该术语来调整权重:
- term1: 存在于测试文档中所以我对 categoryA_term1 使用与上面相同的权重
- term2:在测试文档中不存在,所以我使用 1 权重 categoryA_term2
term3:在测试文档中不存在,所以我使用 1-权重 categoryA_term3
term1: 存在于测试文档中所以我对categoryB_term1使用与上面相同的权重
- term2:在测试文档中不存在,所以我使用 1 权重 categoryB_term2
- term3: 存在于测试文档中所以我对 categoryB_term2 使用与上面相同的权重
然后我将每个类别的权重相乘。
这在我创建一个句子的虚拟 train/test 文档时有效,但是当我为 train/test 文档实现真实文档时,当我将它们加在一起时,我总是得到零。是不是因为概率太小了,乘了这么多小数,python就收敛到零了??
我被困住了,我只是让 运行 陷入同一个零问题 :( 非常感谢你的帮助!
正如 Ed Cottrell 评论的那样,您需要考虑如果遇到某个类别的文档中没有的词会发生什么。您可以使用 Laplace smoothing 避免乘以 0。如果你在一个类别的 n 个文档中看到 k 个词,你可以将条件概率 (k+1)/(n+2) 或 (k+a)/(n+2a) 分配给给定类别的那个词。
标准做法是计算乘积的对数,而不是取许多小数的乘积。
log x*y = log x + log y
log(P(a0|c) * P(a1|c) * ... * P(ak|c))
= log P(a0|c) + log P(a1|c) + ... + log P(ak|c)
那么你就有了一个不小的数字之和。避免使用 log 0。如有必要,您可以在之后取幂,但通常您只是将决策阈值转换为对数条件。
我正在使用朴素贝叶斯进行文本分类,这就是我为指定类别中的每个术语创建初始权重的方式:
- term1:类别 A 中文档的术语 1 exists/number 的次数
- term2:类别 A 中文档的术语 2 exists/number 的次数
term3:类别A
中文档的term 3 exists/number的次数
term1:类别 B
中文档的术语 1 exists/number 的次数
- term2:类别 B 中文档的术语 2 exists/number 的次数
- term3:类别 B 中文档的术语 3 exists/number 的次数
对于新的测试文档,我根据测试文档中是否存在该术语来调整权重:
- term1: 存在于测试文档中所以我对 categoryA_term1 使用与上面相同的权重
- term2:在测试文档中不存在,所以我使用 1 权重 categoryA_term2
term3:在测试文档中不存在,所以我使用 1-权重 categoryA_term3
term1: 存在于测试文档中所以我对categoryB_term1使用与上面相同的权重
- term2:在测试文档中不存在,所以我使用 1 权重 categoryB_term2
- term3: 存在于测试文档中所以我对 categoryB_term2 使用与上面相同的权重
然后我将每个类别的权重相乘。 这在我创建一个句子的虚拟 train/test 文档时有效,但是当我为 train/test 文档实现真实文档时,当我将它们加在一起时,我总是得到零。是不是因为概率太小了,乘了这么多小数,python就收敛到零了?? 我被困住了,我只是让 运行 陷入同一个零问题 :( 非常感谢你的帮助!
正如 Ed Cottrell 评论的那样,您需要考虑如果遇到某个类别的文档中没有的词会发生什么。您可以使用 Laplace smoothing 避免乘以 0。如果你在一个类别的 n 个文档中看到 k 个词,你可以将条件概率 (k+1)/(n+2) 或 (k+a)/(n+2a) 分配给给定类别的那个词。
标准做法是计算乘积的对数,而不是取许多小数的乘积。
log x*y = log x + log y
log(P(a0|c) * P(a1|c) * ... * P(ak|c))
= log P(a0|c) + log P(a1|c) + ... + log P(ak|c)
那么你就有了一个不小的数字之和。避免使用 log 0。如有必要,您可以在之后取幂,但通常您只是将决策阈值转换为对数条件。