我正在尝试总计561个日志 他们看起来像这样:
-7.314254939475686
-7.656004233197743
-4.816276208120333
-8.426112454893817
-4.771824445549499
-9.34240318676797
所以他们不是大数字。但是,当我继续总结它们时,我得到了这个:
-2668.179647264475
-2674.7747795369874
-2679.18920466334
-2683.9724816026214
-2690.3342661536453
-Infinity
-Infinity
执行此操作的代码是:
double probspam=0;
for(int j=0;j<words.size();j++)
{
probspam+= Math.log(spam.getClassProbability(words.get(j)));
}
您是否知道如何解决-Infinity问题及其发生的原因?谢谢
答案 0 :(得分:10)
对于某些值,spam.getClassProbability()
会返回0.0
:see the docs:
如果参数为正零或负零,则结果为负无穷大。
答案 1 :(得分:2)
答案 2 :(得分:1)
spam.getClassProbability(words.get(j))
的值很可能在某个时刻为零。
Math.log(0.0)
返回负无穷大(正如API文档所述)。
答案 3 :(得分:1)
您的一个垃圾邮件候选者从getClassProbability
获得零:
System.out.println(Math.log(0));
输出:
-Infinity
这是一个特殊的保留double值,对它的任何操作也会给-Infinity
,所以一旦它达到零,你的求和变量将保持-Infinity
要“修复”它,请执行以下操作:
double wordProbSpam = spam.getClassProbability(words.get(j));
probspam += wordProbSpam > 0 ? Math.log(wordProbSpam) : 0;
坦率地说,我觉得你的方法存在缺陷。我只是简单地总结了getClassProbability()的结果,而不是将它的 log 求和,因为对于0到1之间的数字,日志是负数,这将对总和做奇怪的事情。
答案 4 :(得分:1)
如果一个单词的类概率为零,则将-Infinity
添加到总和中。
答案 5 :(得分:1)
我认为你已经有了这个问题 - 你的日志是0.0。即使你的getClassProbability()是完美的,数值下溢可能仍然意味着它在数学上说结果为非零时返回零。
一个选项是用Double.ulp(0.0)的值替换所有零。这是Java可以表示的最小非零值(4.9e-324),并且具有-744.44的对数。这承认游戏打破了零概率的概念。毕竟垃圾邮件制造者非常聪明,所以概率永远不会真正为零。