我想画出泊松分布,得到λ的负概率
此代码为不同的lambda生成绘图:
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import factorial
for lambda_val in range(1, 12, 2):
plt.figure()
k = np.arange(0,20)
y = np.power(lambda_val, k)*np.exp(-lambda_val)/factorial(k)
plt.bar(k, y)
plt.title('lambda = ' + str(lambda_val))
plt.xlabel('k')
plt.ylabel('probability')
plt.ylim([-0.1, 0.4])
plt.grid()
plt.show()
请看这两幅图:
在我看来,Lambda=5看起来不错。
λ=9,不适用。
我很确定这和np.power有关因为
np.power(11, 9)
给我:-1937019605,而
11**9
给我:2357947691(WolframAlpha也一样)。
但是如果我避免np。权力与使用
y = (lambda_val**k)*math.exp(-lambda_val)/factorial(k)
为了计算概率,我也得到负值。我完全糊涂了。谁能解释一下效果或者我做错了什么?提前感谢。:)
您的问题是由于32位整数溢出造成的。发生这种情况是因为Numpy有时编译为32位整数,即使平台(操作系统处理器)是64位的。存在溢出,因为Numpy自动将Python解释器的无界整数转换为本机np.int_
类型。您可以使用检查此类型是否为64位类型np.int_np.int64
。AFAIK,Python Pip上为Windows编译的默认Numpy二进制包使用32位整数,Linux包使用64位整数(假设您在64位平台上)。
该问题可以通过以下方式轻松复制:
In [546]: np.power(np.int32(11), np.int32(9))
Out[546]: -1937019605
它也可以解决使用:
In [547]: np.power(np.int64(11), np.int64(9))
Out[547]: 2357947691
在第二个表达式中,使用类型为np的
k
。默认情况下,这就是为什么会出现相同问题的原因。希望您可以向Numpy指定整数应该更大。请注意,Numpy有一些隐式规则来避免溢出,但在所有情况下都很难避免它们,而不会严重影响性能。这里有一个固定的公式:
k = np.arange(0, 20, dtype=np.int64)
y = np.power(lambda_val, k) * np.exp(-lambda_val) / factorial(k)
经验法则是在得到意外结果时要非常小心隐式转换。