scipy.stats.NumericalInverseHermite

class scipy.stats.NumericalInverseHermite(dist, *, tol=1e-12, max_intervals=100000)[源代码]

概率分布的Hermite样条快速数值逆。

的初始值设定项 NumericalInverseHermite 接受 dist ,表示连续分布的对象,并为对象提供近似于 dist.ppfdist.rvs 。对于大多数发行版,这些方法比 dist 它本身。

参数
dist对象

对象,该对象表示需要进行快速数值逆运算的分布;例如, scipy.stats 连续分布。有关详细信息,请参阅注释和示例。

tol浮动,可选

U误差公差(请参阅注释)。默认值为1e-12。

max_intervals整型,可选

三次Hermite样条中用于逼近百分点函数的最大间隔数。默认值为100000。

注意事项

NumericalInverseHermite 用三次Hermite样条近似连续统计分布的CDF的逆。

如中所述 [1], 它首先在分位数网格上评估分布的PDF和CDF x 在发行版的支持范围内。它使用结果来拟合三次Hermite样条 H 这样一来, H(p) == x ,在哪里 p 是与分位数对应的百分位数组 x 。因此,样条近似分布的CDF的倒数到百分位数的加工精度 p ,但通常情况下,样条曲线在百分位点之间的中点处不会那么精确:

p_mid = (p[:-1] + p[1:])/2

因此,根据需要细化分位数网格,以减少最大“u-误差”:

u_error = np.max(np.abs(dist.cdf(H(p_mid)) - p_mid))

低于指定公差 tol 。当达到要求的容差或下次优化后的网格间隔数可能超过最大允许值时,优化将停止 max_intervals

该对象 dist 必须有方法 pdfcdf ,以及 ppf 它们的行为就像 冻结 实例 scipy.stats.rv_continuous 。具体地说,它必须有方法 pdfcdf 它只接受一个ndarray参数 x 并(分别)返回概率密度函数和累积密度函数 x 。该对象还必须有一个方法 ppf 接受浮点数的 p ,并返回百分位点函数 p 。该对象还可以具有方法 isf 接受浮点数的 p ,并返回位于以下位置的逆生存函数 p ;如果不是,将为其分配一个属性 isf 用来计算反生存函数的 ppf 。这个 ppfisf` methods will each be evaluated at a small positive float `` p``(例如 ``p = utol/10 ),并且在其上定义近似数值逆的域将是 ppf(p)isf(p) 。在超出此域的极端尾部,近似值将不准确。

参考文献

1

霍尔曼、沃尔夫冈和约瑟夫·莱多德。“通过快速数值反演产生连续的随机变量。”美国机械学会建模与计算机仿真学报(TOMACS)13.4(2003):347-362。

示例

对于某些发行版, dist.ppfdist.rvs 都很慢。例如,考虑 scipy.stats.genexpon 。我们冻结分布,方法是将所有形状参数传递到其初始值设定项中,并对结果对象的 ppfrvs 功能。

>>> import numpy as np
>>> from scipy import stats
>>> from timeit import timeit
>>> time_once = lambda f: f"{timeit(f, number=1)*1000:.6} ms"
>>> dist = stats.genexpon(9, 16, 3)  # freeze the distribution
>>> p = np.linspace(0.01, 0.99, 99)  # percentiles from 1% to 99%
>>> time_once(lambda: dist.ppf(p))
'154.565 ms'  # may vary
>>> time_once(lambda: dist.rvs(size=100))
'148.979 ms'  # may vary

这个 NumericalInverseHermite 有一种方法近似于 dist.ppf

>>> from scipy.stats import NumericalInverseHermite
>>> fni = NumericalInverseHermite(dist)
>>> np.allclose(fni.ppf(p), dist.ppf(p))
True

在某些情况下,生成快速数值逆并使用它比调用 dist.ppf

>>> def time_me():
...     fni = NumericalInverseHermite(dist)
...     fni.ppf(p)
>>> time_once(time_me)
'11.9222 ms'  # may vary

在生成快速数值逆之后,对其方法的后续调用要快得多。>time_once(lambda:fni.ppf(P))‘0.0819 ms’#可能有所不同

快速数值逆也可用于通过逆变换采样产生随机变量。

>>> time_once(lambda: fni.rvs(size=100))
'0.0911 ms'  # may vary

根据分布的随机抽样方法的实现,在给定相同的随机状态的情况下,生成的随机变量可能几乎相同。

>>> # `seed` ensures identical random streams are used by each `rvs` method
>>> seed = 500072020
>>> rvs1 = dist.rvs(size=100, random_state=np.random.default_rng(seed))
>>> rvs2 = fni.rvs(size=100, random_state=np.random.default_rng(seed))
>>> np.allclose(rvs1, rvs2)
True

要使用 NumericalInverseHermite 使用自定义分发版,用户可以子类 scipy.stats.rv_continuous 并初始化冻结的实例或使用等效的 pdfcdf ,以及 ppf 方法。例如,以下对象表示标准正态分布。为简单起见,我们使用 scipy.special.ndtrscipy.special.ndtri 要计算 cdfppf ,分别为。

>>> from scipy.special import ndtr, ndtri
>>>
>>> class MyNormal:
...
...     def pdf(self, x):
...        return 1/np.sqrt(2*np.pi) * np.exp(-x**2 / 2)
...
...     def cdf(self, x):
...        return ndtr(x)
...
...     def ppf(self, x):
...        return ndtri(x)
...
>>> dist1 = MyNormal()
>>> fni1 = NumericalInverseHermite(dist1)
>>>
>>> dist2 = stats.norm()
>>> fni2 = NumericalInverseHermite(dist2)
>>>
>>> print(fni1.rvs(random_state=seed), fni2.rvs(random_state=seed))
-1.9603810921759424 -1.9603810921747074
属性
intervals集成

插值的间隔数。

midpoint_error浮动

插值区间中点处的最大u误差。

方法:

ppf \(q)

近似百分点数函数(倒数 cdf )指定的房车。

qrvs \([size, d, qmc_engine] )

给定RV的准随机变量。

rvs \([size, random_state] )

给定房车的随机变量。