2010-11-17 14 views
5

Tengo una matriz Nx1 que corresponde a una distribución de probabilidad, es decir, la suma de las sumas de elementos a 1. Esto se representa como una matriz numpy normal. Como N puede ser relativamente grande, p. 10 o 20, muchos de los elementos individuales están bastante cerca de 0. Encuentro que cuando tomo log (my_array), aparece el error "FloatingPointError: valor no válido encontrado en el registro". Tenga en cuenta que esto es después de configurar seterr (inválido = 'raise') en numpy intencionalmente.tomando el registro de valores muy pequeños usando numpy/scipy en Python

¿Cómo puedo lidiar con este problema numérico? Me gustaría representar los vectores correspondientes a una distribución de probabilidad y su registro de toma sin redondear a 0, desde entonces termino tomando el registro (0) que genera el error.

gracias.

+0

Probabilidad de cero es un caso especial, ¿por qué consideraría que es lo mismo que las probabilidades distintas de cero? ¿Por qué no simplemente filtrarlo de los datos y trabajar únicamente con el que no sea cero? –

+1

¿Ha comprobado dos veces que todos los valores en la distribución son realmente positivos? ¿Sin valores negativos y sin valores exactamente cero? Los valores realmente pequeños no deberían importar. –

+0

Mismo problema que: http://stackoverflow.com/questions/3704570/in-python-small-floats-tending-to-zero – monkut

Respuesta

1

¿Qué tan cerca están de 0? Python parece feliz al tomar el registro de 10^-mucho:

>>> log(0.0000000000000000000000000001) 
-64.472382603833282 

Además, ¿por qué estás llevando registros? ¿Qué planeas hacer con ellos una vez que los hayas tomado?

2

¿Qué hay cerca de cero?

>>> 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 solución es agregar un pequeño número positivo a todas las probabilidades para restringirlo lo suficientemente lejos de cero.

La segunda solución es manejar ceros explícitamente, por ejemplo reemplazar 0. * np.log (0) con ceros en la matriz resultante, o sólo incluyen puntos que tienen probabilidad distinta de cero en la matriz de probabilidad

2

Puede simplemente deje caer las colas de acuerdo con la precisión que necesita.

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

Dependiendo de lo que está haciendo después, se puede utilizar una diferente transformación que no explota en los valores cero como registro hace. Tal vez un sigmoid function o algo más con un jacobiano bien definido.

Si solo desea visualizar los datos, siempre puede agregar un pequeño valor antes de tomar el registro.

Cuestiones relacionadas