decimals - Información mutua continua en Python.
python float precision (1)
Antes de intentar soluciones más radicales, como replantear el problema o usar diferentes herramientas de integración, vea si esto ayuda. Reemplace INF=float(''INF'')
con INF=1E12
o algún otro número grande, que puede eliminar los resultados de NaN creados por operaciones aritméticas simples en las variables de entrada.
No hay promesas en este caso, pero a veces es útil intentar una solución rápida antes de realizar una reescritura algorítmica significativa o la sustitución de herramientas alternativas.
[Frontmatter] (omita esto si solo quiere la pregunta) :
Actualmente estoy considerando usar la información mutua de Shannon-Weaver y la redundancia normalizada para medir el grado de enmascaramiento de la información entre bolsas de valores de características discretas y continuas, organizadas por características. Utilizando este método, mi objetivo es construir un algoritmo que se parezca muy a ID3 , pero en lugar de usar la entropía de Shannon , el algoritmo buscará (como una restricción de bucle) maximizar o minimizar la información compartida entre una única característica y una colección de funciones basadas en el espacio de entrada completo, añadiendo nuevas funciones a la última colección si (y solo si) aumentan o disminuyen la información mutua, respectivamente. Esto, en efecto, mueve el algoritmo de decisión de ID3 al espacio de pares, grapando un enfoque conjunto al mismo con todas las complejidades de tiempo y espacio esperadas de ambos métodos.
[/ Frontmatter]
A la pregunta: estoy intentando que un integrator continuo funcione en Python usando SciPy . Debido a que estoy trabajando con comparaciones de variables discretas y continuas, mi estrategia actual para cada comparación para pares de características es la siguiente:
Característica discreta versus característica discreta: use la forma discreta de información mutua. Esto da como resultado una suma doble de las probabilidades, que mi código maneja sin problema.
Todos los demás casos (discretos versus continuos, inversos y continuos versus continuos): use la forma continua, usando un estimador gaussiano para suavizar las funciones de densidad de probabilidad .
Es posible que realice algún tipo de discretización para los últimos casos, pero como los conjuntos de datos de entrada no son intrínsecamente lineales, esto es potencialmente innecesariamente complejo.
Aquí está el código saliente:
import math
import numpy
import scipy
from scipy.stats import gaussian_kde
from scipy.integrate import dblquad
# Constants
MIN_DOUBLE = 4.9406564584124654e-324
# The minimum size of a Float64; used here to prevent the
# logarithmic function from hitting its undefined region
# at its asymptote of 0.
INF = float(''inf'') # The floating-point representation for "infinity"
# x and y are previously defined as collections of
# floating point values with the same length
# Kernel estimation
gkde_x = gaussian_kde(x)
gkde_y = gaussian_kde(y)
if len(binned_x) != len(binned_y) and len(binned_x) != len(x):
x.append(x[0])
y.append(y[0])
gkde_xy = gaussian_kde([x,y])
mutual_info = lambda a,b: gkde_xy([a,b]) * /
math.log((gkde_xy([a,b]) / (gkde_x(a) * gkde_y(b))) + MIN_DOUBLE)
# Compute MI(X,Y)
(minfo_xy, err_xy) = /
dblquad(mutual_info, -INF, INF, lambda a: 0, lambda a: INF)
print ''minfo_xy = '', minfo_xy
Tenga en cuenta que hacer un recuento exacto de un punto se hace deliberadamente para evitar una singularidad en la clase gaussian_kde de SciPy. A medida que el tamaño de x e y se aproximan mutuamente al infinito, este efecto se vuelve insignificante.
Mi problema actual es intentar que la integración múltiple funcione contra una estimación de densidad del kernel gaussiano en SciPy. He estado tratando de usar el dblquad de SciPy para realizar la integración, pero en este último caso, recibí una asombrosa descarga de los siguientes mensajes.
Cuando configuro numpy.seterr ( all=''ignore'' )
:
Advertencia: se detecta la aparición de un error de redondeo, lo que impide que se logre la tolerancia solicitada. El error puede ser subestimado.
Y cuando lo configuro en ''call''
usando un manejador de errores:
Error de punto flotante (subflujo), con bandera 4
Error de punto flotante (valor inválido), con bandera 8
Bastante fácil de averiguar qué está pasando, ¿verdad? Bueno, casi: IEEE 754-2008 y SciPy solo me dicen lo que está sucediendo aquí, no por qué o cómo trabajar alrededor de él .
El resultado: minfo_xy
generalmente se resuelve en nan
; su muestreo es insuficiente para evitar que la información se pierda o no sea válida al realizar la matemática Float64.
¿Hay una solución general para este problema al usar SciPy?
Aún mejor: si hay una implementación sólida y enlatada de información mutua continua para Python con una interfaz que toma dos colecciones de valores de punto flotante o una colección combinada de pares, resolvería este problema completo. Por favor enlázalo si sabes de alguna que exista.
Gracias de antemano.
Edición: esto resuelve el problema de propagación de nan
en el ejemplo anterior:
mutual_info = lambda a,b: gkde_xy([a,b]) * /
math.log((gkde_xy([a,b]) / ((gkde_x(a) * gkde_y(b)) + MIN_DOUBLE)) /
+ MIN_DOUBLE)
Sin embargo, la cuestión de la corrección de redondeo permanece, al igual que la solicitud de una implementación más sólida. Cualquier ayuda en cualquier dominio sería muy apreciada.