我使用np.random.choice来进行无替换抽样。
我希望下面的代码在50%的时间里选择0,在30%的时间里选择1,在20%的时间里选择2。
import numpy as np
draws = []
for _ in range(10000):
draw = np.random.choice(3, size=2, replace=False, p=[0.5, 0.3, 0.2])
draws.append(draw)
result = np.r_[draws]
如何正确选择np.random.choice
的参数以给予所需的结果?
我想要的数字代表事件被画在第一或第二位置的概率。
print(np.any(result==0, axis=1).mean()) # 0.83, want 0.8
print(np.any(result==1, axis=1).mean()) # 0.68, want 0.7
print(np.any(result==2, axis=1).mean()) # 0.47, want 0.5
1条答案
按热度按时间iezvtpos1#
我对这个问题给出了两种解释,一种是我更喜欢的("永恒的"),另一种是我认为技术上有效但较差的("天真的")。
永恒:
给定概率
x, y, z
,该方法计算x', y', z'
,使得如果我们独立地绘制两次并丢弃所有相等的对,则0, 1, 2
的频率为x, y, z
。这在两次试验中给出了正确的总频率,并且在第一次和第二次试验等同的意义上具有简单和无时间限制的附加益处。
为了保持这种状态我们必须
如果我们把其中两个加起来,减去第三个,我们得到
乘以其中的2,然后除以第三个
因此直到一个常数因子
因为我们知道
x', y', z'
必须和为1,这就足以求解了。但是:我们实际上不需要完全解出
x', y', z'
,因为我们只对不相等的两个概率对感兴趣,所以我们只需要条件概率x'y' / (x'y' + x'z' + y'z')
、x'z' / (x'y' + x'z' + y'z')
和y'z' / (x'y' + x'z' + y'z')
,这些可以用公式(2)计算。然后,我们将它们各减半,得到有序对的概率,并从具有这些概率的六个合法对中抽取。
幼稚:
这是基于(在我看来是任意的)假设,即在第一次以概率
x', y', z'
抽奖之后,如果第一次是0
,第二次必须具有条件概率0, y' / (y'+z'), z' / (y'+z')
,如果第一次是1
,第二次必须具有条件概率x' / (x'+z'), 0, z' / (x'+z')
,如果第一次是2
,第二次必须具有条件概率x' / (x'+y'), y' / (x'+y'), 0)
。这有一个缺点,据我所知,没有简单的,封闭式的解决方案和第二次和第一次提请是非常不同的。
优点是可以直接使用
np.random.choice
;然而,这是如此之慢,以至于在下面的实现中我给出了一个避免这个函数的解决方案。经过一些代数运算后,我们发现:
其中
c = 1/x' + 1/y' + 1/z' - 1
,我只能用数值解出来。实施和结果:
这是它的实现。
输出示例: