代码之家  ›  专栏  ›  技术社区  ›  Him

scipy stats binom cdf返回nan

  •  2
  • Him  · 技术社区  · 7 年前

    如果我理解正确 cdf 为了一个 scipy.stats 离散分布应该返回值的概率之和,直到给定的参数。

    scipy.stats.binom(7000000000, 0.5).cdf(6999999999) 应该返回几乎完全为1的值,因为在70亿次试验中,有50/50的机会,在70亿次减去1次或更少的试验中获得成功的概率是非常确定的。相反,我得到了 np.nan . 事实上,对于提供给 .cdf 除了70亿(或更多),我回来了 np.nan公司

    scipy.统计 分发版可以处理文档中没有的内容吗?

    1 回复  |  直到 7 年前
        1
  •  3
  •   zuko3d    7 年前

    热释光;博士

    在内部计算期间缺少浮点精度。尽管scipy是一个Python库,但它的核心是用C编写的,并且使用C数字类型。


    我举个例子:

    import scipy.stats
    
    for i in range (13):
        trials = 10 ** i
        print(f"i: {i}\tprobability: {scipy.stats.binom(trials, 0.5).cdf(trials - 1)}")
    

    i: 0    probability: 0.5
    i: 1    probability: 0.9990234375
    i: 2    probability: 0.9999999999999999
    i: 3    probability: 0.9999999999999999
    i: 4    probability: 0.9999999999999999
    i: 5    probability: 0.9999999999999999
    i: 6    probability: 0.9999999999999999
    i: 7    probability: 0.9999999999999999
    i: 8    probability: 0.9999999999999999
    i: 9    probability: 0.9999999999999999
    i: 10   probability: nan
    i: 11   probability: nan
    i: 12   probability: nan
    

    原因在于二项分布的CDF公式(我不能嵌入图像,所以这里有到wiki的链接: https://en.wikipedia.org/wiki/Binomial_distribution

    在scipy源代码中,我们将看到此实现的参考: http://www.netlib.org/cephes/doubldoc.html#bdtr

    trials ( incbet.c, line 375: ai = 1.0 / a; 这里叫 a ,但nwm)。如果你的 审判 log(0) 未定义,等于 np.nan