2013-08-26 2 views
15

आईओके का उपयोग करते समय ऊपरी और निचली सीमाओं को निर्दिष्ट करने के लिए कैसे करें, इसलिए मैं सामान्य वितरण से मूल्यों को चुनने में सक्षम होना चाहता हूं जो केवल 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 

यह एक सामान्य वितरण से कोई मान लेती है, तो इसे छोड़ देता है अगर यह सीमा 0 से 1 तक अवधि से बाहर है, लेकिन मैं की तरह वहाँ चाहिए लग रहा है ऐसा करने का एक बेहतर तरीका बनें।

+0

"ब्लॉक" < 0 and > 1 को महत्व देता है, तो कोशिश मत करो, यह अभी भी एक गाऊसी वितरण हो जाएगा? –

+0

यह एक गाऊशियन वितरण नहीं होगा, लेकिन कुछ मामलों में मैं एक गाऊशियन वितरण नहीं चाहता हूं। मैं एक वितरण को वापस करना चाहता हूं जो एक यादृच्छिक वितरण (बहुत व्यापक गाऊशियन से चुनना) के बीच ट्यून करने योग्य है, जो डेल्टा फ़ंक्शन के बहुत करीब है (जहां गाऊसी बहुत संकीर्ण हो जाता है) –

उत्तर

21

ऐसा लगता है कि आप truncated normal distribution चाहते हैं। scipy का उपयोग करके आप scipy.stats.truncnorm इस्तेमाल कर सकते हैं इस तरह के एक वितरण से यादृच्छिक variates उत्पन्न करने के लिए:

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.5 का मतलब है एक और 0.1 के मानक विचलन के साथ 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 के समान व्यवहार देता है, लेकिन सीमा के भीतर वांछित। अंतर्निहित का उपयोग नमूने इकट्ठा करने के लिए लूपिंग से काफी तेज़ होगा, विशेष रूप से एन

3

के बड़े मूल्यों के लिए मैंने निम्न द्वारा एक उदाहरण स्क्रिप्ट बनाई है। यह दिखाता है कि हमारे इच्छित कार्यों को लागू करने के लिए एपीआई का उपयोग कैसे करें, जैसे ज्ञात पैरामीटर के साथ उत्पन्न नमूने, सीडीएफ, पीडीएफ आदि की गणना कैसे करें। मैं इसे दिखाने के लिए एक छवि भी संलग्न करता हूं।

#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 (MacGyver का दृष्टिकोण) का उपयोग कर दिया गया है:

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

संपादित करें: इसका उपयोग न करें !! इस तरह आपको यह नहीं करना चाहिए !! उदाहरण के लिए,
a = truncated_normal(np.zeros(10000), 1, -10, 10)
की तरह यह काम करता है लग सकता है, लेकिन
b = truncated_normal(np.zeros(10000), 100, -1, 1)
निश्चित रूप से एक छोटा सामान्य आकर्षित नहीं होगा, जैसा कि आप निम्नलिखित हिस्टोग्राम में देख सकते हैं:

enter image description here

क्षमा करें इसके लिए, आशा है कि किसी को भी चोट नहीं पहुंची!मुझे लगता है कि सबक है, कोडिंग पर MacGyver अनुकरण करने के लिए ... चीयर्स,
एन्ड्रेस