एक समान वितरण को एक सामान्य वितरण में परिवर्तित करना


106

मैं एक समान वितरण (जैसा कि सबसे यादृच्छिक संख्या जनरेटर का उत्पादन करता हूं, जैसे 0.0 और 1.0 के बीच) को सामान्य वितरण में कैसे बदल सकता हूं? क्या होगा यदि मुझे मेरे चयन का एक मतलब और मानक विचलन चाहिए?


3
क्या आपके पास एक भाषा विनिर्देश है, या यह सिर्फ एक सामान्य एल्गोरिथ्म प्रश्न है?
छिपकली का बिल

3
सामान्य एल्गोरिथ्म प्रश्न। मुझे परवाह नहीं है कि कौन सी भाषा है। लेकिन मैं पसंद करूंगा कि उत्तर उस विशिष्ट कार्यक्षमता पर निर्भर न हो जो केवल उस भाषा को प्रदान करती है।
टेहॉर्स्ट

जवाबों:


47

Ziggurat एल्गोरिथ्म इस के लिए बहुत कुशल हालांकि है, बॉक्स-मुलर को बदलने लागू करना आसान खरोंच से (और पागल धीमी गति से नहीं है)।


7
रैखिक अनुरूप जनरेटर के बारे में सामान्य चेतावनियाँ इन दोनों विधियों पर लागू होती हैं, इसलिए एक सभ्य अंडरलिंग जनरेटर का उपयोग करें। चीयर्स।
dmckee --- पूर्व-मध्यस्थ ने बिल्ली का बच्चा

3
जैसे कि मेर्सेनी ट्विस्टर, या आपके पास अन्य सुझाव हैं?
ग्रेग लिंड

47

बहुत सारे तरीके हैं:

  • है बॉक्स मुलर का उपयोग करें। खासकर अगर आप कई गॉसियन नंबर खींचते हैं। बॉक्स मुलर एक परिणाम देता है जो -6 और 6 के बीच में होता है (दोहरी परिशुद्धता को मानते हुए। झांकियों के साथ चीजें बिगड़ जाती हैं।)। और यह वास्तव में अन्य उपलब्ध तरीकों की तुलना में कम कुशल है।
  • Ziggurat ठीक है, लेकिन एक टेबल लुकअप की आवश्यकता है (और कैश आकार के मुद्दों के कारण कुछ प्लेटफ़ॉर्म-विशिष्ट ट्वीकिंग)
  • अनुपात-की-वर्दी मेरा पसंदीदा है, केवल कुछ जोड़ / गुणा और समय का 1/50 वां लॉग (जैसे वहाँ देखो )।
  • CDF Inverting है कुशल (और अनदेखी की, क्यों?), तो आप इसके बारे में तेजी से कार्यान्वयन उपलब्ध यदि आप Google खोज की है। यह क्वासी-रैंडम संख्या के लिए अनिवार्य है।

2
क्या आप [-6,6] क्लैम्पिंग के बारे में निश्चित हैं? यदि यह सच है (और विकिपीडिया पृष्ठ पर एक नोट के योग्य) तो यह एक महत्वपूर्ण बिंदु है।
redcalx

1
@ लॉकर: यह मेरा एक शिक्षक ने मुझे बताया (उसने ऐसे जनरेटर का अध्ययन किया, और मुझे उसके शब्द पर भरोसा है)। मैं आपको एक संदर्भ खोजने में सक्षम हो सकता हूं।
अलेक्जेंड्रे सी।

7
@ लॉकर: यह अवांछनीय संपत्ति उलटा सीडीएफ विधि द्वारा भी साझा की जाती है। Cimat.mx/~src/prope08/randomgauss.pdf देखें । एक समान RNG का उपयोग करके इसे कम किया जा सकता है जिसमें गैर-शून्य संभावना है जो फ्लोटिंग पॉइंट संख्या को शून्य के बहुत करीब पहुंचाता है। अधिकांश RNG नहीं करते हैं, क्योंकि वे एक (आमतौर पर 64 बिट) पूर्णांक उत्पन्न करते हैं जो तब [0,1] पर मैप किया जाता है। यह उन तरीकों को गाऊसी चर के नमूने के नमूने के लिए अनुपयुक्त बनाता है (कम्प्यूटेशनल वित्त में कम / उच्च स्ट्राइक विकल्प के मूल्य निर्धारण के बारे में सोचें)।
अलेक्जेंड्रे सी।

