java中的下溢和日志值

时间:2014-08-02 20:10:55

标签: java math numbers double

关于在机器学习模型中处理小概率值,我有一个问题。

避免因浮点数乘以而导致的下溢问题的标准方法是使用log(x)而不是x

假设x = 0.50,其对数为log(x)= - 0.301029996

稍后恢复x的值(log(x))!= x即

0.740055574!= 0.50

那么,使用对数如何处理下溢呢?

2 个答案:

答案 0 :(得分:3)

这与溢出无关。在第一个log中,您计算​​基数10中的log,而不是自然对数。你可以这样做:

提升10^log(x)以获取x,或使用自然对数。

答案 1 :(得分:0)

(完全不确定我是否记得正确,所以如果我错了请纠正我。)

这不是overflow or underflow,而是关于floating point precision

这个想法是,如果你有很多非常小的数字,乘以它们会产生小数。比如说,你有10个概率为1%,或者每个0.01。将它们相乘,结果为1e-20。在这些区域,浮点精度不是很好,这可能会引入错误。在最坏的情况下,数字可以“舍入”为零,这将破坏整个计算。

对数的诀窍是转换为对数后

  1. 这些值通常会小得多(在指数较小的意义上),
  2. 而不是乘以值,你只需添加它们,所以非常小(或非常大)的数字不会变得更快(或更大) ,和
  3. 一旦你记录了所有的candudate概率,所有其他计算只是加法,而不是乘法,这也应该更快一点。
  4. 示例(使用Python,因为我太懒了,不能启动Eclipse,但是同样适用于Java):

    >>> x,y,z = 0.01, 0.02, 0.03
    >>> x*y*z
    6.0000000000000002e-06
    >>> log(x)+log(y)+log(z)
    -12.023751088736219
    >>> exp(log(x)+log(y)+log(z))
    6.0000000000000002e-06
    

    另外,正如另一个答案中所指出的,您的特定计算的问题是您似乎使用了对数base-10(Java中为log10),而exp(x)不是{反函数,但10^x。但请注意,在大多数语言/数学库中,log is in fact the natural logarithm