【问题标题】:Is the numpy random generator biased?numpy 随机生成器有偏差吗?
【发布时间】:2018-12-31 20:49:06
【问题描述】:

如果不同的元素应该有不同的概率,numpy.random.choice 方法可以生成一个随机样本而无需替换。但是,当我用

测试它时
import numpy

a = [0, 1, 2, 3, 4, 5]
p = [0.1, 0.3, 0.3, 0.1, 0.1, 0.1]
result = [0, 0, 0, 0, 0, 0]
N = 1000000
k = 3

for i in range(0, N):
    temp = numpy.random.choice(a, k, False, p)
    for j in temp:
        result[j] += 1
for i in range(0, 6):
    result[i] /= (N * k)
print(result)

第二个和第三个元素只出现了 25% 的时间,相差很多。我尝试了不同的概率分布(例如,[0.1, 0.2, 0.3, 0.1, 0.1, 0.2]),每次结果都不符合预期。我的代码有问题还是 numpy 真的那么不准确?

【问题讨论】:

  • replace=True 函数使用replace=True 选项。
  • 看看sorted(np.random.choice(list(range(10)), 10, replace=False))。它将永远是[0,1,2,3,4,5,6,7,8,9]。将False 更改为True 和/或将第二个10 更改为11 以获得更多洞察力。

标签: python numpy random


【解决方案1】:

你对np.random.choice函数的理解是错误的。特别是replace= 选项。 documentation 表示replace=False 表示一旦选择了一个项目,就不能再次选择它。这可以通过运行来显示

for _ in range(100):
    assert set(np.random.choice(np.arange(5), 5, replace=False)) == set(range(5))

并没有看到任何错误。顺序发生变化,但必须返回所有 5 个值。

由于此属性,您当前的方法会给出奇怪的结果。尽管 1 和 2 有 0.3 的机会作为第一个项目出现,但它们作为第二个或第三个项目出现的机会却小于 0.3,因为如果它们是第一个项目,它们就不可能是后面的项目。

解决方案显然是像这样使用replace=True(或者忽略,True是默认的):

import numpy as np

a = [0, 1, 2, 3, 4, 5]
p = [0.1, 0.3, 0.3, 0.1, 0.1, 0.1]
n = 100_000

choices = np.random.choice(a, n, p=p)
values, counts = np.unique(choices, return_counts=True)
result = dict(zip(values, counts / n))

# result == {0: 0.10063, 1: 0.30018, 2: 0.30003, 3: 0.09916, 4: 0.10109, 5: 0.09891}

【讨论】:

  • 一个很好的答案 - 但请注意,您指向 numpy 文档的链接不会指向正确的位置(以及帖子开头的“你是”而不是“你的”)跨度>