4

所以我刚刚修复了以下代码中的一个有趣的错误,但我不确定我采用的最佳方法:

p = 1
probabilities = [ ... ] # a (possibly) long list of numbers between 0 and 1
for wp in probabilities:

  if (wp > 0):
    p *= wp

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up
# being zero
try:
    result = math.log(p)

因为结果不需要精确,我通过简单地保持最小的非零值来解决这个问题,如果 p 变成 0 就使用它。

p = 1
probabilities = [ ... ] # a long list of numbers between 0 and 1
for wp in probabilities:

  if (wp > 0):
    old_p = p
    p *= wp
    if p == 0:
      # we've gotten so small, its just 0, so go back to the smallest
      # non-zero we had
      p = old_p
      break

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up
# being zero
try:
    result = math.log(p)

这行得通,但对我来说似乎有点笨拙。我不做大量这种数值编程,我不确定这是否是人们使用的那种修复方法,或者是否有更好的东西我可以去做。

4

1 回答 1

9

既然math.log(a * b)等于,为什么不对数组math.log(a) + math.log(b)所有成员的日志求和呢?probabilities

这将避免p变得如此之小以至于不足的问题。

编辑:这是 numpy 版本,对于大型数据集来说更干净、更快:

import numpy
prob = numpy.array([0.1, 0.213, 0.001, 0.98 ... ])
result = sum(numpy.log(prob))
于 2010-06-08T17:58:54.923 回答