np.random.choice:概率不等于1

pd *_*hah 6 python numpy

如何在这里使用np.random.choice? 可以p通过一些操作来计算,例如:

 p=[  1.42836755e-01,   1.42836735e-01  , 1.42836735e-01,   1.42836735e-01
,   4.76122449e-05,   1.42836735e-01  , 4.76122449e-05  , 1.42836735e-01,
   1.42836735e-01,   4.76122449e-05]
Run Code Online (Sandbox Code Playgroud)

通常,和p不精确等于1:

>>> sum(p)
1.0000000017347
Run Code Online (Sandbox Code Playgroud)

我想通过概率= p来随机选择:

>>> np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
array([4, 3, 2, 9])
Run Code Online (Sandbox Code Playgroud)

这项工作在这里!但是在程序中有一个错误:

Traceback (most recent call last):
    indexs=np.random.choice(range(len(population)), population_number, p=p, replace=False)
  File "mtrand.pyx", line 1141, in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:17808)
ValueError: probabilities do not sum to 1
Run Code Online (Sandbox Code Playgroud)

如果我打印p

[  4.17187500e-05   2.49937500e-01   4.16562500e-05   4.16562500e-05
   2.49937500e-01   4.16562500e-05   4.16562500e-05   4.16562500e-05
   2.49937500e-01   2.49937500e-01]
Run Code Online (Sandbox Code Playgroud)

但是它可以通过以下方式在python shell中工作p

>>> p=[  4.17187500e-05 ,  2.49937500e-01   ,4.16562500e-05  , 4.16562500e-05,
   2.49937500e-01  , 4.16562500e-05  , 4.16562500e-05  , 4.16562500e-05,
   2.49937500e-01   ,2.49937500e-01]
>>> np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
array([ 9, 10,  2,  5])
Run Code Online (Sandbox Code Playgroud)

更新 我已经通过precision = 15测试了它:

 np.set_printoptions(precision=15)
 print(p)
[  2.499375625000002e-01   2.499375000000000e-01   2.499375000000000e-01
   4.165625000000000e-05   4.165625000000000e-05   4.165625000000000e-05
   4.165625000000000e-05   4.165625000000000e-05   2.499375000000000e-01
   4.165625000000000e-05]
Run Code Online (Sandbox Code Playgroud)

测试:

>>> p=np.array([  2.499375625000002e-01   ,2.499375000000000e-01   ,2.499375000000000e-01,
   4.165625000000000e-05   ,4.165625000000000e-05,   4.165625000000000e-05,
   4.165625000000000e-05  , 4.165625000000000e-05 ,  2.499375000000000e-01,
   4.165625000000000e-05])
>>> np.sum(p)
1.0000000000000002
Run Code Online (Sandbox Code Playgroud)

如何解决此问题以使用np.random.choice?

Soi*_*oid 17

将其转换为 float64:

p = np.asarray(p).astype('float64')
p = p / np.sum(p)
np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
Run Code Online (Sandbox Code Playgroud)

这是受到另一篇文章的启发:How can I避免值错误时使用numpy.random.multinomial?

  • IMO 这应该有更多的选票。当我的 p = [1,1,1] 时,所有答案都不适用于我的情况,而这个答案却适用。谢谢你! (2认同)

use*_*737 12

这是numpy 的已知问题。随机选择函数使用给定的公差检查概率之和(此处为源

解决方案是,如果总和足够接近1,则将它们除以总和来归一化概率

例:

>>> p=[  1.42836755e-01,   1.42836735e-01  , 1.42836735e-01,   1.42836735e-01
,   4.76122449e-05,   1.42836735e-01  , 4.76122449e-05  , 1.42836735e-01,
   1.42836735e-01,   4.79122449e-05]
>>> sum(p) 
1.0000003017347 # over tolerance limit
>>> np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)

Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
  File "mtrand.pyx", line 1417, in mtrand.RandomState.choice (numpy\random\mtrand\mtrand.c:15985)
ValueError: probabilities do not sum to 1
Run Code Online (Sandbox Code Playgroud)

使用归一化:

>>> p = np.array(p)
>>> p /= p.sum()  # normalize
>>> np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
array([8, 4, 1, 6])
Run Code Online (Sandbox Code Playgroud)

  • thx 但不工作。ValueError:概率总和不为 1。怎么办? (2认同)

小智 5

\n

ValueError:概率之和不等于 1

\n
\n\n

这是一个已知的 numpy bug。当 numpy 可以\xe2\x80\x99t 足够精确地处理浮点运算时,会发生此错误。有时,概率之和约为 0.9999999999997 或 1.0000000000003。他们会破坏 np.random.choice()。

\n\n

有一个解决方法:np.random.multinomial()。此方法可以更优雅地处理概率,而无需恰好为 1.0。

\n\n
\n

pvals :浮点序列,长度 p 每个 p\n 不同结果的概率。这些总和应为 1(但是,只要 sum(pvals[:-1]) <= 1,总是假定最后一个元素\n 解释了剩余概率)。

\n
\n\n

例如,我有一些选择和与这些选择相关的标准化权重。

\n\n

np.random.multinomial() 根据 normalized_weights 选择 20 次,并返回每个选项被选择的次数。

\n\n
choices = [......]\nweights = np.array([......])\nnormalized_weights = weights / np.sum(weights)\n\nnumber_of_choices = 20\nresample_counts = np.random.multinomial(number_of_choices,\n                                        normalized_weights)\n\nchosen = []\nresample_index = 0\nfor resample_count in resample_counts:\n    for _ in range(resample_count):\n        chosen.append(choices[resample_index])\n    resample_index += 1\n
Run Code Online (Sandbox Code Playgroud)\n