【问题标题】:drawing gaussian random variables using scipy erfinv使用 scipy erfinv 绘制高斯随机变量
【发布时间】:2016-12-09 19:32:45
【问题描述】:

我想绘制 npts 随机变量分布为具有均值 mu 和离散度 sigma 的高斯分布。我知道如何在 Numpy 中做到这一点:

x = np.random.normal(loc=mu, scale=sigma, size=npts)
print(np.std(x), np.mean(x))
0.1998, 0.3997

这也应该可以通过逆变换使用 scipy.special.erfinv 从均匀分布开始:

u = np.random.uniform(0, 1, npts)

但是,我不知道如何正确缩放。以前有人做过吗?

【问题讨论】:

  • 什么是npts?我是否理解正确,您只需要参数化正常分布的样本?如果是这样,为什么不使用 numpy 方法?
  • 我的用例需要从u开始。
  • npts 只是从分布中抽取的次数
  • “我的用例需要从你开始。”你能解释一下你的动机吗?
  • 当然,ali_m。我将使用 x 的百分位数(模型中感兴趣的物理量)作为数组 u。高斯变量是建模量 y 的分布。这样x和y是单调对应的,y是高斯的。

标签: python numpy random scipy scientific-computing


【解决方案1】:

试试这个:

mean = 100
sigma = 7
x = mean + 2**0.5 * sigma * erfinv(np.random.uniform(size=10**5) * 2 - 1)
x.mean(), x.std()
Out: (99.965915366042381, 7.0062395839075107)

erf到正态分布的转换是从John D. Cook's blog.

【讨论】:

  • 完美答案:正是我所需要的,即使对于大型阵列也非常快。
【解决方案2】:

最好的方法可能是自己实现高度优化的高斯采样器,例如:

但这里有一些简单的东西(我很久以前就看到了here)。这将比上述方法效率低(因为它使用分位数函数/百分比点函数,它没有正态分布的封闭形式表示并且将被近似):

import numpy as np
from scipy.stats.distributions import norm

uniform_samples = np.random.rand(100000)
gaussian_samples = norm(loc=0, scale=1).ppf(uniform_samples)

【讨论】:

  • 谢谢萨沙。这是一个有趣的解决方案,但不如透明 erfinv 方法清晰一些,而且对于非常大的数组,速度要慢约 3 倍。
  • @aph 在我看来,这要清楚得多。它只是使用 ppf 函数进行逆变换采样(使用您要从中采样的分布)。我还认为,如果 erfinv 可以通过线性变换来做到这一点,那么它的反函数也不能以封闭形式表示,并且也需要近似(内部)。如果操作正确,上述算法之一在几行代码中实现的速度应该快 100 倍(所有快速 rng-lib 都使用它们是有原因的)。但我接受,ayhan 更准确地回答了你的问题,因为你想要一些基于 erfinv 的方法。 :-)
  • 好的,萨沙,我会检查你建议的链接,并在检查接受的答案之前尝试调整它们。我只喜欢基于 erfinv 的答案,因为与逆变换采样的连接直接在语法级别上是简单明了的。
  • 我很乐意接受 ayhan 的回答。我认为,您应该首先采用这两种简单方法中的一种。如果速度对您来说太慢,请仅实施上述其中一项(或获取一些 numpy/scipy 内部)。
猜你喜欢
  • 2010-09-18
  • 2012-10-17
  • 2013-02-07
  • 2012-07-02
  • 1970-01-01
  • 2015-04-26
  • 1970-01-01
  • 2013-12-02
  • 2012-07-14
相关资源
最近更新 更多