Как я должен иметь дело с плавающими числами, которые могут стать такими маленькими, что они становятся равными нулю - PullRequest
4 голосов
/ 08 июня 2010

Так что я просто исправил интересную ошибку в следующем коде, но я не уверен, что подход, который я выбрал, был лучшим:

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)

Это работает, но мне кажется немного глупым. Я не делаю тонну такого рода числового программирования, и я не уверен, что это именно тот тип исправлений, который используют люди, или я могу пойти на что-то лучшее.

1 Ответ

9 голосов
/ 08 июня 2010

Поскольку math.log(a * b) равно math.log(a) + math.log(b), почему бы не взять сумму журналов всех членов массива probabilities?

Это позволит избежать проблемы получения psmall он недоразвит.

Редактировать: это небольшая версия, которая чище и намного быстрее для больших наборов данных:

import numpy
prob = numpy.array([0.1, 0.213, 0.001, 0.98 ... ])
result = sum(numpy.log(prob))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...