如何避免 numpy.random.choice 中的舍入错误?

Fır*_*yak 4 python random floating-point numpy floating-accuracy

假设 x_1, x_2, ..., x_n 是 n 个对象,并且想要选择其中一个,以便选择 x_i 的概率与某个数字 u_i 成正比。Numpy 为此提供了一个函数:

x, u = np.array([x_1, x_2, ..., x_n]), np.array([u_1, ..., u_n])
np.random.choice(x, p = u/np.sum(u))
Run Code Online (Sandbox Code Playgroud)

然而,我观察到这段代码有时会抛出一个 ValueError ,指出“概率之和不等于 1”。这可能是由于有限精度算术的舍入误差造成的。应该怎么做才能让这个功能正常工作呢?

Fır*_*yak 5

在阅读了 @Pychopath 指出的问题的答案/sf/answers/4227049921/后,我找到了以下解决方案,灵感来自 numpy.random.multinomial https://docs.scipy 的文档。 org/doc/numpy-1.15.0/reference/ generated/numpy.random.multinomial.html

Sayp是概率数组,1即使我们用 对其进行归一化,也可能不完全是由于舍入误差所致p = p/np.sum(p)。这种情况并不罕见,请参阅 @pd shah 在答案中的评论/sf/answers/3257794501/

做就是了

p[-1] = 1 - np.sum(p[0:-1])
np.random.choice(x, p = p)
Run Code Online (Sandbox Code Playgroud)

问题就解决了!减法引起的舍入误差将比归一化引起的舍入误差小得多。此外,我们不必担心 p 的变化,它们是舍入误差的量级。