web-dev-qa-db-ja.com

Pythonのscipy / numpyのexpのオーバーフロー?

次のエラーは何をしますか:

Warning: overflow encountered in exp

Python一般的に意味ですか?私はログ形式で比率を計算しています、すなわちlog(a)+ log(b)、そしてexpを使用して結果の指数を取得しています、次のように、logsumexpで合計を使用します。

c = log(a) + log(b)
c = c - logsumexp(c)

配列bの一部の値は、意図的に0に設定されています。それらのログは-Infです。

この警告の原因は何ですか?ありがとう。

20
user248237

あなたの場合、それはbがあなたの配列のどこかでvery小さく、数を得ていることを意味します(_a/b_またはexp(log(a) - log(b)))は、出力を格納するために使用しているdtype(float32、float64など)に対して大きすぎるものです。

Numpyは次のように構成できます

  1. この種のエラーは無視してください。
  2. エラーを出力しますが、実行を停止するための警告を表示しません(デフォルト)
  3. エラーを記録し、
  4. 警告を発する
  5. エラーを発生させる
  6. ユーザー定義関数を呼び出す

_numpy.seterr_ を参照して、浮動小数点配列でアンダーフローやオーバーフローなどを処理する方法を制御してください。

26
Joe Kington

指数関数に対処する必要がある場合、関数は非常に急速に成長するため、アンダーフロー/オーバーフローにすばやく入ります。典型的なケースは統計であり、さまざまな振幅の指数の合計が非常に一般的です。数値は非常に大きい/小さいので、一般的に、ログを「合理的な」範囲、いわゆるログドメインに留めるために取ります。

exp(-a) + exp(-b) -> log(exp(-a) + exp(-b))

Exp(-a)がまだアンダーフローするため、問題が発生します。たとえば、exp(-1000)はすでにdoubleとして表すことができる最小の数値を下回っています。たとえば、次のとおりです。

log(exp(-1000) + exp(-1000))

-1000(log(0 + 0))を与えますが、-1000のようなものを手動で期待できます(-1000 + log(2))。関数logsumexpは、設定された数値の最大値を抽出し、それをログから取り出すことにより、それを改善します。

log(exp(a) + exp(b)) = m + log(exp(a-m) + exp(b-m))

アンダーフローを完全に回避するわけではありません(たとえば、aとbが大幅に異なる場合)が、最終結果のほとんどの精度の問題を回避します

8

この方法を使用してこの問題を解決できると思います。

正規化

この方法の問題を克服しました。このメソッドを使用する前の分類精度は86%です。この方法を使用した後、分類の精度は:96%です!!!それは素晴らしい!
最初:
最小-最大スケーリング

Min-Max scaling

2番目:
Zスコアの標準化

Z-score standardization

これらは、normalizationを実装する一般的な方法です。
最初の方法を使用します。そして、私はそれを変更します。最大数は10で除算されます。したがって、結果の最大数は10です。したがって、exp(-10)はoverflow!ではありません。
私の答えがお役に立てば幸いです!(^_^)

3
intoo

exp(log(a) - log(b))exp(log(a/b))と同じではありませんか?これは_a/b_と同じですか?

_>>> from math import exp, log
>>> exp(log(100) - log(10))
10.000000000000002
>>> exp(log(1000) - log(10))
99.999999999999957
_

2010-12-07:これが「配列bの一部の値が意図的に0に設定されている」場合、本質的に0で割っています。それは問題のように聞こえます。

2
hughdbrown

私の場合、データの値が大きいことが原因でした。値を縮小するには、正規化(データが画像に関連しているため、255で除算)する必要がありました。

0
sheikirfanbasha