我有一个非常直截了当的问题。我的目标是生成一组具有正态分布 ( mu = 0
, sigma = 1
) 的随机数。
现在,处理上述高斯钟的最佳方法是生成大量样本。
不幸的是,就我而言,我只能生成保留的样本子集:通常围绕2048
样本,这会导致拟合不佳。
我实际上想知道是否有任何方法可以提高适应度,首先生成更大的样本集或相同大小的更多子集(作为 2048 样本的 10 倍),然后选择那些最接近所需平均值和标准的 2048偏差(当然还有高斯)。
您会提出什么建议或如何进行?
我有一个非常直截了当的问题。我的目标是生成一组具有正态分布 ( mu = 0
, sigma = 1
) 的随机数。
现在,处理上述高斯钟的最佳方法是生成大量样本。
不幸的是,就我而言,我只能生成保留的样本子集:通常围绕2048
样本,这会导致拟合不佳。
我实际上想知道是否有任何方法可以提高适应度,首先生成更大的样本集或相同大小的更多子集(作为 2048 样本的 10 倍),然后选择那些最接近所需平均值和标准的 2048偏差(当然还有高斯)。
您会提出什么建议或如何进行?
详细说明 Dilip 的答案(这是完全正确的,尽管在实践中Ziggurat 方法的计算效率比 Box-Mueller 高得多):
你的推理中缺少的一个关键因素是你是否希望你的样本是独立的。从您的问题中不清楚,但这是最常见的情况......
如果您希望您的样本是独立的,那么您将不得不接受它们的经验均值和方差不会完全为 0 和 1 - 众所周知,样本越大,经验值越接近 0、1 - 这绝对没问题 - 这是正态分布的“特征”而不是“错误”。尝试选择看起来更“随机”或“表现良好”的样本是个坏主意;因为这个选择过程使它们变得不那么随机了!例如,如果你想出一个过程总是产生 2048 个样本块,其中和,这意味着在您的生成过程中只有 2046 个可能的自由度,因此您的样本不是独立的(给定 2046 个第一个样本,您可以使用和 equation...所以这最后两个值不是随机的!)。
Dilip 和 pichenettes 已经指出了两种生成高斯随机变量的方法(Box-Muller 变换和Ziggurat 算法)。为了完整起见,我将指出另一个:逆变换采样。我最近需要创建一个最大吞吐量的软件高斯随机数生成器,在评估了我能找到的所有方法之后,我选择了这个,因为它被证明是目标系统上最快的。
逆变换采样的想法是,您从一个基本随机生成器开始,该生成器在某个区间内产生均匀的值,通常是(或者区间在任一端是开还是闭的一些变化)。然后,您将这些统一值应用于选择的函数,以使结果输出具有所需的分布。这种技术的设置如下:
选择要从中生成随机数的分布。确定其累积分布函数 (cdf) . 对于高斯分布,此函数为:
反转分布的 CDF 以产生其逆 CDF,有时称为分位数函数。这通常很难或不可能以紧凑的分析形式完成,因此您可能需要依赖数值近似。对于标准高斯分布,这是概率函数,可以从上面的 cdf 表达式中获得:
如果您的计算环境具有逆误差函数的实现,那么这应该很容易评估。否则,您将需要依赖函数的一些数值近似。
有了上述信息,您现在可以从所需的分布中生成值。简单的程序如下:
生成统一值在区间.
计算.
输出.
假设您有一个良好的基础统一生成器(以及逆 CDF 函数的良好实现),则生成的样本为应该非常接近于期望的分布。这种技术有几个好处:
它很笼统;虽然我在上面谈到了高斯随机数生成,但您可以通过更改用于逆 CDF 的函数来成功地将其用于许多分布。
如果你有一个逆 CDF 函数的简单实现,它可以非常快(尽管统一生成器的速度很重要)。通过使用不使用任何逻辑检查或分支的逆 CDF 近似,我能够从这种方法中挤出比 Ziggurat 算法更快的速度。
Box Müller 大多是好的,但不一定优于逆 CDF,因为它受到 Neave 效应的影响,请参阅 HR Neave,On using the Box-Muller transformation with multiplicative congruential pseudorandom number generators Applied Statistics, 22, 92-97, 1973,或手冢https://www.researchgate.net/publication/3528180_NEAVE_EFFECT_ALSO_OCCURS_WITH_TAUSWORTHE_SEQUENCES
这个堆栈溢出帖子是相关的https://stackoverflow.com/questions/2325472/generate-random-numbers-following-a-normal-distribution-in-cc