我使用 scipy integrate.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。 有人可以告诉我出了什么问题吗?
与为什么四边形在以非常小的差异集成一个简单的高斯 pdf 时返回两个零的原因相同? 但是看到我无法将其标记为重复项,
因此:您正在以非常大(实际上是无限的(间隔集成具有严格定位(在尺度增量(的函数。积分例程可以简单地错过函数与 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 是什么。
笔记:
- 使用
np.sqrt
等;通常没有理由在NumPy代码中放置math
函数。NumPy版本可用,并且是矢量化的。 - 将
np.vectorize
应用于quad
除了使代码更长且更难阅读之外,没有任何作用。使用正常的 Python 循环或列表理解。请参阅带集成的 NumPy 矢量化