6
@AlexandreC। बस दो बिंदुओं पर स्पष्ट होने के लिए, 64-बिट संख्याओं का उपयोग करके पूंछ 8.57 या 9.41 (लॉग लेने से पहले [0,1 में बदलने के लिए संबंधित कम मूल्य) के लिए निकल जाती है। यहां तक ​​कि अगर [-6, 6] से जुड़ा हुआ है, तो इस सीमा के बाहर होने की संभावना लगभग 1.98e-9 है, जो विज्ञान में भी अधिकांश लोगों के लिए पर्याप्त है। 8.57 और 9.41 के आंकड़ों के लिए यह 1.04e-17 और 4.97e-21 हो जाता है। ये संख्या इतनी कम है कि एक बॉक्स मुलर नमूने और उक्त सीमा के संदर्भ में एक सच्चे गॉसियन नमूने के बीच का अंतर लगभग पूरी तरह से अकादमिक है। यदि आपको बेहतर की जरूरत है, तो बस उनमें से चार को जोड़ें और 2 से विभाजित करें
क्राइस्टकास्ट

6
मुझे लगता है कि बॉक्स मुलर ट्रांसफॉर्म का उपयोग नहीं करने का सुझाव उपयोगकर्ताओं के एक बड़े प्रतिशत के लिए भ्रामक है। सीमा के बारे में जानना बहुत अच्छा है, लेकिन जैसा कि क्रेज़ीकास्ट बताते हैं, अधिकांश अनुप्रयोगों के लिए जो आउटलेर्स पर बहुत अधिक निर्भर नहीं हैं, आपको शायद इस बारे में चिंता करने की आवश्यकता नहीं है। एक उदाहरण के रूप में, यदि आप कभी भी खसखस ​​का उपयोग करके सामान्य से नमूने पर निर्भर करते हैं, तो आप बॉक्स मुलर ट्रांसफॉर्म (ध्रुवीय समन्वय रूप) github.com/numpy/numpy/blob/… पर निर्भर हैं ।
एंड्रियास ग्रिवस

30

किसी भी फ़ंक्शन के वितरण को दूसरे में बदलना, आपके इच्छित फ़ंक्शन के व्युत्क्रम का उपयोग करना शामिल है।

दूसरे शब्दों में, यदि आप किसी विशिष्ट प्रायिकता फ़ंक्शन p (x) का लक्ष्य रखते हैं, तो आप इस पर एकीकरण करके वितरण प्राप्त करते हैं -> d (x) = इंटीग्रल (p (x)) और इसके व्युत्क्रम का उपयोग करें: Inv (d (x)) । अब यादृच्छिक संभाव्यता फ़ंक्शन (जिसमें एक समान वितरण है) का उपयोग करें और फ़ंक्शन आमंत्रण (d (x)) के माध्यम से परिणाम मान डालें। आपके द्वारा चुने गए फ़ंक्शन के अनुसार आपको वितरण के साथ यादृच्छिक मान प्राप्त होने चाहिए।

यह जेनेरिक गणित दृष्टिकोण है - इसका उपयोग करके अब आप किसी भी संभावना या वितरण फ़ंक्शन को चुन सकते हैं, जब तक कि इसका उलटा या अच्छा उलटा सन्निकटन हो।

आशा है कि इस मदद और वितरण का उपयोग करने के बारे में छोटी टिप्पणी के लिए धन्यवाद और संभावना ही नहीं।


4
+1 यह गाऊसी चर बनाने के लिए एक अनदेखी पद्धति है जो बहुत अच्छी तरह से काम करती है। उलटा सीडीएफ को इस मामले में न्यूटन विधि के साथ कुशलता से गणना की जा सकती है (व्युत्पन्न ई ^ {- t ^ 2}) है, एक प्रारंभिक अनुमान एक तर्कसंगत अंश के रूप में प्राप्त करना आसान है, इसलिए आपको एरफ और एक्सप के 3-4 मूल्यांकन की आवश्यकता है। यह अनिवार्य है यदि आप अर्ध-यादृच्छिक संख्याओं का उपयोग करते हैं, तो ऐसा मामला जहां आपको गौसियन प्राप्त करने के लिए बिल्कुल एक समान संख्या का उपयोग करना होगा।
एलेक्जेंडर सी।

9
ध्यान दें कि आपको संचयी वितरण फ़ंक्शन को उलटने की आवश्यकता है, न कि संभावना वितरण फ़ंक्शन की। अलेक्जेंड्रे का तात्पर्य यह है, लेकिन मैंने सोचा कि इसका उल्लेख अधिक स्पष्ट रूप से चोटिल नहीं कर सकता है - क्योंकि उत्तर में पीडीएफ का सुझाव प्रतीत होता है
ltjax

यदि आप बेतरतीब ढंग से दिशा के सापेक्ष दिशा का चयन करने के लिए तैयार हैं, तो आप पीडीएफ का उपयोग कर सकते हैं; क्या मैं इसे सही समझता हूं?
मार्क मैककेना


1
यहाँ एसई से संबंधित प्रश्न अच्छा स्पष्टीकरण के साथ अधिक सामान्यीकृत उत्तर के साथ है।
द्वादशी

23

यहां बॉक्स-मुलर परिवर्तन के ध्रुवीय रूप का उपयोग करके एक जावास्क्रिप्ट कार्यान्वयन है।

/*
 * Returns member of set with a given mean and standard deviation
 * mean: mean
 * standard deviation: std_dev 
 */
function createMemberInNormalDistribution(mean,std_dev){
    return mean + (gaussRandom()*std_dev);
}

/*
 * Returns random number in normal distribution centering on 0.
 * ~95% of numbers returned should fall between -2 and 2
 * ie within two standard deviations
 */
function gaussRandom() {
    var u = 2*Math.random()-1;
    var v = 2*Math.random()-1;
    var r = u*u + v*v;
    /*if outside interval [0,1] start over*/
    if(r == 0 || r >= 1) return gaussRandom();

    var c = Math.sqrt(-2*Math.log(r)/r);
    return u*c;

    /* todo: optimize this algorithm by caching (v*c) 
     * and returning next time gaussRandom() is called.
     * left out for simplicity */
}

5

अपने लाभ के लिए केंद्रीय सीमा प्रमेय विकिपीडिया प्रविष्टि मैथवर्ल्ड प्रविष्टि का उपयोग करें।

समान रूप से वितरित संख्याओं के n उत्पन्न करें, उन्हें योग करें, n * 0.5 घटाएं और आपके पास लगभग सामान्य वितरण का उत्पादन 0 के बराबर होता है और समान रूप से भिन्न होता है (1/12) * (1/sqrt(N))( उस अंतिम एक के लिए समान वितरण पर विकिपीडिया देखें )

n = 10 आपको कुछ अच्छा आधा उपवास देता है। यदि आप टायलर समाधान के लिए आधे से अधिक सभ्य चाहते हैं (जैसा कि सामान्य वितरण पर विकिपीडिया प्रविष्टि में उल्लेख किया गया है )


1
यह एक विशेष रूप से करीब सामान्य ("पूंछ" या अंत-अंक वास्तविक सामान्य वितरण के करीब नहीं होगा) नहीं देगा। बॉक्स-मुलर बेहतर है, जैसा कि दूसरों ने सुझाव दिया है।
पीटर के।

1
बॉक्स मुलर में गलत पूंछ भी है (यह दोहरी सटीकता में -6 और 6 के बीच एक संख्या देता है)
एलेक्जेंडर सी।

n = 12 (योग 0 से 1 तक की संख्या में यादृच्छिक संख्या 6, और घटाएँ 6) stddev में परिणाम = 1 और माध्य = 0। इसके बाद किसी भी सामान्य वितरण को उत्पन्न करने के लिए उपयोग किया जा सकता है। बस वांछित stddev द्वारा परिणाम गुणा करें और माध्य जोड़ें।
जेरीएम

3

मैं बॉक्स-मुलर का उपयोग करूंगा। इसके बारे में दो बातें:

  1. आप प्रति बार दो मूल्यों के साथ समाप्त होते हैं
    आमतौर पर, आप एक मूल्य को कैश करते हैं और दूसरे को वापस करते हैं। एक नमूने के लिए अगले कॉल पर, आप कैश्ड मान वापस करते हैं।
  2. बॉक्स-मुलर एक जेड-स्कोर देता है
    आपको मानक विचलन द्वारा जेड-स्कोर को स्केल करना होगा और सामान्य वितरण में पूर्ण मूल्य प्राप्त करने के लिए साधन जोड़ना होगा।

आप जेड-स्कोर को कैसे मापेंगे?
टेरहॉस्ट

3
स्केल्ड = माध्य + stdDev * zScore // आपको सामान्य देता है (मतलब, stdDev ^ 2)
yoyoyoyosef

2

जहाँ R1, R2 यादृच्छिक समरूप संख्याएँ हैं:

1, sqrt (-2 * लॉग (R1)) * cos (2 * p * * R2) के एसडी के साथ सामान्य वितरण

यह सटीक है ... उन सभी धीमी छोरों को करने की कोई आवश्यकता नहीं है!


इससे पहले कि कोई मुझे सुधारे ... यहाँ सन्निकटता आई है: (१.५- (आर १ + आर २ + आर ३)) * १.) ...। मुझे भी यह पसंद है।
एरिक एरोनिटी

