我想force scipy.stats.cauchy
概率密度函数只生成介于-1和1之间的值。
当前,我正在通过在while循环内运行y=cauchy.rvs(center,sigma)
来进行变通的方式,当其小于-1或大于1时,它将重新计算它,并在进入所需的间隔后返回y。因此,基本上我要绘制一个新的随机变量,直到不满足条件为止。
我想知道是否有可能以更简单的方式做到这一点,scipy文档不是很有帮助,而且模棱两可。是否可以通过** kwargs之类的方法来指定函数参数内随机变量的最小/最大范围?
答案 0 :(得分:1)
简短的回答:不是直接的,不是。
问题在于分布已归一化,支撑上pdf的积分是统一的。更改支持时,实际上是在更改发行版。
对于截断的柯西分布,您可以使用统一随机变量的逆函数变换轻松滚动自己的小生成器。
答案 1 :(得分:1)
@ ev-br是正确的,没有使用SciPy或NumPy的内置方法。 @ ev-br也是正确的,“您可以使用统一随机变量的逆函数变换轻松滚动自己的小生成器”。您在一条评论中说:“不幸的是,scipy包中没有反函数,而不是手动输入,这很长,我想我会保留while循环...”,但实际上公式很简单。 (实际上,Cauchy分布的CDF有一个倒数scipy.stats.cauchy.ppf
,但在这里我将直接实现该公式。)
这是使用逆变换的截断式柯西采样器:
import numpy as np
def truncated_cauchy_rvs(loc=0, scale=1, a=-1, b=1, size=None):
"""
Generate random samples from a truncated Cauchy distribution.
`loc` and `scale` are the location and scale parameters of the distribution.
`a` and `b` define the interval [a, b] to which the distribution is to be
limited.
With the default values of the parameters, the samples are generated
from the standard Cauchy distribution limited to the interval [-1, 1].
"""
ua = np.arctan((a - loc)/scale)/np.pi + 0.5
ub = np.arctan((b - loc)/scale)/np.pi + 0.5
U = np.random.uniform(ua, ub, size=size)
rvs = loc + scale * np.tan(np.pi*(U - 0.5))
return rvs
例如,
In [57]: x = truncated_cauchy_rvs(loc=0.25, scale=1/3, size=200000)
In [58]: ignore = plt.hist(x, bins=100, density=True, color='green', alpha=0.25)
In [59]: plt.grid(alpha=0.5)