Numpy如何从非均匀分布中抽样随机数?

4
我是一位有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我一直在学习随机抽样方法,并且知道Numpy使用Mersenne-Twister生成均匀分布的随机数,那么它是如何将这些随机数转换为非均匀分布的呢?

例如:

np.random.normal(mu,sigma,n)

这里使用何种算法来采样正态分布的数值?谢谢。

可能与当前源代码相关的部分在 https://github.com/numpy/numpy/blob/master/numpy/random/mtrand/randomkit.c#L601。 - 9769953
1个回答

4
您的总体问题太广泛,它可以(而且确实)填满一整本教科书。
话虽如此,生成非均匀随机数的技术通常分为几个常见类别。这些包括:
1. 累积分布函数(CDF)的反变换; 2. 卷积(随机变量之和本身是具有不同分布的随机变量); 3. 组合(使用条件概率将复杂分布分解成更简单的部分); 4. 接受/拒绝技术(生成随机“猜测”,如果目标分布的限制条件被违反,则拒绝并重试);以及 5. “特殊关系”(认识到某些分布与其他易于生成的分布存在密切关系)。
1-3和5各有一个简单的例子可以在此教程论文的第4.3节中找到。
在实践中,通常使用这些技术的组合。
例如,正态分布无法通过反演解析地找到,因为这需要能够为累积分布函数编写一个封闭形式的方程。生成正态分布的两个流行变体以极坐标中的正态分布对进行研究,即表示为方向和距离。基本的Box-Muller算法指出,方向在0到2π之间是均匀的,而勾股定理告诉我们距离基于平方正态分布之和,其具有chi-square(2)分布(卷积)。"特殊关系"告诉我们,chi-square(2)是指数(2),可以通过反演轻松生成。将所有部分组合起来并转换回笛卡尔坐标系,即可得到Wikipedia文章中发现的一对公式。
第二种变体是 Marsaglia的极坐标法, 这似乎是NumPy使用的方法。它通过在一个正方形内随机生成点,并拒绝任何不包含在外接圆内的点(接受/拒绝),避免了正弦/余弦超越函数的计算。然后,它使用相同的卡方/指数距离计算来缩放结果,因此也利用了卷积、"特殊关系"和反演。
最快的方法基于ziggurat算法,它将正态分布分成层(组合),对某些层使用特殊关系,并使用接受/拒绝来处理层的尾部。

2
问题不一定是有哪些算法可以生成正态分布的随机数,而是NumPy用了什么算法来生成这样的数字。虽然由于向后兼容性,NumPy的numpy.random.normal算法多年来没有改变,但在未来可能不会是这种情况(请参见新的Numpy RNG策略)。 - Peter O.
1
@PeterO。重点是NumPy必须使用一种或多种基本技术,对于正态分布,它使用Marsaglia的极坐标法(如答案中所述)。问题明确要求“...然后如何传递这些以生成非均匀分布?”并列出正态分布作为“例如”。我理解为想要了解涉及的技术。如果不是这样,那么没有单一的答案可以涵盖NumPy提供的整个随机变量生成套件,您最好查看所有随机变量的源代码。这对于SO来说是一个过于广泛的问题。 - pjs
重新阅读问题,我发现它适用于NumPy支持的所有“非均匀分布”,而不仅仅是正态分布。在这种情况下,NumPy源代码是记录它们的最佳方式。 - Peter O.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接