Konversi (normalisasi) sangat kecil nilai kemungkinan menjadi probabilitas

21

Saya menulis sebuah algoritma di mana, diberikan model, saya menghitung kemungkinan untuk daftar dataset dan kemudian perlu menormalkan (untuk probabilitas) masing-masing kemungkinan. Jadi sesuatu seperti [0,00043, 0,00004, 0,00321] mungkin dikonversi menjadi seperti [0,2, 0,03, 0,77].

Masalah saya adalah kemungkinan log, saya bekerja dengan, cukup kecil (misalnya, dalam ruang log, nilainya seperti -269647.432, -231444.981 dll). Dalam kode C ++ saya, ketika saya mencoba untuk menambahkan dua dari mereka (dengan mengambil eksponen mereka) saya mendapatkan jawaban "Inf". Saya mencoba menambahkannya di ruang log (Penjumlahan / Pengurangan log) , tetapi sekali lagi menemukan masalah yang sama.

Adakah yang bisa berbagi pendapat ahli tentang hal ini?

Ikram
sumber
Ketika Anda menggunakan fungsi yang Anda tunjuk melibatkan , apakah Anda menggunakan fungsi dalam bahasa Anda? Ini menggunakan ekspansi Taylor sekitar 1.log(1+...)log1p
Neil G
1
Lihat juga beberapa diskusi sebelumnya yang terkait di sini
Glen_b -Reinstate Monica

Jawaban:

30

Kurangi logaritma maksimum dari semua log. Buang semua hasil yang sangat negatif sehingga akan melemahkan eksponensial. (Kemungkinannya, untuk semua tujuan praktis, nol.)

Memang, jika Anda menginginkan presisi relatif dari (seperti untuk digit presisi) dan Anda memiliki kemungkinan, buanglah hasil yang kurang dari logaritma . Kemudian lanjutkan seperti biasa untuk membuat eksponensial nilai yang dihasilkan dan bagi masing-masing dengan jumlah semua eksponensial.ϵ = 10 - d d n ϵ / nϵϵ=10ddnϵ/n

Bagi mereka yang suka rumus, biarkan logaritma menjadi dengan . Untuk logaritma ke basis b \ gt 1 , tentukanλ n = maks ( λ i ) b > 1λ1,λ2,...,λnλn=maks(λsaya)b>1

αsaya={bλsaya-λn,λsaya-λnlog(ϵ)-log(n)0jika tidak.

Kemungkinan dinormalisasi sama dengan , Ini berfungsi karena mengganti semua underflow dengan nol membuat kesalahan total paling banyak sedangkan, karena dan semua adalah non-negatif, penyebut , di mana total kesalahan relatif karena aturan penggantian nol secara ketat lebih kecil dari , seperti yang diinginkan. i = 1 , 2 , , n . α i ( n - 1 ) ϵ / n < ϵ α n = b λ n - λ n = b 0 = 1 α i A = j α j1 ( ( n - 1αsaya/j=1nαjsaya=1,2,...,n.αsaya(n-1)ϵ/n<ϵαn=bλn-λn=b0=1αsayaSEBUAH=jαj1((n-1)ϵ/n)/SEBUAH<ϵ

Untuk menghindari kesalahan pembulatan yang terlalu banyak, hitung jumlah yang dimulai dengan nilai terkecil dari . Ini akan dilakukan secara otomatis ketika pertama kali disortir dalam urutan yang meningkat. Ini hanya pertimbangan untuk sangat besar .λ i nαsayaλsayan

BTW, resep ini mengasumsikan basis log lebih besar dari . Untuk basis kurang dari , pertama negasikan semua log dan lanjutkan seolah-olah basis sama dengan .b 1 1 / b1b11/b


Contoh

Biarkan ada tiga nilai dengan logaritma (log natural, katakanlah) sama dengan dan Yang terakhir adalah yang terbesar; Mengurangkannya dari masing-masing nilai memberi dan- 231444.981 , - 231444.699. - 38202.733 , - 0.282 , 0.-269647.432, -231444.981,-231444.699.-38202.733, -0,282,0.

Misalkan Anda ingin presisi sebanding dengan dua kali lipat IEEE (sekitar 16 angka desimal), sehingga dan . (Anda tidak dapat benar-benar mencapai ketepatan ini, karena hanya diberikan kepada tiga angka penting, tapi tidak apa-apa: kami hanya membuang nilai yang dijamin tidak akan memengaruhi ketepatan yang Anda inginkan, dan ketepatan yang sebenarnya Anda dapatkan have.) Hitung = = Yang pertama dari tiga perbedaan, lebih sedikit dari ini, jadi buanglah, hanya dan Memberi eksponensial memberi n = 3 - 0,282 log ( ϵ / n ) log ( 10 - 16 ) - log ( 3 ) - 37,93997. - 38202.733 , - 0.282 0. exp ( - 0.282 ) = 0.754 exp ( 0 ) = 1 0 0.754 / ( 1 + 0.754 ) =ϵ=10-16n=30.282log(ϵ/n)log(1016)log(3)37.93997.38202.733,0.2820.exp(0.282)=0.754 dan (tentu saja). Nilai yang dinormalisasi adalah - dalam urutan - untuk yang Anda buang, , dan .exp(0)=100.754/(1+0.754)=0.4301/(1+0.754)=0.570

whuber
sumber
Ini brilian - sangat sederhana, dan sangat jelas di belakang. @ Ikram, tandai ini sebagai jawaban yang benar! (kecuali tentu saja Anda memiliki sesuatu yang lebih baik, dalam hal ini silakan bagikan)
zelanix
2
@whuber apakah kita perlu membuang ? Eksponen yang memberi kita nol, jadi tidak akan berkontribusi pada penjumlahan. 38202.733
Taylor