0

我使用 scipy integration.quad 来计算正态分布的 cdf:

def nor(delta, mu, x):
    return 1 / (math.sqrt(2 * math.pi) * delta) * np.exp(-np.square(x - mu) / (2 * np.square(delta)))


delta = 0.1
mu = 0
t = np.arange(4.0, 10.0, 1)
nor_int = lambda t: integrate.quad(lambda x: nor(delta, mu, x), -np.inf, t)
nor_int_vec = np.vectorize(nor_int)

s = nor_int_vec(t)
for i in zip(s[0],s[1]): 
    print i

虽然它打印如下:

(1.0000000000000002, 1.2506543424265854e-08)
(1.9563704110140217e-11, 3.5403445591955275e-11)
(1.0000000000001916, 1.2616577562700088e-08)
(1.0842532749783998e-34, 1.9621183122960244e-34)
(4.234531567162006e-09, 7.753407284370446e-09)
(1.0000000000001334, 1.757986959115912e-10)

对于某些 x,它返回一个近似为零的值,它应该返回 1。有人可以告诉我出了什么问题吗?

4

1 回答 1

1

为什么以非常小的方差对简单的高斯 pdf 积分时 quad 返回两个零的原因相同?但看到我不能将它标记为重复,这里是:

您正在一个非常大的(实际上是无限的)间隔内集成一个具有紧密定位(在比例增量上)的函数。积分例程可以简单地忽略函数与 0 有很大不同的区间部分,而将其判断为 0。需要一些指导。该参数points可用于此效果(请参阅链接的问题),但由于quad无限区间不支持它,因此必须手动拆分区间,如下所示:

for t in range(4, 10):
    int1 = integrate.quad(lambda x: nor(delta, mu, x), -np.inf, mu - 10*delta)[0] 
    int2 = integrate.quad(lambda x: nor(delta, mu, x), mu - 10*delta, t)[0] 
    print(int1 + int2)

每次打印 1 个或接近 1 个。我选择mu-10*delta了一个拆分点,认为大多数函数都位于它的右侧,无论 mu 和 delta 是什么。

笔记:

  1. 使用np.sqrt等;通常没有理由math在 NumPy 代码中放置函数。NumPy 版本可用并且是矢量化的。
  2. 除了使代码更长且更难阅读之外,申请np.vectorize并没有做任何事情。quad使用普通的 Python 循环或列表推导。请参阅带有集成的 NumPy 矢量化
于 2018-06-27T01:04:42.313 回答