Я пишу алгоритм, в котором, учитывая модель, я вычисляю вероятности для списка наборов данных, а затем должен нормализовать (для вероятности) каждый из вероятностей. Таким образом, что-то вроде [0.00043, 0.00004, 0.00321] может быть преобразовано в что-то вроде [0.2, 0.03, 0.77].
Моя проблема заключается в том, что вероятность журналов, с которыми я работаю, довольно мала (например, в пространстве журналов значения равны -269647.432, -231444.981 и т. Д.). В моем коде C ++, когда я пытаюсь добавить два из них (взяв их показатель степени), я получаю ответ «Inf». Я попытался добавить их в пространство журнала (Суммирование / Вычитание журнала) , но снова наткнулся на ту же проблему.
Кто-нибудь может поделиться своим мнением по этому поводу?
log1p
Ответы:
Вычтите максимальный логарифм из всех журналов. Отбросьте все результаты, которые настолько отрицательны, что потеряют экспоненциальный результат. (Их вероятность для всех практических целей равна нулю.)
Действительно, если вам нужна относительная точность (например, для цифр точности) и у вас вероятностей, отбросьте любой результат, меньший логарифма . Затем продолжайте как обычно, чтобы возвести в степень полученные значения и разделите каждое из них на сумму всех экспонент.ϵ = 10 - д д н ϵ / нϵ ϵ=10−d d n ϵ / н
Для тех, кто любит формулы, пусть логарифмы будут с . Для логарифмов к основанию определитеλ n = max ( λ i ) b > 1λ1, λ2, … , ΛN λN= max ( λя) б > 1
Нормализованные вероятности равны , Это работает, потому что замена всех остальных заниженных на ноль приводит к общей ошибке не более тогда как и все неотрицательны, знаменатель , откуда общая относительная ошибка, обусловленная правилом замены нуля, строго меньше , по желанию. i = 1 , 2 , … , n . α i ( n - 1 ) ϵ / n < ϵ α n = b λ n - λ n = b 0 = 1 α i A = ∑ j α j ≥ 1 ( ( n - 1αя/ ∑NJ = 1αJ я = 1 , 2 , … , н . αя ( n - 1 ) ϵ / n < ϵ αN= бλN- λN= б0= 1 αя A = ∑JαJ≥ 1 ( ( n - 1 ) ϵ / n ) / A < ϵ
Чтобы избежать слишком большой ошибки округления, вычислите сумму, начиная с наименьших значений . Это будет сделано автоматически при первой сортировке в порядке возрастания. Это соображение только для очень больших .λ i nαя λя N
Кстати, этот рецепт предполагал, что база журналов больше . Для баз меньших , сначала сверните все журналы и продолжайте, как если бы база была равна .б 1 1 / б1 б 1 1 / б
пример
Пусть будет три значения с логарифмами (скажем, натуральными), равными и Последний самый большой; вычитание его из каждого значения дает и- 231444,981 , - 231444,699. - 38202,733 , - 0,282 , 0.- 269647,432 , - 231444,981 , - 231444,699. - 38202,733 , - 0,282 , 0.
Предположим, вы хотите, чтобы точность была сопоставима с двойными значениями IEEE (около 16 десятичных цифр), чтобы и . (Вы не можете на самом деле достичь этой точности, потому что задается только тремя значащими цифрами, но это нормально: мы отбрасываем только те значения, которые гарантированно не повлияют на лучшую точность, которую вы хотите, и точность, которую вы на самом деле иметь.) Вычислить = = Первое из трех различий, меньше, чем это, поэтому отбросьте его, оставив только и их дает n = 3 - 0,282 log ( ϵ / n ) log ( 10 -ε = 10- 16 n = 3 - 0,282 журнал( ϵ / н ) -37,93997. -38202.733,-0,2820.ехр(-0,282)=0,754ехр(0)=100,754 / (1+0,754)=журнал( 10- 16) - журнал( 3 ) - 37,93997. - 38202,733 , - 0,282 0. ехр( - 0,282 ) = 0,754 и (конечно). Нормализованные значения - по порядку - для того, что вы выбросили, и .ехр( 0 ) = 1 0 1 / ( 1 + 0,754 ) = 0,5700.754/(1+0.754)=0.430 1/(1+0.754)=0.570
источник