4

我正在用非常大的数字做一些数学运算(我使用的是 Python,但这个问题不是 Python 特有的)。对于一个值,我有一个公式可以给我f(t) = Pr(X < t). 我想用这个公式得到Pr(X >= t) = 1 - f(t). 因为f(t)返回值非常接近于零,所以我一直在使用对数转换和存储log( f(t) )而不是f(t). 我log( f(t) )的顺序是-1e5 左右。

对于乘法,这非常有效。log( f(t) * g ) = log( f(t) ) + log(g).

但是,log( 1 - f(t) )仅使用; 来计算非常困难log( f(t) );当然,我可以暂时对我存储和计算的值求幂log( 1 - exp( log( f(t) ) ),但这会返回,log( 1 - 0.0 ) = 0.0因为log( f(t) )它非常接近于零。

你可能会问,“你为什么在乎?如果它接近于零,那么 1 减去它就非常接近于 1。” 嗯,这是一个很好的观点。你是个聪明的饼干。

问题是我想用它来对值进行排名,所以我真的很关心一个是log(0.999),另一个是log(0.9999)。你也可能会问,“好吧,你为什么不给 排名log( f(t) ),然后颠倒顺序来获得排名log( 1 - f(t) )。” 再一次,我不得不指出你的问题有多棒。与您交谈真的很愉快。

但问题是:我不只是想按1 - f(t); 我实际上想根据 排名Pr(X >= t) * g(t) = (1 - f(t)) g(t)。记录日志后,我得到log( 1 - f(t) ) + log( g(t) ); 仅基于排名f(t)不会给出正确答案。

过去我写了一个小 Python 函数来计算log(a + b)和:log(a)log(b)

def log_add(logA,logB):
    if logA == log(0):
        return logB
    if logA<logB:
        return log_add(logB,logA)
    return log( 1 + math.exp(logB-logA) ) + logA

它有助于首先将它们归一化,使它们靠近在一起,然后在它们靠近在一起时取幂。

不幸的是,我无法使用相同的技巧来进行减法运算,因为没有归一化因子可以将它们log(1)结合log( f(t) )在一起,因为它们相距甚远。

有谁知道如何解决这个问题?这似乎是一个经典的问题;我真的希望/希望/祈祷有一个聪明的功能可以在位级别上运行,可以log(1-x)log(x). 另外,如果你知道它是如何工作的,我真的很想知道。

干杯! 奥利弗

4

1 回答 1

2

如果log(f(t))确实是 -1e5(或类似数量级),则 0.0 是 的最佳浮点表示log(1-f(t))。确实,f(t) = exp(-1e5)因此,根据 dmuir 提到的泰勒级数,log(1-f(t)) = -exp(-1e5)(这实际上不是一个精确的等式,但它是一个非常好的近似值)。现在,-exp(-1e5) = -3.56e-43430,但是在 0 和 -4e-324 之间没有浮点数,所以最好的浮点表示是 0.0。

因此,使用标准浮点数是不可能做到的。

这有关系吗?你说要排名依据Pr(X >= t) * g(t) = (1 - f(t)) g(t),相当于排名依据log( 1 - f(t) ) + log( g(t) )。我们在上面发现log(1-f(t)) = -3.56e-43430,所以这个术语只有在不同的值log(g(t))相差不超过这个微小的数字并且你的计算足够准确以至于它可以通过这些微小的数字来区分(如果你使用标准浮点数字,那么您的计算将永远不够准确)。换句话说,如果log(f(t))确实是 -1e5 或类似的值,那么您只能按g(t).

然而,它可能是log(f(t))-1e5 的数量级,但它有时会采用更接近零的值,如 -10 或 -1。在这种情况下,你不能忽略它,你必须确实排名log(1-f(t)) + log(g(t))。您应该使用以下函数编写此math.log1p代码:rank by log1p(-f(t)) + log(g(t))。原因是如果 f(t) 接近于零,则不log(1-f(t))准确但log1p(-f(t))准确。如果 f(t) 非常接近于零,例如 when log(f(t)) = -1e5,那么log1p(-f(t)) = 0.0因为这是使用标准浮点数可以做到的最好的。

我使用“标准浮点数”是有原因的。可以使用更精确的浮点数,如果你真的想捕获这样的小数-3.56e-43430,你应该这样做。Python 中的一种可能性是mpmath(不幸的是,它似乎不支持该log1p功能)。请注意,这比标准浮点数要慢得多,正如我所说,我认为您不需要它。但是,如果您想更好地了解这些问题,值得一试。

于 2011-07-28T09:46:31.997 回答