scipy.stats cdf 大于 1

问题描述

我正在使用 scipy.stats,对于某些分布,我需要达到给定值 x 的 CDF,我知道 PDF 可以大于 1,因为它们不是概率而是密度,因此即使特定值,它们也应该集成为 1更大,但 CDF 永远不应大于 1,并且在 scipy.stats 上运行 cdf 函数时,有时我会得到类似 2.89 的值,我完全确定我使用的是 cdf 而不是 pdf(这是我的第一个猜测),这因为我需要累积概率,所以弄乱了我的结果和算法,为什么 scipy.stats cdf 返回的值大于 1 和/或我应该如何解决它?

使用样本分布和参数重现问题的代码(但其他人也会发生):

from scipy import stats
distribution = stats.gausshyper
params = [9.482986347673158,16.65813644507513,-38.11083665959626,16.08698932118982,-13.387170754433273,18.352117022674125]
test_val = [-0.512720,1,1]

arg = params[:-2]
loc = params[-2]
scale = params[-1]

print("cdf:",distribution.cdf(test_val,*arg,loc=loc,scale=scale))
print("pdf:",distribution.pdf(test_val,scale=scale))

cdf:[2.68047481 7.2027761 7.2027761] pdf: [2.76857133 2.23996739 2.23996739]

解决方法

问题在于您为高斯超几何 (HG) 分布指定的参数,特别是 params 的第三个元素,即 HG 分布中的参数 beta(参见 {{ 3}} 为高斯超几何分布密度的定义)。此参数必须为正值才能使 HG 具有有效的密度。否则,密度不会整合为 1,这正是您的示例中发生的情况。对于负 Beta,该分布不是有效的概率分布。

您还可以在 scipy 文档 this paper 中找到 beta(表示为 b)必须为正的要求。 将 beta 更改为正参数可以立即解决您的问题:

from scipy import stats
distribution = stats.gausshyper
params = [9.482986347673158,16.65813644507513,38.11083665959626,16.08698932118982,-13.387170754433273,18.352117022674125]
test_val = [-0.512720,1,1]

arg = params[:-2]
loc = params[-2]
scale = params[-1]

print("cdf:",distribution.cdf(test_val,*arg,loc=loc,scale=scale))
print("pdf:",distribution.pdf(test_val,scale=scale))

输出:

cdf: [1. 1. 1.]
pdf: [3.83898392e-32 1.25685346e-35 1.25685346e-35]

,其中所有 cdf 根据需要集成为 1。另请注意,您的 x 也必须介于 0 和 1 之间,如 scipy 文档 here 中所述。