scipy.stats.sampling.

SimpleRatioUniforms#

scipy.stats.sampling.SimpleRatioUniforms(dist, *, mode=, pdf_area=1, domain=, cdf_at_mode=, random_state=)#

均匀比率 (SROU) 方法。

SROU 基于比率统一性方法,该方法利用通用不等式构造(通用)边界矩形。它适用于 T 凹型分布,T(x) = -1/sqrt(x)。该方法的主要优势是快速设置。如果需要重复生成不同形状参数的分布的小到中等样本,这可能会带来优势。在这种情况下,NumericalInverseHermiteNumericalInversePolynomial 的设置步骤将导致糟糕的性能表现。

参数:
distobject

具有 pdf 方法的类的实例。

  • pdf:分布的 PDF。PDF 的签名预计为:def pdf(self, x: float) -> float。即,PDF 应接受 Python 浮点数并返回 Python 浮点数。它不必整合为 1,即 PDF 不必经过标准化处理。如果未经标准化处理,pdf_area 应设置为 PDF 下的区域。

modefloat,可选

分布的(精确)众数。当众数为 None 时,将使用速度较慢的数值例程来近似计算众数。默认值为 None

pdf_areafloat,可选

PDF 下的区域。根据需要,可以传递 PDF 下区域的上限,但要以增加拒绝常数作为代价。默认值为 1。

domain长度为 2 的列表或元组,可选

分布的支持。默认值为 None。当为 None

  • 如果分布对象 dist 提供 support 方法,则使用它设置分布的域。

  • 否则,将假设支持为 \((-\infty, \infty)\)

cdf_at_modefloat,可选

模式下分布函数。提供它可提高算法性能。如果提供模式下分布函数,则拒绝常数将减少一半。默认为

random_state{None, int, numpy.random.Generator,

NumPy 随机数生成器或用于生成均匀随机数流的底层 NumPy 随机数生成器的种子。如果 random_state 为 None(或 np.random),则使用 numpy.random.RandomState 单例。如果 random_state 为 int,则使用一个新的 RandomState 实例,对其以 random_state 播种。如果 random_state 已是 GeneratorRandomState 实例,则使用该实例。

参考

[1]

UNU.RAN 参考手册,第 5.3.16 节,“SROU - 简单均匀比值法”,http://statmath.wu.ac.at/software/unuran/doc/unuran.html#SROU

[2]

Leydold, Josef。“连续和离散单变量 T 凹分布的简单通用生成器。”ACM 数学软件学报 (TOMS) 27.1 (2001): 66-82

[3]

Leydold, Josef。“通过广义均匀比值法实现简短通用生成器。”计算数学 72.243 (2003): 1453-1471

示例

>>> from scipy.stats.sampling import SimpleRatioUniforms
>>> import numpy as np

假设我们有正态分布

>>> class StdNorm:
...     def pdf(self, x):
...         return np.exp(-0.5 * x**2)

请注意,PDF 尚未积分至 1。我们可以在生成器初始化期间分别传递 PDF 下的精确面积或 PDF 下的精确面积的上限。另外,建议传递该分布的模式以加快安装速度

>>> urng = np.random.default_rng()
>>> dist = StdNorm()
>>> rng = SimpleRatioUniforms(dist, mode=0,
...                           pdf_area=np.sqrt(2*np.pi),
...                           random_state=urng)

现在,我们可以使用 rvs 方法从分布中生成样本

>>> rvs = rng.rvs(10)

如果模式下的 CDF 可用,则可将其设置为改善 rvs 的性能

>>> from scipy.stats import norm
>>> rng = SimpleRatioUniforms(dist, mode=0,
...                           pdf_area=np.sqrt(2*np.pi),
...                           cdf_at_mode=norm.cdf(0),
...                           random_state=urng)
>>> rvs = rng.rvs(1000)

通过可视化其直方图,我们可以查看样本是否来自给定的分布

>>> import matplotlib.pyplot as plt
>>> x = np.linspace(rvs.min()-0.1, rvs.max()+0.1, 1000)
>>> fx = 1/np.sqrt(2*np.pi) * dist.pdf(x)
>>> fig, ax = plt.subplots()
>>> ax.plot(x, fx, 'r-', lw=2, label='true distribution')
>>> ax.hist(rvs, bins=10, density=True, alpha=0.8, label='random variates')
>>> ax.set_xlabel('x')
>>> ax.set_ylabel('PDF(x)')
>>> ax.set_title('Simple Ratio-of-Uniforms Samples')
>>> ax.legend()
>>> plt.show()
../../_images/scipy-stats-sampling-SimpleRatioUniforms-1.png

方法

rvs([size, random_state])

按分布样本

set_random_state([random_state])

设置基本的随机数生成器