Skip to main content
 首页 » 编程设计

python之scipy.stats 中 cdf 的精度

2025年05月04日12unruledboy

我正在使用 chi2分布作为模拟系统的理论问题。

对于给定的区间,我需要将此分布估计为 PMF,定义为该区间内 PDF 的积分。该值应接近区间中心 PDF 的值,但可能略有不同,具体取决于 PDF 的形状。

这是我的做法:

import numpy 
from scipy.stats import chi2 
 
dist = chi2(10) 
nbins = 120 
 
F = dist.cdf(numpy.arange(nbins+1)) 
pmf = F[1:] - F[:-1] # surface inside the interval 
pmf /= pmf.sum() # Normalisation 

问题是 chi2.cdf(100, 10) 及以上给出的恰好是 1.0。所以我能得到的最小值大约是 1.11e-16。但是 chi2.pdf(100, 10) 不完全是 0(大约是 2.5e-17)。

我的问题是:如何更精确地估算 pmf(可能高达 1e-25)?为什么 cdf 函数不如 pdf 函数精确?

请您参考如下方法:

cdf 在等于 1 的浮点精度内,但 sf 接近于零,因此微小差异 1e-20 不会被大 1 掩盖。(参见 JABS 引用资料)

>>> probs_from_cdf = np.diff(stats.chi2.cdf(np.arange(nbins+1), 10)) 
>>> probs_from_sf = np.diff(stats.chi2.sf(np.arange(nbins+1)[::-1], 10))[::-1] 
>>> probs_from_sf[:4] 
array([ 0.00017212,  0.00348773,  0.01491609,  0.03407708]) 
>>> probs_from_cdf[:4] 
array([ 0.00017212,  0.00348773,  0.01491609,  0.03407708]) 
>>> probs_from_cdf[-5:] 
array([ 0.,  0.,  0.,  0.,  0.]) 
>>> probs_from_sf[-5:] 
array([  1.94252577e-20,   1.21955220e-20,   7.65430774e-21, 
         4.80270079e-21,   3.01259913e-21]) 

我不知道 sf 的准确范围,即 scipy.special.chdtrc(df, x) 有多远