Numpy的power函数返回负数

4
我想绘制泊松分布图,并且在 lambda >= 9 时得到负概率。
以下代码可以生成不同 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看起来不错。

enter image description here

Lambda = 9 不是。

enter image description here

我相当确信它与np.power有关,因为。
np.power(11, 9)

给我:-1937019605,而

11**9

给我:2357947691(在WolframAlpha中相同)。
但是如果我避免使用np.power,而使用
y = (lambda_val**k)*math.exp(-lambda_val)/factorial(k)

用于计算概率的时候,我得到了负值。我完全糊涂了。有人能解释一下这个影响或者我做错了什么吗?提前谢谢。 :)

5
没问题。你的系统是32位的吗?一切都对我来说运行良好。 - Quang Hoang
检查 np.finfo(float).bits - 9769953
1个回答

3
您遇到的问题是由于32位整数溢出引起的。这是因为Numpy有时会使用32位整数进行编译,即使平台(操作系统+处理器)是64位的。由于Numpy自动将Python解释器的无限整数转换为本地 np.int_ 类型,所以会发生溢出。您可以使用 np.int_ is np.int64 检查此类型是否为64位。据我所知,Windows上可用的默认Numpy二进制包在Python Pip上使用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.int_k,这肯定是导致你遇到相同问题的原因。希望你可以告诉Numpy这个整数应该更大一些。请注意,Numpy有一些隐式规则来避免溢出问题,但在所有情况下都避免它们会严重影响性能。这是一个修正后的公式:
k = np.arange(0, 20, dtype=np.int64)
y = np.power(lambda_val, k) * np.exp(-lambda_val) / factorial(k)

在处理意外结果时,原则上要非常小心隐式转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接