大事なことしか話さない

学んだことの備忘録 python/金融工学/ベイズ統計学など

numpy.clipとinvalid value encountered in double_scalars

(参考:numpy.clip — NumPy v1.14 Manual

機械学習でsigmoid関数の計算をしていたら

RuntimeWarning: invalid value encountered in double_scalars

RuntimeWarning: divide by zero encountered in log

この2つのエラーが出てきた

解決策:

numpy.clipをして極端な値の出現を抑える。

つまりsigmoidの式を

def sigmoid(x):
    return 1.0 / (1.0 + np.exp(-(np.clip(x, -10, 10))))

こんな感じにすれば解決した。  

何が起こっていたか:

そもそも下の式で表せられるシグモイド関数はxにどんな値を入れようがyは0,または1にはならない。

 { \displaystyle y = \frac{1}{1 + e^{-ax}}}

f:id:bnbnp:20180715165220p:plain

しかし、pythonでは最大桁数が定められているので、sigmoidの式xの値に大きかったり(10000とか)、小さかったりする値を入れてしまうと(本当は0.99999とか、0.00000001とかいう値が欲しいのにもかかわらず)本来は帰ってくるはずのない1.0とか、0.0とかいう値が帰ってきてしまう。

1.0 / (1.0 + np.exp(-50)) # 1.0

これはnumpy.clipで防げる。例えば、xに10という上限、-10という下限を設ければいい。

numpy.clip(114514, -10, 10)  # => 10

numpy.clip(-810931, -10, 10) # => -10

1.0 / (1.0 + numpy.exp(-810)) # => 1.0 <= 良くない!

1.0 / (1.0 + numpy.exp(-(numpy.clip(810, -10, 10)))) # => 0.9999546 <= 嬉しい!