scipy.stats.NumericalInverseHermite¶
- class scipy.stats.NumericalInverseHermite(dist, *, tol=1e-12, max_intervals=100000)[源代码]¶
概率分布的Hermite样条快速数值逆。
的初始值设定项
NumericalInverseHermite
接受 dist ,表示连续分布的对象,并为对象提供近似于 dist.ppf 和 dist.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 必须有方法
pdf
,cdf
,以及ppf
它们的行为就像 冻结 实例scipy.stats.rv_continuous
。具体地说,它必须有方法pdf
和cdf
它只接受一个ndarray参数x
并(分别)返回概率密度函数和累积密度函数x
。该对象还必须有一个方法ppf
接受浮点数的p
,并返回百分位点函数p
。该对象还可以具有方法isf
接受浮点数的p
,并返回位于以下位置的逆生存函数p
;如果不是,将为其分配一个属性isf
用来计算反生存函数的ppf
。这个ppf
和isf` 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.ppf
和dist.rvs
都很慢。例如,考虑scipy.stats.genexpon
。我们冻结分布,方法是将所有形状参数传递到其初始值设定项中,并对结果对象的ppf
和rvs
功能。>>> 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
并初始化冻结的实例或使用等效的pdf
,cdf
,以及ppf
方法。例如,以下对象表示标准正态分布。为简单起见,我们使用scipy.special.ndtr
和scipy.special.ndtri
要计算cdf
和ppf
,分别为。>>> 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] )给定房车的随机变量。