scipy.stats.sampling.

FastGeneratorInversion#

class scipy.stats.sampling.FastGeneratorInversion(dist, *, domain=None, ignore_shape_range=False, random_state=None)[source]#

對於 scipy.stats 中大量連續分佈,透過 CDF 的數值反演進行快速採樣。

參數:
distrv_frozen 物件

來自 scipy.stats 的 Frozen 分佈物件。支援的分佈列表可以在「註解」章節中找到。用於建立分佈的形狀參數 locscale 必須是純量。例如,對於形狀參數為 p 的 Gamma 分佈,p 必須是浮點數,而對於形狀參數為 (a, b) 的 beta 分佈,a 和 b 都必須是浮點數。

domain浮點數 tuple,可選

如果希望從截斷/條件分佈中採樣,則必須指定 domain。預設值為 None。在這種情況下,隨機變數不會被截斷,並且 domain 是從分佈的支援範圍推斷出來的。

ignore_shape_range布林值,可選。

如果為 False,則為了確保數值準確性(請參閱「註解」),形狀參數超出有效值範圍時,將引發 ValueError。如果為 True,則接受分佈的任何有效形狀參數。這對於測試可能很有用。預設值為 False。

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

NumPy 隨機數生成器或用於底層 NumPy 隨機數生成器的種子,用於生成均勻隨機數流。如果 random_state 為 None,則使用 self.random_state。如果 random_state 為整數,則使用 np.random.default_rng(random_state)。如果 random_state 已經是 GeneratorRandomState 實例,則使用該實例。

註解

此類別為 dist 指定的連續分佈建立物件。方法 rvs 使用來自 scipy.stats.sampling 的生成器,該生成器在物件實例化時建立。此外,還加入了方法 qrvsppfqrvs 基於來自 scipy.stats.qmc 的準隨機數生成樣本。ppf 是基於 [1] 中的數值反演方法的 PPF (NumericalInversePolynomial),用於生成隨機變數。

支援的分佈 (distname) 包括:alphaanglitargusbetabetaprimebradfordburrburr12cauchychichi2cosinecrystalballexpongammagennormgeninvgaussgumbel_lgumbel_rhypsecantinvgammainvgaussinvweibulllaplacelogisticmaxwellmoyalnormparetopowerlawtrayleighsemicircularwaldweibull_maxweibull_min

rvs 依賴於數值反演的準確性。如果使用極端的形狀參數,數值反演可能無法正常工作。但是,對於所有已實作的分佈,都已測試過可接受的形狀參數,如果使用者提供的數值超出允許範圍,將會引發錯誤。對於所有有效參數,u-error 不應超過 1e-10。請注意,即使參數在有效範圍內,在實例化物件時也可能會引發警告。若要檢查數值準確性,可以使用方法 evaluate_error

請注意,所有已實作的分佈也都是 scipy.stats 的一部分,而由 FastGeneratorInversion 建立的物件依賴於來自 rv_frozen 的方法,例如 ppfcdfpdf。使用此類別的主要好處可以總結如下:一旦在設定步驟中建立了用於採樣隨機變數的生成器,使用 ppf 進行採樣和 PPF 評估非常快速,並且效能基本上與分佈無關。因此,如果需要大量的隨機變數,對於許多分佈可以實現顯著的加速。重要的是要知道,這種快速採樣是透過 CDF 的反演實現的。因此,一個均勻隨機變數被轉換為一個非均勻變數,這對於幾種模擬方法來說是一個優勢,例如,當使用共同隨機變數或反義變數的變異數縮減方法時 ([2])。

此外,反演還使其能夠: - 使用來自 scipy.stats.qmc 的 QMC 生成器(方法 qrvs), - 生成截斷到區間的隨機變數。例如,如果目標是從區間 (2, 4) 中採樣標準常態隨機變數,則可以使用參數 domain 輕鬆實現。

最初由 dist 定義的位置和尺度可以重設,而無需重新執行設定步驟來建立用於採樣的生成器。分佈 Ylocscale 與標準分佈 X(即 loc=0scale=1)的關係由 Y = loc + scale * X 給出。

參考文獻

[1]

Derflinger, Gerhard, Wolfgang Hörmann, 和 Josef Leydold. “Random variate generation by numerical inversion when only the density is known.” ACM Transactions on Modeling and Computer Simulation (TOMACS) 20.4 (2010): 1-25.

[2]

Hörmann, Wolfgang, Josef Leydold 和 Gerhard Derflinger. “Automatic nonuniform random number generation.” Springer, 2004.

範例

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

讓我們從一個簡單的範例開始,來說明主要功能

>>> gamma_frozen = stats.gamma(1.5)
>>> gamma_dist = FastGeneratorInversion(gamma_frozen)
>>> r = gamma_dist.rvs(size=1000)

平均值應約等於形狀參數 1.5

>>> r.mean()
1.52423591130436  # may vary

同樣地,我們可以基於準隨機數繪製樣本

>>> r = gamma_dist.qrvs(size=1000)
>>> r.mean()
1.4996639255942914  # may vary

將 PPF 與近似值 ppf 進行比較。

>>> q = [0.001, 0.2, 0.5, 0.8, 0.999]
>>> np.max(np.abs(gamma_frozen.ppf(q) - gamma_dist.ppf(q)))
4.313394796895409e-08

為了確認數值反演的準確性,我們評估近似誤差(u-error),它應該低於 1e-10(更多詳細資訊,請參閱 evaluate_error 的文件)

>>> gamma_dist.evaluate_error()
(7.446320551265581e-11, nan)  # may vary

請注意,位置和尺度可以在不實例化新生成器的情況下更改

>>> gamma_dist.loc = 2
>>> gamma_dist.scale = 3
>>> r = gamma_dist.rvs(size=1000)

平均值應約為 2 + 3*1.5 = 6.5。

>>> r.mean()
6.399549295242894  # may vary

讓我們也說明如何應用截斷

>>> trunc_norm = FastGeneratorInversion(stats.norm(), domain=(3, 4))
>>> r = trunc_norm.rvs(size=1000)
>>> 3 < r.min() < r.max() < 4
True

檢查平均值

>>> r.mean()
3.250433367078603  # may vary
>>> stats.norm.expect(lb=3, ub=4, conditional=True)
3.260454285589997

在這個特定案例中,也可以使用 scipy.stats.truncnorm 來生成截斷常態隨機變數。

屬性:
loc浮點數

位置參數。

random_state{numpy.random.Generator, numpy.random.RandomState}

在相關方法(如 rvs)中使用的隨機狀態(除非另一個 random_state 作為參數傳遞給這些方法)。

scale浮點數

尺度參數。

方法

evaluate_error([size, random_state, x_error])

評估反演的數值準確性(u-error 和 x-error)。

ppf(q)

分佈的極快速 PPF(反向 CDF),它是精確 PPF 值的非常接近的近似值。

qrvs([size, d, qmc_engine])

給定分佈的準隨機變數。

rvs([size])

透過反演從分佈中採樣。

支援()

分佈的支援範圍。

cdf