2

यह अविश्वसनीय लगता है कि मैं आठ साल के बाद इसमें कुछ जोड़ सकता हूं, लेकिन जावा के मामले में मैं पाठकों को रैंडम.नेक्स्टगॉसियन () विधि की ओर संकेत करना चाहूंगा , जो आपके लिए औसत 0.0 और मानक भक्ति 1.0 के साथ गौसियन वितरण उत्पन्न करता है।

एक साधारण जोड़ और / या गुणा आपकी आवश्यकताओं के औसत और मानक विचलन को बदल देगा।


1

मानक अजगर पुस्तकालय मॉड्यूल यादृच्छिक आप क्या चाहते हैं:

normalvariate (mu, sigma)
सामान्य वितरण। म्यू मतलब है, और सिग्मा मानक विचलन है।

एल्गोरिथ्म के लिए, पायथन लाइब्रेरी में random.py के फ़ंक्शन पर एक नज़र डालें।

मैनुअल प्रविष्टि यहाँ है


2
दुर्भाग्य से, अजगर की लाइब्रेरी किंडरमैन, ए जे और मोनाहन, जेएफ, "यूनिफॉर्म विचलन के अनुपात का उपयोग करके यादृच्छिक चर की कंप्यूटर पीढ़ी", एसीएम ट्रांस मठ सॉफ्टवेयर, 3, (1977), पीपी 257-260 का उपयोग करती है। यह सामान्य मान उत्पन्न करने के लिए एक समान के बजाय दो समान यादृच्छिक चर का उपयोग करता है, इसलिए यह स्पष्ट नहीं है कि ओपी चाहता था कि मैपिंग के रूप में इसका उपयोग कैसे किया जाए।
इयान

