- Java中的无穷大值

时间:2012-03-16 13:00:40

标签: java

我正在尝试总计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问题及其发生的原因?谢谢

6 个答案:

答案 0 :(得分:10)

对于某些值,spam.getClassProbability()会返回0.0see the docs

  

如果参数为正零或负零,则结果为负无穷大。

答案 1 :(得分:2)

Javadoc for Math解释了为什么你得到-Infinity

  

如果参数为正零或负零,则结果为负无穷大。

您应该检查零值,或在应用log功能之前将其过滤掉。

答案 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的对数。这承认游戏打破了零概率的概念。毕竟垃圾邮件制造者非常聪明,所以概率永远不会真正为零。

相关问题