получение журнала очень маленьких значений с использованием numpy/scipy в Python

У меня есть массив Nx1, который соответствует распределению вероятностей, т.е. сумма элементов равна 1. Это представлено как обычный массив numpy. Поскольку N может быть относительно большим, например. 10 или 20, многие из отдельных элементов довольно близки к 0. Я обнаружил, что когда я беру log(my_array), я получаю сообщение об ошибке "FloatingPointError: в журнале обнаружено недопустимое значение". Обратите внимание, что это сделано после намеренной установки seterr(invalid='raise') в numpy.

Как я могу решить эту числовую проблему? Я хотел бы представить векторы, соответствующие распределению вероятностей, и их журнал взятия без округления до 0, так как в итоге я получаю журнал (0), что вызывает ошибку.

Благодарю.


person Community    schedule 17.11.2010    source источник
comment
Нулевая вероятность — это особый случай, почему вы считаете ее такой же, как и ненулевые вероятности? Почему бы просто не отфильтровать его из данных и работать только с ненулевыми?   -  person S.Lott    schedule 17.11.2010
comment
Вы дважды проверили, что все значения в распределении действительно положительны? Нет отрицательных значений и нет значений, которые точно равны нулю? Действительно маленькие значения не должны иметь значения.   -  person Sven Marnach    schedule 18.11.2010
comment
Та же проблема, что и: stackoverflow.com /вопросы/3704570/   -  person monkut    schedule 11.05.2012


Ответы (4)


Вы можете просто отбросить хвосты в соответствии с необходимой вам точностью.

eps = 1e-50
array[array<eps]=eps
log(array)
person gerry    schedule 17.11.2010

Что близко к нулю?

>>> np.log(0)
-inf
>>> 0.*np.log(0)
nan
>>> np.log(1e-200)
-460.51701859880916
>>> 1e-200*np.log(1e-200)
-4.6051701859880914e-198

Одно из решений состоит в том, чтобы добавить небольшое положительное число ко всем вероятностям, чтобы они были достаточно далеки от нуля.

Второе решение заключается в явной обработке нулей, например, замене 0.*np.log(0) нулями в результирующем массиве или включении в массив вероятностей только тех точек, которые имеют ненулевую вероятность.

person Josef    schedule 17.11.2010

Насколько они «довольно близки» к 0? Python кажется довольным, принимая журнал 10 ^ - очень большой:

>>> log(0.0000000000000000000000000001)
-64.472382603833282

Кроме того, почему вы берете журналы? Что вы планируете делать с ними после того, как заберете их?

person Spacedman    schedule 17.11.2010

В зависимости от того, что вы делаете потом, вы можете использовать другое преобразование, которое не взрывается при нулевых значениях, как это делает log. Возможно, это сигмовидная функция или что-то еще с четко определенным якобианом.

Если вы просто хотите визуализировать данные, вы всегда можете добавить небольшое значение, прежде чем брать журнал.

person Mark    schedule 17.11.2010