Scipy expit: неожиданное поведение. значение NaN

заметил, что некоторые Нэнпоявлялись неожиданно, в моих данных. (и расширяется и naning все они коснулись) Провел тщательное расследование и привел минимальный рабочий пример:

>>> import numpy
>>> from scipy.special import expit
>>> expit(709)
1.0
>>> expit(710)
nan

Expit является обратным логитом. документация Scipy здесь. Что говорит нам: expit(x) = 1/(1+exp(-x))

так 1+exp(-709)==1.0, Так что expit(709)=1.0 кажется довольно разумным, округление exp(-709)==0.
Однако, что происходит с expit(710)?
expit(710)==nan означает, что 1+exp(-710)==0, из которого следует: exp(-710)=-1 это совсем не правильно.

что происходит?

я фиксирую его с:

def sane_expit(x):
    x = np.minimum(x,700*np.ones_like(x)) #Cap it at 700 to avoid overflow
    return expit(x)

но это будет немного медленнее, потому что дополнительный op и накладные расходы python.

я использую numpy 1.8.-0, и scipy 0.13.2

1 ответов


что происходит?

функция, очевидно, не закодирована для работы с такими большими входами и сталкивается с переполнением во время внутренних вычислений.

значение числа 710 в том, что math.exp(709) можно представить как float, тогда как math.exp(710) нельзя:

In [27]: import math

In [28]: math.exp(709)
Out[28]: 8.218407461554972e+307

In [29]: math.exp(710)
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
----> 1 math.exp(710)

OverflowError: math range error

стоит подача ошибки против SciPy.