Random 处理正态(高斯)分布
我基本上是研究了一个相当简单的问题: 掷N枚硬币,发现其中有多少是人头落地的 解决方案性能不能依赖于N,因此我们不能只调用Random 处理正态(高斯)分布,random,normal-distribution,coin-flipping,Random,Normal Distribution,Coin Flipping,我基本上是研究了一个相当简单的问题: 掷N枚硬币,发现其中有多少是人头落地的 解决方案性能不能依赖于N,因此我们不能只调用Math.random()=10,但让我们定义一个更严格的规则 首先,Box-Muller将严格限制在[-6,6],以确保正确的结果(640KB应该…,我的意思是,每个人都应该有6个西格玛) 然后,使用6常数,我们声明,为了让Box-Muller产生有效的结果,Math.sqrt(方差)*6不得超过mean。使用N/2和N/4分别作为mean和variance后,我们得出以下
Math.random()<0.5次。显然,救援行动是高斯分布的
我使用了Box-Muller方法:
function gaussian_random(mean, variance) {
var s;
var x;
var y;
do {
x = Math.random() * 2.0 - 1.0;
y = Math.random() * 2.0 - 1.0;
s = Math.pow(x, 2) + Math.pow(y, 2);
} while ( (s > 1) || (s == 0) );
var gaussian = x * Math.sqrt(-2*Math.log(s)/s);
return mean + gaussian * Math.sqrt(variance);
}
数学上说,N次抛硬币的平均值是N/2
,方差是N/4
然后,我做了一个测试,掷N枚硬币M次,给出了最小、最大和平均人头数
我比较了naive方法(Math.random()
多次)和Gaussian-Box-Muller方法的结果
有测试的典型输出:
Toss 1000 coins, 10000 times
Straight method:
Elapsed time: 127.330 ms
Minimum: 434
Maximum: 558
Average: 500.0306
Box-Muller method:
Elapsed time: 2.575 ms
Minimum: 438.0112461962819
Maximum: 562.9739632480057
Average: 499.96195358695064
Toss 10 coins, 10000 times
Straight method:
Elapsed time: 2.100 ms
Minimum: 0
Maximum: 10
Average: 5.024
Box-Muller method:
Elapsed time: 2.270 ms
Minimum: -1.1728354576573263
Maximum: 11.169478925333504
Average: 5.010078819562535
正如我们在N=1000
上所看到的,它几乎完全适合
但是,在N=10
Box Muller上,他疯了:它允许这样的测试结果,我可以从10次掷硬币中得到11.17个人头(这是非常罕见的,但也是可能的!)
毫无疑问,我做错了什么。但究竟是什么呢
有,并链接到
更新了x2:看来,以前我并没有很好地描述这个问题。它有一个通用版本:
如何在摊余固定时间内获得N均匀随机值(离散或连续)的样本平均值。高斯分布对大的N是有效的,但是有没有办法使它对小的N有效?或者在精确的N上,解决方案应该从高斯方法切换到其他方法(例如直接)
数学上说,N次抛硬币的平均数是N/2,方差是N/4
数学只是说,如果这是一个公平的硬币。解决方案不可能不依赖于N
假设所有投掷都相互独立,对于精确行为,使用二项分布而不是正态分布。二项式有两个参数:N是抛硬币的次数,p是正面(或反面)的概率。在伪代码中
function binomial(n, p) {
counter = 0
successes = 0
while counter < n {
if Math.random() <= p
successes += 1
counter += 1
}
return successes
}
函数二项式(n,p){
计数器=0
成功=0
而计数器 if Math.random()基于中讨论的内容,我得出了这个特定的解决方案
有经验法则n*p>=10和n*(1-p)>=10
,但让我们定义一个更严格的规则
首先,Box-Muller将严格限制在[-6,6],以确保正确的结果(640KB应该…,我的意思是,每个人都应该有6个西格玛)
然后,使用6
常数,我们声明,为了让Box-Muller产生有效的结果,Math.sqrt(方差)*6
不得超过mean
。使用N/2
和N/4
分别作为mean
和variance
后,我们得出以下结论:
Math.sqrt(N) * 6 <= N
N >= 36
Math.sqrt(N)*6=36
当这个条件成立时,我们可以安全地使用盖帽盒-穆勒高斯函数。
对于任何较低的样本量,坚持二项式解决方案
刚刚从统计上检查了这条规则——金额相对较大(1000万)在测试中,最小值不再超出样本量32及以上的范围。我想说,你需要的是一个p=0.5
,而不是高斯分布。如果N足够大,则正态分布是二项分布的合理近似值。但肯定不是N=10
。从Box-Muller的角度来看,这并没有什么疯狂之处。他没有硬币的方式,并给出一个“溢出”基于您提供的参数进行计算。在样本数较低的情况下,此溢出会打破采样边界,因为公式对其一无所知。@StefanZobel事实上,p=0.5
案例计划是第一步;接下来我想解决任何p
和N
的问题。这就是二项分布不存在的原因sn不合适,我在寻求一般解决方案。@SergeyGrinev我知道,Box Muller完全按照它的设计做了。然而,它的使用限制令人惊讶。但是@pjs已经是你的问题了。无论你选择的是p
,二项分布都是正确的。如果p
本身是一个随机变量,那么应该考虑分布。获得答案的最好方法是问你想要答案的实际问题。如果你想得到n个独立分布的实际分布的平均值,它与发生的平均值相同。另一方面,样本平均值A.K.A.平均值与B值相同。ut具有可变性,因此试验将产生不同的结果,但长期平均值将收敛于平均值。如果您希望生成经验试验,但不喜欢O(N),请参阅O(Np)算法。@除非你对高斯分布的假设是错误的,否则这是一个预兆。对于大样本量,高斯分布是二项分布的一个相当好的近似值(如果你希望结果的概率在一个范围内,则称为“连续性校正”).需要多大的样本量?意见不同,但一个合理的经验法则是n*p
和n*(1-p)
都应至少为10,以防止对使用无限范围分布近似有界范围分布的边缘效应产生太大的影响。@augur你问的是“疯狂”你得到的N=10的值。这里有两条评论告诉你,正常值不是N=10的好近似值(假设p=0.5)。现在你说你可以接受(任何?)近似值。你的问题是什么?@augur这被称为“移动目标柱”不酷!正确的做法是发布一个不同的问题。提交给测试示例。