我有两种方法可以推导出一个正常分布的随机变量在一个区间内的概率。第一次也是最直截了当的是:
import scipy.stats
print scipy.stats.norm.cdf(6) - scipy.stats.norm.cdf(5)
# 2.85664984223e-07
第二种方法是集成pdf。
import scipy.integrate
print scipy.integrate.quad(scipy.stats.norm.pdf, 5, 6)[0]
# 2.85664984234e-07
在这种情况下,差别确实很小,但这并不意味着对于其他发行版或集成限制,它不能变得更大。你能分辨出哪个更准确,为什么?
顺便说一句,第一种选择似乎至少快了10倍,所以如果它也更准确(我猜,因为它有点专门),那么它就完美了。
发布于 2014-06-11 14:08:11
在这种特殊情况下,给定这些特定的数字,quad
方法实际上会更精确。当然,可以快速而准确地计算民防基金本身,但看看实际数字:
>>> scipy.stats.norm.cdf(6), scipy.stats.norm.cdf(5)
(0.9999999990134123, 0.99999971334842808)
当你把两个非常相似的量相差无几时,你就失去了准确性。在集成过程中,如果编码者对其求和非常小心的话,类似的问题可以得到一定程度的缓解。
无论如何,我们可以通过使用mpmath
进行高分辨率的计算来检查这一点。
>>> via_cdf = scipy.stats.norm.cdf(6)-scipy.stats.norm.cdf(5)
>>> via_quad = scipy.integrate.quad(scipy.stats.norm.pdf, 5, 6)[0]
>>> import mpmath
>>> mpmath.mp.dps = 100
>>> def cdf(x): return 0.5 * (1 + mpmath.erf(x/mpmath.sqrt(2)))
>>> highres = cdf(6)-cdf(5)
>>> highres
mpf('0.0000002856649842341562135330514687422473118357532223619105443630157837185833042478210791954518847897468442097')
>>> float((highres - via_quad)/highres)
-2.3824773334590333e-16
>>> float((highres - via_cdf)/highres)
3.86659439572868e-11
https://stackoverflow.com/questions/24164482
复制相似问题