1

डोनाल्ड नथ की पुस्तक द आर्ट ऑफ़ कंप्यूटर प्रोग्रामिंग की धारा 3.4.1 से यह एल्गोरिथम पी ( सामान्य विचलन के लिए ध्रुवीय विधि ) का मेरा जावास्क्रिप्ट कार्यान्वयन है :

function normal_random(mean,stddev)
{
    var V1
    var V2
    var S
    do{
        var U1 = Math.random() // return uniform distributed in [0,1[
        var U2 = Math.random()
        V1 = 2*U1-1
        V2 = 2*U2-1
        S = V1*V1+V2*V2
    }while(S >= 1)
    if(S===0) return 0
    return mean+stddev*(V1*Math.sqrt(-2*Math.log(S)/S))
}

0

मुझे लगता है कि तुम EXCEL में यह कोशिश करनी चाहिए: =norminv(rand();0;1) :। यह यादृच्छिक संख्याओं का उत्पादन करेगा जो सामान्य रूप से शून्य माध्य और एकजुट संस्करण के साथ वितरित किया जाना चाहिए। "0" किसी भी मूल्य के साथ आपूर्ति की जा सकती है, ताकि संख्या वांछित साधन की हो, और "1" को बदलकर, आपको अपने इनपुट के वर्ग के बराबर विचरण मिलेगा।

उदाहरण के लिए: =norminv(rand();50;3)MEAN = 50 VARIANCE = 9 के साथ सामान्य रूप से वितरित संख्याओं के लिए उपज होगी।


0

