RatioUniforms#
- class scipy.stats.sampling.RatioUniforms(pdf, *, umax, vmin, vmax, c=0, random_state=None)[原始碼]#
使用均勻分佈比率法從機率密度函數生成隨機樣本。
- 參數:
- pdf可呼叫物件(callable)
一個簽名為 pdf(x) 的函數,與分佈的機率密度函數成比例。
- umaxfloat
u 方向邊界矩形的上限。
- vminfloat
v 方向邊界矩形的下限。
- vmaxfloat
v 方向邊界矩形的上限。
- cfloat,選用。
均勻分佈比率法的位移參數,請參閱「註解」。預設值為 0。
- random_state{None, int,
numpy.random.Generator
, 如果 seed 為 None(或 np.random),則使用
numpy.random.RandomState
單例模式。如果 seed 為整數,則使用新的RandomState
實例,並以 seed 作為種子。如果 seed 已經是Generator
或RandomState
實例,則使用該實例。
註解
給定單變數機率密度函數 pdf 和常數 c,定義集合
A = {(u, v) : 0 < u <= sqrt(pdf(v/u + c))}
。如果(U, V)
是在A
上均勻分佈的隨機向量,則V/U + c
遵循根據 pdf 的分佈。上述結果(請參閱 [1]、[2])可用於僅使用 PDF 對隨機變數進行抽樣,即不需要 CDF 的反函數。 c 的典型選擇為零或 pdf 的眾數。集合
A
是矩形R = [0, umax] x [vmin, vmax]
的子集,其中umax = sup sqrt(pdf(x))
vmin = inf (x - c) sqrt(pdf(x))
vmax = sup (x - c) sqrt(pdf(x))
特別是,如果 pdf 有界且
x**2 * pdf(x)
有界(即次二次尾部),則這些值是有限的。可以生成在R
上均勻分佈的(U, V)
,如果(U, V)
也位於A
中,則返回V/U + c
,這可以直接驗證。如果將 pdf 替換為 k * pdf,對於任何常數 k > 0,演算法都不會改變。因此,通常方便使用與機率密度函數成比例的函數,方法是捨棄不必要的正規化因子。
直觀地說,如果
A
填滿了大部分的封閉矩形,則該方法效果良好,這樣一來,當(U, V)
位於R
中時,(U, V)
也位於A
中的機率很高,否則所需的迭代次數會變得過多。更精確地說,請注意,繪製在R
上均勻分佈的(U, V)
,使得(U, V)
也位於A
中的預期迭代次數由比率area(R) / area(A) = 2 * umax * (vmax - vmin) / area(pdf)
給出,其中 area(pdf) 是 pdf 的積分(如果使用機率密度函數,則等於 1,但如果使用與密度成比例的函數,則可以取其他值)。等式成立,因為A
的面積等於0.5 * area(pdf)
([1] 中的定理 7.1)。如果在 50000 次迭代後抽樣仍無法生成單個隨機變數(即,沒有單個抽樣位於A
中),則會引發例外。如果未正確指定邊界矩形(即,如果它不包含
A
),則演算法會從與 pdf 給定的分佈不同的分佈中抽樣。因此,建議執行諸如kstest
之類的測試作為檢查。參考文獻
[2]W. Hoermann 和 J. Leydold,“Generating generalized inverse Gaussian random variates”,Statistics and Computing,24(4),第 547–557 頁,2014 年。
[3]A.J. Kinderman 和 J.F. Monahan,“Computer Generation of Random Variables Using the Ratio of Uniform Deviates”,ACM Transactions on Mathematical Software,3(3),第 257–260 頁,1977 年。
範例
>>> import numpy as np >>> from scipy import stats
>>> from scipy.stats.sampling import RatioUniforms >>> rng = np.random.default_rng()
模擬常態分佈的隨機變數。在這種情況下,很容易顯式計算邊界矩形。為了簡單起見,我們捨棄密度的正規化因子。
>>> f = lambda x: np.exp(-x**2 / 2) >>> v = np.sqrt(f(np.sqrt(2))) * np.sqrt(2) >>> umax = np.sqrt(f(0)) >>> gen = RatioUniforms(f, umax=umax, vmin=-v, vmax=v, random_state=rng) >>> r = gen.rvs(size=2500)
K-S 檢定確認隨機變數確實是常態分佈的(在 5% 顯著性水平下不拒絕常態性)
>>> stats.kstest(r, 'norm')[1] 0.250634764150542
指數分佈提供了另一個可以顯式確定邊界矩形的範例。
>>> gen = RatioUniforms(lambda x: np.exp(-x), umax=1, vmin=0, ... vmax=2*np.exp(-1), random_state=rng) >>> r = gen.rvs(1000) >>> stats.kstest(r, 'expon')[1] 0.21121052054580314
方法
rvs
([size])隨機變數抽樣