2013-08-26 7 views
15

IOKだから、0と1の間にしかない正規分布から値を選びたいと思う。場合によっては、完全にランダムな分布を返すだけで、他の場合には、ガウスの形をした値を返すことができます。私は次の関数を使用しています現時点ではnumpy.random.normalを使用するときの上限と下限の指定方法

def blockedgauss(mu,sigma): 
    while True: 
     numb = random.gauss(mu,sigma) 
     if (numb > 0 and numb < 1): 
      break 
    return numb 

それはそれは1の範囲0の外にある場合は、それを破棄しますが、そこになければならないように私は感じて、正規分布から値を取り出しますこれを行うためのよりよい方法になります。

+0

コーディングで冒険野郎マクガイバーをエミュレートしてみませんか? –

+0

ガウス分布ではありませんが、ガウス分布を望まない場合もあります。私は無作為分布(非常に幅の広いガウス型からのピッキング)、デルタ関数(ガウス型が非常に狭くなる)に非常に近いものまで調整可能な分布を返したいと思います。 –

答えて

21

truncated normal distributionのように聞こえます。 scipyのダウンロードを使用して、あなたは、このような分布からランダム変量を生成するためにscipy.stats.truncnormを使用することができます。

import matplotlib.pyplot as plt 
import scipy.stats as stats 

lower, upper = 3.5, 6 
mu, sigma = 5, 0.7 
X = stats.truncnorm(
    (lower - mu)/sigma, (upper - mu)/sigma, loc=mu, scale=sigma) 
N = stats.norm(loc=mu, scale=sigma) 

fig, ax = plt.subplots(2, sharex=True) 
ax[0].hist(X.rvs(10000), normed=True) 
ax[1].hist(N.rvs(10000), normed=True) 
plt.show() 

enter image description here

を上図は、切断正規分布を示し、下の図は、同じ平均muの正規分布を示しています標準偏差はsigmaです。

+0

完璧です。 –

5

この投稿には、ゼロから1の間で切り捨てられた正規分布からサンプリングされた一連の値(すなわち確率)を返す方法を探していました。同じ問題を抱えている人を助けるために、私はscipy.stats.truncnormに ".rvs"という組み込み機能があることに気づきたいと思います。

だから、あなたは、0.1の0.5の平均値と標準偏差100,000サンプルたい場合:

import scipy.stats 
lower = 0 
upper = 1 
mu = 0.5 
sigma = 0.1 
N = 100000 

samples = scipy.stats.truncnorm.rvs(
      (lower-mu)/sigma,(upper-mu)/sigma,loc=mu,scale=sigma,size=N) 

これはnumpy.random.normalと非常に類似した挙動を与えるが、しかし範囲内で希望しました。組み込み関数の使用は、特にNの大きな値の場合、サンプルを収集するためのループ処理よりもかなり高速になります。

3

次の例でスクリプトを作成しました。既知のパラメータでサンプルを生成する、CDF、PDFなどを計算する方法など、私たちが望む機能を実装するためにAPIを使用する方法を示します。これを示す画像も添付します。

#load libraries 
import scipy.stats as stats 

#lower, upper, mu, and sigma are four parameters 
lower, upper = 0.5, 1 
mu, sigma = 0.6, 0.1 

#instantiate an object X using the above four parameters, 
X = stats.truncnorm((lower - mu)/sigma, (upper - mu)/sigma, loc=mu, scale=sigma) 

#generate 1000 sample data 
samples = X.rvs(1000) 

#compute the PDF of the sample data 
pdf_probs = stats.truncnorm.pdf(samples, (lower-mu)/sigma, (upper-mu)/sigma, mu, sigma) 

#compute the CDF of the sample data 
cdf_probs = stas.truncnorm.cdf(samples, (lower-mu)/sigma, (upper-mu)/sigma, mu, sigma) 

#make a histogram for the samples 
plt.hist(samples, bins= 50,normed=True,alpha=0.3,label='histogram'); 

#plot the PDF curves 
plt.plot(samples[samples.argsort()],pdf_probs[samples.argsort()],linewidth=2.3,label='PDF curve') 

#plot CDF curve   
plt.plot(samples[samples.argsort()],cdf_probs[samples.argsort()],linewidth=2.3,label='CDF curve') 


#legend 
plt.legend(loc='best') 

enter image description here

4

場合、誰もが唯一のnumpyのを使用して解決策を望んでいる、ここnormal機能とclip(冒険野郎マクガイバーのアプローチ)を使用して、簡単な実装です:

import numpy as np 
    def truncated_normal(mean, stddev, minval, maxval): 
     return np.clip(np.random.normal(mean, stddev), minval, maxval) 

EDIT:これを使用しないでください!これはあなたがそれをしてはいけない方法です!例えば、それが動作するように
a = truncated_normal(np.zeros(10000), 1, -10, 10)
に見えるかもしれませんが、
b = truncated_normal(np.zeros(10000), 100, -1, 1)
次のヒストグラムで見ることができるよう間違いなく、切り捨て通常を描画しません。

enter image description here

申し訳ありませんそのために、誰も傷ついていないと願っています!私はレッスンがあると思い、それはまだガウス分布となり、あなたの「ブロック」の値< 0 and > 1なら... 乾杯、
アンドレス

関連する問題