5

次の比率を計算しようとしています: w(i) / (sum(w(j))ここでw、指数関数的減少関数を使用して更新されます。つまりw(i) = w(i) * exp(-k)k正のパラメーターです。すべての数値は負ではありません。次に、この比率を式に使用します (定数を掛けて、別の定数を追加します)。予想通り、すぐにアンダーフローの問題に遭遇しました。

これはよくあることだと思いますが、誰かがこれに対処する方法について参考にしてもらえますか? 適切な変換が見つからなかったので、安全しきい値として最小の正の数を設定しようとしましたが、最小の正のフロートを見つけることができませんでした (私は で数値を表していますnumpy.float128)。私のマシンで実際に最小の正の数を取得するにはどうすればよいですか? コードは次のようになります。

w = np.ones(n, dtype='float128')
lt = np.ones(n)
for t in range(T):
    p = (1-k) * w / w.sum() + (k/n)
    # Process a subset of the n elements, call it set I, j is some range()
    for i in I: 
        s = p[list(j[i])].sum()
        lt /= s
        w[s] *= np.exp(-k * lt)

ここで、k は (0,1) の定数で、n は配列の長さです。

4

1 に答える 1

3

指数関数的に小さい数を扱う場合は、通常、対数空間で作業する方が適切です。たとえば、log(w*exp(-k)) = log(w) - kk 自体が指数関数的に大きいか、w がゼロでない限り、オーバー/アンダーフローの問題は発生しません。そして、wがゼロの場合、numpy は正しく を返し-infます。次に、合計を行うときに、最大の項を因数分解します。

log_w = np.log(w) - k
max_log_w = np.max(log_w)
# Individual terms in the following may underflow, but then they wouldn't
# contribute to the sum anyways.
log_sum_w = max_log_w + np.log(np.sum(np.exp(log_w - max_log_w)))
log_ratio = log_w - log_sum_w

これはおそらく完全に因数分解することができるので(配列ではなく定数であると仮定して)、あなたが望むものとは正確には異なりますkが、それはあなたのやり方であなたを得るはずです.

scikit-learnは で同様のことを実装していますextmath.logsumexpが、基本的には上記と同じです。

于 2015-10-30T20:03:55.713 に答える