将均匀分布转换为正态分布

时间:2020-03-05 18:56:50  来源:igfitidea点击:

如何将均匀分布(如大多数随机数生成器产生的,例如0.0到1.0之间)转换为正态分布?如果我想要选择均值和标准差怎么办?

解决方案

回答

Ziggurat算法对此非常有效,尽管Box-Muller变换更容易从头开始实现(而不是疯狂慢)。

回答

我会使用Box-Muller。关于此的两件事:

  • 每次迭代最终得到两个值通常,我们缓存一个值,然后返回另一个值。在下一次调用样本时,我们将返回缓存的值。
  • Box-Muller提供Z分数然后,我们必须按标准偏差缩放Z分数,并添加均值以获得正态分布的完整值。

回答

标准的Python库模块random具有我们想要的:

normalvariate(mu, sigma)

  Normal distribution. mu is the mean, and sigma is the standard deviation.

对于算法本身,请查看Python库中random.py中的函数。

手动输入在这里

回答

function distRandom(){
  do{
    x=random(DISTRIBUTION_DOMAIN);
  }while(random(DISTRIBUTION_RANGE)>=distributionFunction(x));
  return x;
}

回答

将任何函数的分布更改为另一个函数都涉及使用所需函数的逆函数。

换句话说,如果我们针对特定的概率函数p(x),则可以通过对其积分-> d(x)=积分(p(x))并使用其反函数来获得分布:Inv(d(x)) 。现在使用随机概率函数(具有均匀分布)并通过函数Inv(d(x))转换结果值。我们应该根据选择的功能获得带有分布的随机值。

这是通用的数学方法,通过使用它,我们现在可以选择具有逆或者良好逆近似的任何概率或者分布函数。

希望这对我们有所帮助,并感谢我们对使用分布的简短评论,而不是概率本身。

回答

使用中央极限定理Wikipedia条目mathworld条目可发挥优势。

生成n个均匀分布的数字,将它们相加,减去n * 0.5,我们将得到近似正态分布的输出,均值等于0,方差等于(1/12)*(1 / sqrt(N))(请参阅维基百科,关于最后一个的均匀分布)

n = 10可以使我们快得快一半。如果我们想要的东西超过一半的话,请寻求泰勒解决方案(正态分布在Wikipedia条目中已指出)

回答

这是使用Box-Muller变换的极坐标形式的javascript实现。

/*
 * Returns member of set with a given mean and standard deviation
 * mean: mean
 * standard deviation: std_dev 
 */
function createMemberInNormalDistribution(mean,std_dev){
    return mean + (gaussRandom()*std_dev);
}

/*
 * Returns random number in normal distribution centering on 0.
 * ~95% of numbers returned should fall between -2 and 2
 * ie within two standard deviations
 */
function gaussRandom() {
    var u = 2*Math.random()-1;
    var v = 2*Math.random()-1;
    var r = u*u + v*v;
    /*if outside interval [0,1] start over*/
    if(r == 0 || r >= 1) return gaussRandom();

    var c = Math.sqrt(-2*Math.log(r)/r);
    return u*c;

    /* todo: optimize this algorithm by caching (v*c) 
     * and returning next time gaussRandom() is called.
     * left out for simplicity */
}

回答

有很多方法:

  • 请勿使用Box Muller。特别是当我们绘制许多高斯数时。 Box Muller得出的结果被限制在-6和6之间(假设双精度,浮点会使情况变得更糟)。而且它的效率确实比其他可用方法低。
  • Ziggurat很好,但需要进行表查找(由于缓存大小问题,需要进行一些特定于平台的调整)
  • 均匀率是我的最爱,只有几次加法/乘法和对数的1/50(例如,看那里)。
  • 反转CDF是高效的(并且被忽略了,为什么?),如果我们搜索google,就可以快速实现它。准随机数是必需的。