[英]One-sided truncated normal distribution in scipy
在 scipy 中,有沒有辦法從僅在一側截斷的正態分布中進行采樣?
假設我有一個標准正態分布,域為(-inf, 0]
。
scipy.stats.truncnorm
類為具有特定下限和上限的分布提供實用程序,但是如果您只有一個或另一個,缺少scipy.stats.truncnorm(a=-9999999, b=0, loc=0, scale=1)
?
使用np.inf
(或-np.inf
)設置邊界會導致分布在該側無界:
scipy.stats.truncnorm(a=-np.inf, b=0, loc=0, scale=1)
回復@warren-weckesser 以獲取評論中的答案。
您所描述的是半正態分布(准確地說是其鏡像到 y 軸),這是折疊正態分布和截斷正態分布等效的特殊情況。 scipy 還提供了該分布: scipy.stats.foldnorm 。 我提到這一點的唯一原因是(不要迂腐)因為 scipy 和 numpy 如何定義這些分布非常復雜(見下文: mu
& sigma
vs. beta
, scale
, loc
, a
& b
)
在筆記本中運行它,差異變得明顯:
import numpy as np
import scipy.stats as st
import matplotlib.pyplot as plt
resolution=10000
mu, sigma = 0.0, 0.2
normdist = lambda x: 1/(sigma * np.sqrt(2 * np.pi)) * np.exp( - (x - mu)**2 / (2 * sigma**2) )
f = np.random.normal(mu, sigma, resolution)
count, bins, ignored = plt.hist(f, 'auto', density=True)
plt.plot(bins, [normdist(x) for x in bins], 'r--', linewidth=2, label='(np)norm.dist')
beta=2.0
scale=1/np.sqrt(2)*(2*sigma)
nd = st.gennorm(beta, loc=mu, scale=scale)
x = np.linspace(nd.ppf(0.01), nd.ppf(0.99), resolution)
plt.plot(x, nd.pdf(x),'g-', lw=2, alpha=0.6, label='(sc)gennorm pdf')
print(f'mean: {nd.mean()}, std: {nd.std()}')
c=0.0
fnd = st.foldnorm(c, loc=0.0, scale=scale)
x = np.arange(-1.0, 5.0, 1/resolution)
plt.plot(x, fnd.pdf(x),'k-', lw=2, alpha=0.6, label='(sc)foldnorm pdf')
# count, bins, ignored = plt.hist(fnd.rvs(size=resolution), 'auto', density=True)
print(f'mean: {fnd.mean()}, std: {fnd.std()}')
a=0
b=np.inf
tnd = st.truncnorm(a=a, b=b, loc=0, scale=scale)
plt.plot(x, tnd.pdf(x),'b-', lw=1, alpha=0.6, label='(sc)truncnorm pdf')
# count, bins, ignored = plt.hist(tnd.rvs(size=resolution), 'auto', density=True)
plt.plot(x, [normdist(x) for x in x], 'r--', lw=1, label='(np)norm.dist')
print(f'mean: {fnd.mean()}, std: {fnd.std()}')
plt.legend()
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.