1

log(1 - normal_cdf(x))数値的に安定した方法で評価する方法は? ここで、normal_cdfは標準正規分布の累積分布関数です。

たとえば、Python では次のようになります。

import scipy 
from scipy.stats import norm

np.log(1 - norm.cdf(10))

-infとほぼ等しいRuntimeWarning: divide by zero encountered in logのでで与えます。数値のアンダーフローを回避できるような関数はありますか?norm.cdf(10)1logsumexp

4

2 に答える 2

4

正規分布は 0 について対称なので、

1 - F(x) = P(X > x)
         = P(X < -x)
         = F(-x)

したがって

np.log(1 - norm.cdf(10)) = np.log(norm.cdf(-10))
                         = norm.logcdf(-10)
于 2018-05-10T23:37:27.133 に答える
2

対称性を利用するという@HongOoiの提案は素晴らしいです。しかし、scipy.stats( を含む) の任意の分布の場合、この方法を正確にこの計算にnorm使用できます。は関数の名前であるサバイバル関数の略です。logsfsf1 - cdf(x)

例えば、

In [25]: import numpy as np

In [26]: from scipy.stats import norm, gamma

次に例を示しnorm.logsfます。

In [27]: norm.logsf(3, loc=1, scale=1.5)
Out[27]: -2.3945773661586434

In [28]: np.log(1 - norm.cdf(3, loc=1, scale=1.5))
Out[28]: -2.3945773661586434

そして、ここに例がありgamma.logsfます:

In [29]: gamma.logsf(1.2345, a=2, scale=1.8)
Out[29]: -0.16357333194167956

In [30]: np.log(1 - gamma.cdf(1.2345, a=2, scale=1.8))
Out[30]: -0.16357333194167956

logsf(x)これは、の代わりに使用する理由を示していますlog(1 - cdf(x))

In [35]: norm.logsf(50, loc=1, scale=1.5)
Out[35]: -537.96178420294677

In [36]: np.log(1 - norm.cdf(50, loc=1, scale=1.5))
/Users/warren/miniconda3scipy/bin/ipython:1: RuntimeWarning: divide by zero encountered in log
  #!/Users/warren/miniconda3scipy/bin/python
Out[36]: -inf
于 2018-05-11T00:28:41.520 に答える