我应该如何处理浮点数,这些数字可能变得很小以至于变成零

发布于 2024-09-04 08:25:08 字数 906 浏览 6 评论 0原文

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

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)

这可行,但对我来说似乎有点笨拙。我不会进行大量此类数值编程,并且我不确定这是否是人们使用的修复方法,或者是否有更好的东西我可以寻求。

So I just fixed an interesting bug in the following code, but I'm not sure the approach I took it the best:

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)

Because the result doesn't need to be exact, I solved this by simply keeping the smallest non-zero value, and using that if p ever becomes 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)

This works, but it seems a bit kludgy to me. I don't do a ton of this kind of numerical programming, and I'm not sure if this is the kind of fix people use, or if there is something better I can go for.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

日记撕了你也走了 2024-09-11 08:25:08

既然,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))

Since, math.log(a * b) is equal to math.log(a) + math.log(b), why not take a sum of the logs of all members of the probabilities array?

This will avoid the problem of p getting so small it under-flows.

Edit: this is the numpy version, which is cleaner and a lot faster for large data sets:

import numpy
prob = numpy.array([0.1, 0.213, 0.001, 0.98 ... ])
result = sum(numpy.log(prob))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文