Piszę algorytm, w którym przy danym modelu obliczam prawdopodobieństwa dla listy zestawów danych, a następnie muszę znormalizować (według prawdopodobieństwa) każde z prawdopodobieństw. Więc coś w rodzaju [0,00043, 0,00004, 0,00321] można przekonwertować na coś takiego jak [0,2, 0,03, 0,77].
Mój problem polega na tym, że prawdopodobieństwa dziennika, z którymi pracuję, są dość małe (na przykład w przestrzeni dziennika, wartości są takie jak -269647.432, -231444.981 itp.). W moim kodzie C ++, gdy próbuję dodać dwa z nich (biorąc ich wykładnik), otrzymuję odpowiedź „Inf”. Próbowałem dodać je w przestrzeni dziennika (sumowanie / odejmowanie dziennika) , ale znów natknąłem się na ten sam problem.
Czy ktoś może podzielić się swoją opinią na ten temat?
log1p
funkcji w swoim języku? Wykorzystuje to rozszerzenie Taylora około 1.Odpowiedzi:
Odejmij maksymalny logarytm od wszystkich dzienników. Wyrzuć wszystkie wyniki, które są tak negatywne, że będą zaniżać wartość wykładniczą. (Ich prawdopodobieństwa są dla wszystkich praktycznych celów zerowe.)
Rzeczywiście, jeśli chcesz względnej dokładności (takiej jak ϵ = 10 - d dla cyfr dokładności d ) i masz n prawdopodobieństw, odrzuć dowolny wynik mniejszy niż logarytm ϵ / n . Następnie postępuj jak zwykle, aby potęgować otrzymane wartości i podzielić każdą z nich przez sumę wszystkich wykładniczych.ϵ ϵ = 10- d re n ϵ / n
Dla tych, którzy lubią formuły, niech logarytmy będą wynosić z λ n = max ( λ i ) . Dla logarytmów do podstawy b > 1 zdefiniujλ1, λ2),…,λn λn=max(λi) b>1
Znormalizowane prawdopodobieństwa wynoszą , i = 1 , 2 , … , n . Działa to, ponieważ zastąpienie wszystkich pozostałych niedomiarów α i przez zero powoduje całkowity błąd co najwyżej ( n - 1 ) ϵ / n < ϵ, podczas gdy, ponieważ α n = b λ n - λ n = b 0 =αi/∑nj=1αjot i = 1 , 2 , … , n . αja ( n - 1 ) ϵ / n < ϵ i wszystkie α i są nieujemne mianownik = Σ j α J ≥ 1 , z którego całkowitawzględembłędu ze względu na zasady zerowej wymiany ściśle mniejszy niż ( ( n - 1 ) ε / n ) / < ϵ , zgodnie z życzeniem.αn= bλn- λn= b0= 1 αja A = ∑jotαjot≥ 1 ( ( n - 1 ) ϵ / n ) / A < ϵ
Aby uniknąć zbyt dużego błędu zaokrąglania, oblicz sumę zaczynając od najmniejszych wartości . Nastąpi to automatycznie, gdy λ i zostaną najpierw posortowane w porządku rosnącym. Jest to rozważane tylko dla bardzo dużej liczby n .αja λja n
BTW, ta recepta przyjęła, że baza dzienników jest większa niż . Dla zasad b mniejszych niż 1 , najpierw neguj wszystkie logi i postępuj tak, jakby baza była równa 1 / b .1 b 1 1 / b
Przykład
Niech będzie trzy wartości z logarytmów naturalnych (dzienniki, powiedzmy) jest równa - +231.444,981 , i - +231.444,699. Ostatni jest największy; odejmując ją od każdej wartości daje - 38202.733 , - 0,282 , a 0.- 269647.432 , - 231444.981 , - 231444.699. - 38202,733 , - 0,282 , 0.
Załóżmy, że chcesz dokładność porównywalną z IEEE podwójnej (około 16 miejsc po przecinku), tak że i n = 3 . (Tak naprawdę nie można osiągnąć tej precyzji, ponieważ - 0,282 podaje się tylko trzem znaczącym liczbom, ale to w porządku: odrzucamy tylko te wartości, które z pewnością nie wpłyną na lepszą pożądaną precyzję mają) oblicz. log ( ε / n ) = log ( 10 - 16 ) - log ( 3 ) = -ϵ = 10- 16 n = 3 - 0,282 log( ϵ / n ) log( 10- 16) - log( 3 ) Pierwszy z trzech różnic - 38202.733 , jest mniejsza niż to, więc go wyrzucić, pozostawiając tylko - 0,282 i 0. Exponentiating im daje exp ( - 0,282 ) = 0,754 i exp ( 0 ) = 1 (oczywiście). Znormalizowane wartości wynoszą - w kolejności - 0 dla wyrzuconego, 0,754 / ( 1 + 0,754 ) = 0,430 i 1 / ( 1 +- 37,93997. - 38202,733 , - 0,282 0. exp( - 0,282 ) = 0,754 exp( 0 ) = 1 0 0,754 / ( 1 + 0,754 ) = 0,430 .1 / ( 1 + 0,754 ) = 0,570
źródło