我如何在这里使用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]
通常和p不完全等于1:
>>> sum(p)
1.0000000017347
我想通过概率= p:
进行随机选择>>> np.random.choice([1,2,3,4,5,6,7,8,9, 10], 4, p=p, replace=False)
array([4, 3, 2, 9])
这个工作在这里!但在程序中它有一个错误:
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
如果我打印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]
但它可以在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])
更新 我已经通过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]
测试:
>>> 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
如何修复此问题以使用np.random.choice?
答案 0 :(得分:7)
这是一个带有numpy的known issue。随机选择函数使用给定的容差(here the source)
检查概率的总和解决方案是通过将概率除以它们的总和来归一化概率,如果总和足够接近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
规范化:
>>> 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])
答案 1 :(得分:2)
将其转换为 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)
这是受到另一篇文章的启发:How can I avoid value errors when using numpy.random.multinomial?
答案 2 :(得分:1)
看待差异的一种方法是:
numpy.set_printoptions(precision=15)
print(p)
这可能会告诉您4.17187500e-05
实际上是4.17187500005e-05
。请参阅the manual here。
答案 3 :(得分:0)
ValueError:概率不等于1
这是一个已知的numpy错误。当numpy无法足够精确地处理浮点运算时,就会发生此错误。有时,概率总和约为0.9999999999997或1.0000000000003。他们会破坏np.random.choice()。
有一种解决方法:np.random.multinomial()。这种方法可以更精确地处理概率,而不必精确地是1.0。
pvals:浮点序列,长度为p每个p的概率 不同的结果。这些总和应为1(但是,最后一个元素 只要假设,只要 sum(pvals [:-1])<= 1)。
例如,我有一些选择,并且与这些选择相关联的normalized_weights。
np.random.multinomial()根据normalized_weights选择20次,并返回选择每个选择的次数。
choices = [......]
weights = np.array([......])
normalized_weights = weights / np.sum(weights)
number_of_choices = 20
resample_counts = np.random.multinomial(number_of_choices,
normalized_weights)
chosen = []
resample_index = 0
for resample_count in resample_counts:
for _ in range(resample_count):
chosen.append(choices[resample_index])
resample_index += 1