2010-11-17 5 views
5

Ho una matrice Nx1 che corrisponde a una distribuzione di probabilità, vale a dire la somma degli elementi somme a 1. Questo è rappresentato come un normale array numpy. Poiché N potrebbe essere relativamente grande, ad es. 10 o 20, molti dei singoli elementi sono abbastanza vicini a 0. Trovo che quando prendo log (my_array), ottengo l'errore "FloatingPointError: valore non valido rilevato nel registro". Si noti che questo è dopo aver impostato seterr (invalid = 'raise') in numpy intenzionalmente.prendendo il registro di valori molto piccoli usando numpy/scipy in Python

Come posso risolvere questo problema numerico? Mi piacerebbe rappresentare i vettori corrispondenti a una distribuzione di probabilità e il loro log di registrazione senza arrotondamento a 0, da allora finisco per prendere il log (0) che solleva l'errore.

grazie.

+0

Probabilità di zero è un caso speciale, perché dovresti considerarlo uguale a probabilità non zero? Perché non filtrarlo semplicemente dai dati e lavorare solo con il non zero? –

+1

Hai ricontrollato che tutti i valori nella distribuzione sono davvero positivi? Nessun valore negativo e nessun valore esattamente uguale a zero? Valori davvero piccoli non dovrebbero avere importanza. –

+0

Lo stesso problema di: http://stackoverflow.com/questions/3704570/in-python-small-floats-tending-to-zero – monkut

risposta

1

Quanto "abbastanza vicino" a 0 sono? Python sembra felice prendendo il log di 10^-molto grande:

>>> log(0.0000000000000000000000000001) 
-64.472382603833282 

Inoltre, perché stai prendendo i registri? Cosa pensi di fare con loro una volta che li hai presi?

2

Cosa c'è abbastanza vicino allo zero?

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

Una soluzione consiste nell'aggiungere un numero piccolo positivo a tutte le probabilità per limitare la loro distanza sufficiente da zero.

La seconda soluzione è gestire zeri esplicitamente, per esempio sostituire 0. * np.log (0) con zeri nella matrice risultante, o includere solo punti che hanno probabilità diversa da zero nella matrice probabilità

2

Puoi lascia cadere le code in base all'accuratezza di cui hai bisogno.

eps = 1e-50 
array[array<eps]=eps 
log(array) 
0

A seconda di quello che stai facendo seguito, è possibile utilizzare una diversa trasformazione che non esplode su valori pari a zero come log fa. Forse un sigmoid function o qualcos'altro con un giacobino ben definito.

Se stai solo cercando di visualizzare i dati, potresti sempre aggiungere qualche piccolo valore prima di prendere il registro.

Problemi correlati