当'a'和'b'离平均值太远时,在python和R中截断法线

时间:2014-06-13 12:56:21

标签: python r scipy

尝试获取截断正态分布的pdf时:

from scipy.stats import truncnorm
truncnorm.pdf(-31, np.inf, -30, loc=0, scale=1)

它工作正常。但如果上限与均值相差太远,那么分配给非截断侧(总质量应为1)的样本的概率为NaN:

# -41 is one of the points with highest probability. Why nan?
>truncnorm.pdf(-41, np.inf, -40, loc=0, scale=1)
nan

# 39 is impossible since it lays in the truncated side
>truncnorm.pdf(-39, np.inf, -40, loc=0, scale=1)
0.0

是否因数字预测问题或某些原因而导致错误? 还有另一种方法吗?

更新1 (使用R库“truncnorm”):

这似乎是一个常见问题。与R“truncnorm”库相同的问题:

 > dtruncnorm(-41, a=-Inf, b=-40, mean = 0, sd = 1)
 [1] NaN

更新2 (使用R库“msm”):

在他的博客中,Christian Robert pointed out访问了实现他的paper的“msm”库。

但是,它也会因此情况而崩溃:

> dtnorm(-41, mean = 0, sd=1, lower=-Inf, upper=-40)
[1] NaN

1 个答案:

答案 0 :(得分:3)

truncnorm的计算基于正态分布的cdf。

在尾部到目前为止,无法以浮点(双精度)表示cdf。

>>> stats.norm.cdf(-37)
5.7255712225239266e-300
>>> stats.norm.cdf(-38)
0.0

>>> stats.norm.pdf(-37)
2.120006551524606e-298
>>> stats.norm.pdf(-38)
1.0972210519949712e-314
>>> stats.norm.pdf(-39)
0.0

>>> np.finfo(float).tiny
2.2250738585072014e-308

实现这一目标的唯一方法是直接计算或逼近截断分布,而不是通过正态分布的特殊函数。

我从来没有见过我想要使用它的用例。