Solución:
Como dice Fuglede, el problema aquí es que np.float64
no puede manejar un número tan grande como exp(1234.1)
. Intenta usar np.float128
en lugar de:
>>> cc = np.array([[0.120,0.34,-1234.1]], dtype=np.float128)
>>> cc
array([[ 0.12, 0.34, -1234.1]], dtype=float128)
>>> 1 / (1 + np.exp(-cc))
array([[ 0.52996405, 0.58419052, 1.0893812e-536]], dtype=float128)
Sin embargo, tenga en cuenta que existen ciertas peculiaridades con el uso de precisión extendida. Puede que no funcione en Windows; en realidad no obtienes los 128 bits completos de precisión; y puede perder la precisión cada vez que el número pasa por python puro. Puede leer más sobre los detalles aquí.
Para la mayoría de los propósitos prácticos, probablemente pueda aproximar 1 / (1 + <a large number>)
a cero. Es decir, simplemente ignore la advertencia y continúe. Numpy se encarga de la aproximación por usted (cuando usa np.float64
):
>>> 1 / (1 + np.exp(-cc))
/usr/local/bin/ipython3:1: RuntimeWarning: overflow encountered in exp
#!/usr/local/bin/python3.4
array([[ 0.52996405, 0.58419052, 0. ]])
Si desea suprimir la advertencia, puede usar scipy.special.expit
, como lo sugirió WarrenWeckesser en un comentario a la pregunta:
>>> from scipy.special import expit
>>> expit(cc)
array([[ 0.52996405, 0.58419052, 0. ]])
El mayor valor representable por un numpy
float es 1.7976931348623157e + 308, cuyo logaritmo es aproximadamente 709.782, por lo que no hay forma de representar np.exp(1234.1)
.
In [1]: import numpy as np
In [2]: np.finfo('d').max
Out[2]: 1.7976931348623157e+308
In [3]: np.log(_)
Out[3]: 709.78271289338397
In [4]: np.exp(709)
Out[4]: 8.2184074615549724e+307
In [5]: np.exp(710)
/usr/local/bin/ipython:1: RuntimeWarning: overflow encountered in exp
#!/usr/local/bin/python3.5
Out[5]: inf
Una posible solución es utilizar el decimal
módulo, que le permite trabajar con flotadores de precisión arbitrarios. Aquí hay un ejemplo donde un numpy
Se utiliza una matriz de flotadores con precisión de 100 dígitos:
import numpy as np
import decimal
# Precision to use
decimal.getcontext().prec = 100
# Original array
cc = np.array(
[0.120,0.34,-1234.1]
)
# Fails
print(1/(1 + np.exp(-cc)))
# New array with the specified precision
ccd = np.asarray([decimal.Decimal(el) for el in cc], dtype=object)
# Works!
print(1/(1 + np.exp(-ccd)))