当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Python SciPy sampling.DiscreteGuideTable用法及代码示例


本文简要介绍 python 语言中 scipy.stats.sampling.DiscreteGuideTable 的用法。

用法:

class  scipy.stats.sampling.DiscreteGuideTable(dist, *, domain=None, guide_factor=1, random_state=None)#

离散导表法。

Discrete Guide Table 方法从任意但有限的概率向量中采样。它使用大小为 的概率向量或具有有限支持的概率质量函数从分布中生成随机数。 Discrete Guide Table 的设置速度非常慢(与矢量长度成线性关系),但采样速度非常快。

参数

dist 数组 或对象,可选

分布的概率向量 (PV)。如果 PV 不可用,则需要一个具有 pmf 方法的类的实例。 PMF 的签名预计为:def pmf(self, k: int) -> float。即它应该接受一个 Python 整数并返回一个 Python 浮点数。

domain 整数,可选

支持 PMF。如果概率向量 (pv) 不可用,则必须给出有限域。即 PMF 必须有一个有限的支持。默认为 None 。当 None

  • 如果一个support方法由分发对象提供距离,用于设置分布的域。

  • 否则,假定支持为 (0, len(pv)) 。当此参数与概率向量一起传递时,domain[0] 用于将分布从 (0, len(pv)) 重新定位到 (domain[0], domain[0]+len(pv)),而 domain[1] 将被忽略。有关更详细的说明,请参阅注释和教程。

guide_factor: int, optional

相对于 PV 长度的导向台尺寸。更大的引导表会导致更快的生成时间,但需要更昂贵的设置。不推荐大于 3 的尺寸。如果相对大小设置为 0,则使用顺序搜索。默认值为 1。

random_state {无,整数, numpy.random.Generator

NumPy 随机数生成器或底层NumPy 随机数生成器的种子,用于生成统一随机数流。如果random_state是无(或np.random), 这numpy.random.RandomState使用单例。如果random_state是一个 int,一个新的RandomState使用实例,播种random_state.如果random_state已经是一个Generator或者RandomState实例然后使用该实例。

注意

当有限概率向量可用或分布的 PMF 可用时,此方法有效。如果只有 PMF 可用,则还必须给出 PMF 的有限支持(域)。建议首先通过评估支持中每个点的 PMF 来获得概率向量,然后再使用它。

DGT 样本来自任意但有限的概率向量。随机数是通过反演方法生成的,即

  1. 生成一个随机数 U ~ U(0,1)。

  2. 找到最小整数 I 使得 F(I) = P(X<=I) >= U。

步骤(2)是关键步骤。使用顺序搜索需要 O(E(X)) 比较,其中 E(X) 是分布的期望值。然而,索引搜索使用引导表跳转到靠近 I 的一些 I' <= I 以在恒定时间内找到 X。实际上,当引导表与概率向量具有相同大小(这是默认值)时,预期的比较次数减少到 2。对于较大的引导表,此数字会变小(但始终大于 1),对于较小的表,它会变大。对于表大小为 1 的极限情况,该算法只是进行顺序搜索。

另一方面,引导表的设置时间为 O(N),其中 N 表示概率向量的长度(对于大小 1,不需要预处理)。此外,对于非常大的引导表,内存效应甚至可能会降低算法的速度。所以我们不建议使用比给定概率向量大三倍以上的引导表。如果只需要生成几个随机数,(很多)较小的表大小会更好。引导表相对于给定概率向量长度的大小可以通过guide_factor参数设置。

如果给定一个概率向量,它必须是一个非负浮点数的一维数组,没有任何 infnan 值。此外,必须至少有一个非零条目,否则会引发异常。

默认情况下,概率向量从 0 开始索引。但是,这可以通过传递 domain 参数来更改。当 domain 与 PV 一起给出时,它具有将分布从 (0, len(pv)) 重新定位到 (domain[0], domain[0] + len(pv)) 的效果。 domain[1] 在这种情况下被忽略。

参考

[1]

UNU.RAN 参考手册,第 5.8.4 节,“DGT -(离散)引导表方法(索引搜索)”https://statmath.wu.ac.at/unuran/doc/unuran.html#DGT

[2]

HC陈和 Y. Asau (1974)。关于从经验分布中生成随机变量,AIIE Trans。 6,第 163-166 页。

例子

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

要使用概率向量创建随机数生成器,请使用:

>>> pv = [0.1, 0.3, 0.6]
>>> urng = np.random.default_rng()
>>> rng = DiscreteGuideTable(pv, random_state=urng)

RNG 已设置完毕。现在,我们现在可以使用 rvs 方法从分布中生成样本:

>>> rvs = rng.rvs(size=1000)

为了验证随机变量是否遵循给定分布,我们可以使用卡方检验(作为goodness-of-fit 的度量):

>>> from scipy.stats import chisquare
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> freqs
array([0.092, 0.355, 0.553])
>>> chisquare(freqs, pv).pvalue
0.9987382966178464

由于 p 值非常高,我们无法拒绝观察到的频率与预期频率相同的零假设。因此,我们可以安全地假设变量是根据给定的分布生成的。请注意,这只是给出了算法的正确性,而不是样本的质量。

如果 PV 不可用,也可以传递具有 PMF 方法和有限域的类的实例。

>>> urng = np.random.default_rng()
>>> from scipy.stats import binom
>>> n, p = 10, 0.2
>>> dist = binom(n, p)
>>> rng = DiscreteGuideTable(dist, random_state=urng)

现在,我们可以使用 rvs 方法从分布中采样,并测量样本的 goodness-of-fit:

>>> rvs = rng.rvs(1000)
>>> _, freqs = np.unique(rvs, return_counts=True)
>>> freqs = freqs / np.sum(freqs)
>>> obs_freqs = np.zeros(11)  # some frequencies may be zero.
>>> obs_freqs[:freqs.size] = freqs
>>> pv = [dist.pmf(i) for i in range(0, 11)]
>>> pv = np.asarray(pv) / np.sum(pv)
>>> chisquare(obs_freqs, pv).pvalue
0.9999999999999989

为了检查样本是否来自正确的分布,我们可以可视化样本的直方图:

>>> import matplotlib.pyplot as plt
>>> rvs = rng.rvs(1000)
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> x = np.arange(0, n+1)
>>> fx = dist.pmf(x)
>>> fx = fx / fx.sum()
>>> ax.plot(x, fx, 'bo', label='true distribution')
>>> ax.vlines(x, 0, fx, lw=2)
>>> ax.hist(rvs, bins=np.r_[x, n+1]-0.5, density=True, alpha=0.5,
...         color='r', label='samples')
>>> ax.set_xlabel('x')
>>> ax.set_ylabel('PMF(x)')
>>> ax.set_title('Discrete Guide Table Samples')
>>> plt.legend()
>>> plt.show()
scipy-stats-sampling-DiscreteGuideTable-1_00_00.png

要设置引导表的大小,请使用 guide_factor 关键字参数。这设置了引导表相对于概率向量的大小

>>> rng = DiscreteGuideTable(pv, guide_factor=1, random_state=urng)

要使用 计算二项分布的 PPF:我们可以设置如下指导表:

>>> n, p = 4, 0.1
>>> dist = binom(n, p)
>>> rng = DiscreteGuideTable(dist, random_state=42)
>>> rng.ppf(0.5)
0.0

相关用法


注:本文由纯净天空筛选整理自scipy.org大神的英文原创作品 scipy.stats.sampling.DiscreteGuideTable。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。