SimpleRatioUniforms#
- class scipy.stats.sampling.SimpleRatioUniforms(dist, *, mode=None, pdf_area=1, domain=None, cdf_at_mode=None, random_state=None)#
简单均匀比(SROU)方法。
SROU基于均匀比方法,该方法使用通用不等式来构建(通用)边界矩形。 它适用于具有
T(x) = -1/sqrt(x)
的T-凹分布。 该方法的主要优点是设置速度快。 如果需要重复生成具有不同形状参数的分布的小到中等样本,这将是有益的。 在这种情况下,NumericalInverseHermite
或NumericalInversePolynomial
的设置步骤将导致性能不佳。- 参数:
- dist对象
具有
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,可选
模式下的 CDF。 可以给出它以提高算法的性能。 当给出模式下的 CDF 时,拒绝常数减半。 默认为
None
。- random_state{None, int,
numpy.random.Generator
, 用于生成均匀随机数流的底层 NumPy 随机数生成器或种子。 如果random_state为 None(或np.random),则使用
numpy.random.RandomState
单例。 如果random_state是一个 int,则使用一个新的RandomState
实例,并使用random_state作为种子。 如果random_state已经是一个Generator
或RandomState
实例,则使用该实例。
方法
rvs
([size, random_state])从分布中采样。
set_random_state
([random_state])设置底层的均匀随机数生成器。
参考文献
[1]UNU.RAN 参考手册,第 5.3.16 节,“SROU - 简单均匀比方法”,http://statmath.wu.ac.at/software/unuran/doc/unuran.html#SROU
[2]Leydold, Josef. “用于连续和离散单变量 T 凹分布的简单通用生成器。” ACM Transactions on Mathematical Software (TOMS) 27.1 (2001): 66-82
[3]Leydold, Josef. “通过广义均匀比方法的短通用生成器。” Mathematics of Computation 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()