Q मैं एक समान वितरण (जैसे सबसे यादृच्छिक संख्या जनरेटर का उत्पादन, जैसे 0.0 और 1.0 के बीच) को सामान्य वितरण में कैसे बदल सकता हूं?

  1. सॉफ्टवेयर कार्यान्वयन के लिए मुझे युगल यादृच्छिक जनरेटर नाम पता हैं जो आपको [0,1] में एक छद्म वर्दी यादृच्छिक अनुक्रम देते हैं (मेरसेन ट्विस्टर, लीनियर कग्रेट जेनरेटर)। चलो इसे यू (एक्स) कहते हैं

  2. यह गणितीय क्षेत्र है, जिसे संभाव्यता सिद्धांत कहा जाता है। पहली बात: यदि आप अभिन्न वितरण F के साथ rv मॉडल करना चाहते हैं तो आप F ^ -1 (U (x)) का मूल्यांकन करने का प्रयास कर सकते हैं। Pr.theory में यह साबित हुआ कि ऐसे rv का अभिन्न वितरण F होगा।

  3. चरण 2 किसी भी गिनती के तरीकों के उपयोग के बिना आरवी ~ एफ उत्पन्न करने के लिए प्रशंसनीय हो सकता है जब एफ -1 को समस्याओं के बिना विश्लेषणात्मक रूप से प्राप्त किया जा सकता है। (उदा। विस्तार)

  4. सामान्य वितरण को मॉडल करने के लिए आप y1 * cos (y2) को कैसक्यूलेट कर सकते हैं, जहां y1 ~ [0,2pi] में समान है। और y2 रेले वितरण है।

प्रश्न: क्या होगा अगर मुझे मेरे चयन का एक मतलब और मानक विचलन चाहिए?

आप सिग्मा * N (0,1) + m की गणना कर सकते हैं।

यह दिखाया जा सकता है कि इस तरह की शिफ्टिंग और स्केलिंग से N (m, sigma) को बढ़ावा मिलता है


0

यह बॉक्स-मुलर परिवर्तन के ध्रुवीय रूप का उपयोग करके एक मैटलैब कार्यान्वयन है :

समारोह randn_box_muller.m:

function [values] = randn_box_muller(n, mean, std_dev)
    if nargin == 1
       mean = 0;
       std_dev = 1;
    end

    r = gaussRandomN(n);
    values = r.*std_dev - mean;
end

function [values] = gaussRandomN(n)
    [u, v, r] = gaussRandomNValid(n);

    c = sqrt(-2*log(r)./r);
    values = u.*c;
end

function [u, v, r] = gaussRandomNValid(n)
    r = zeros(n, 1);
    u = zeros(n, 1);
    v = zeros(n, 1);

    filter = r==0 | r>=1;

    % if outside interval [0,1] start over
    while n ~= 0
        u(filter) = 2*rand(n, 1)-1;
        v(filter) = 2*rand(n, 1)-1;
        r(filter) = u(filter).*u(filter) + v(filter).*v(filter);

        filter = r==0 | r>=1;
        n = size(r(filter),1);
    end
end

और histfit(randn_box_muller(10000000),100);यह परिणाम है: बॉक्स-मुलर मतलाब हिस्टफिट

जाहिर है कि यह वास्तव में अक्षम है, जिसमें निर्मित मलबे की तुलना में रैंडन है


0

मेरे पास निम्नलिखित कोड हैं जो शायद मदद कर सकते हैं:

set.seed(123)
n <- 1000
u <- runif(n) #creates U
x <- -log(u)
y <- runif(n, max=u*sqrt((2*exp(1))/pi)) #create Y
z <- ifelse (y < dnorm(x)/2, -x, NA)
z <- ifelse ((y > dnorm(x)/2) & (y < dnorm(x)), x, z)
z <- z[!is.na(z)]

0

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

n <- length(z)
t0 <- Sys.time()
z <- rnorm(n)
t1 <- Sys.time()
t1-t0

-2
function distRandom(){
  do{
    x=random(DISTRIBUTION_DOMAIN);
  }while(random(DISTRIBUTION_RANGE)>=distributionFunction(x));
  return x;
}

वापसी की गारंटी नहीं है, हालांकि, यह है? ;-)
पीटर के।

5
रैंडम नंबर को मौका देने के लिए छोड़ा जाना बहुत जरूरी है।
ड्रू नोक

इस सवाल का जवाब नहीं है - सामान्य वितरण में एक अनंत डोमेन है।
मैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.