2017-04-21 3 views
9

एक फ़ंक्शन को देखते हुए जो एकाधिक चर पर निर्भर करता है, प्रत्येक एक निश्चित संभाव्यता वितरण के साथ, मैं फ़ंक्शन की संभाव्यता वितरण प्राप्त करने के लिए मोंटे कार्लो विश्लेषण कैसे कर सकता हूं। मैं आदर्श रूप से पैरामीटर की संख्या या पुनरावृत्तियों की संख्या में वृद्धि के रूप में उच्च प्रदर्शन करने के लिए समाधान की तरह होगा।मैं समीकरण पर मोंटे कार्लो विश्लेषण कैसे कर सकता हूं?

उदाहरण के तौर पर, मैंने total_time के लिए समीकरण प्रदान किया है जो कई अन्य मानकों पर निर्भर करता है।

import numpy as np 
import matplotlib.pyplot as plt 

size = 1000 

gym = [30, 30, 35, 35, 35, 35, 35, 35, 40, 40, 40, 45, 45] 

left = 5 
right = 10 
mode = 9 
shower = np.random.triangular(left, mode, right, size) 

argument = np.random.choice([0, 45], size, p=[0.9, 0.1]) 

mu = 15 
sigma = 5/3 
dinner = np.random.normal(mu, sigma, size) 

mu = 45 
sigma = 15/3 
work = np.random.normal(mu, sigma, size) 

brush_my_teeth = 2 

variables = gym, shower, dinner, argument, work, brush_my_teeth 
for variable in variables: 
    plt.figure() 
    plt.hist(variable) 
plt.show() 


def total_time(variables): 
    return np.sum(variables) 

जिम gym

बौछार shower

रात के खाने के dinner

तर्क argument

काम work

brush_my_teeth brush_my_teeth

+0

क्या आपने [pymc] (https://pymc-devs.github.io/pymc/tutorial.html) पैकेज को आजमाया है? – elphz

उत्तर

10

मौजूदा जवाब सही विचार है, लेकिन मुझे शक है आप size में सभी मान योग करने के लिए के रूप में nicogen किया है चाहता हूँ।

मुझे लगता है कि आप हिस्टोग्राम में आकार का प्रदर्शन करने के लिए अपेक्षाकृत बड़े size चुन रहे थे और इसके बजाय आप प्रत्येक श्रेणी से एक मान जोड़ना चाहते हैं। उदाहरण के लिए, हम प्रत्येक गतिविधि के एक उदाहरण की गणना करना चाहते हैं, 1000 उदाहरण नहीं।

पहला कोड ब्लॉक मानता है कि आप जानते हैं कि आपका फ़ंक्शन एक योग है और इसलिए योग की गणना करने के लिए तेज़ संख्यात्मक संक्षेप का उपयोग कर सकते हैं।

import numpy as np 
import matplotlib.pyplot as plt 

mc_trials = 10000 

gym = np.random.choice([30, 30, 35, 35, 35, 35, 
        35, 35, 40, 40, 40, 45, 45], mc_trials) 
brush_my_teeth = np.random.choice([2], mc_trials) 
argument = np.random.choice([0, 45], size=mc_trials, p=[0.9, 0.1]) 
dinner = np.random.normal(15, 5/3, size=mc_trials) 
work = np.random.normal(45, 15/3, size=mc_trials) 
shower = np.random.triangular(left=5, mode=9, right=10, size=mc_trials) 

col_per_trial = np.vstack([gym, brush_my_teeth, argument, 
      dinner, work, shower]) 

mc_function_trials = np.sum(col_per_trial,axis=0) 

plt.figure() 
plt.hist(mc_function_trials,30) 
plt.xlim([0,200]) 
plt.show() 

histogram

आप अपने कार्य को नहीं जानते हैं, या आसानी से फिर से पात्र चयन नहीं कर सकते हैं एक numpy तत्व के लिहाज से मैट्रिक्स आपरेशन के रूप में है, तो आप अभी भी बहुत तरह पाश कर सकते हैं के माध्यम से:

def total_time(variables): 
     return np.sum(variables) 

mc_function_trials = [total_time(col) for col in col_per_trial.T] 

आप "संभाव्यता वितरण" प्राप्त करने के बारे में पूछते हैं। जैसा कि हमने उपरोक्त किया है, हिस्टोग्राम प्राप्त करना आपके लिए काफी कुछ नहीं करता है। यह आपको एक दृश्य प्रतिनिधित्व देता है, लेकिन वितरण समारोह नहीं। फ़ंक्शन प्राप्त करने के लिए, हमें कर्नेल घनत्व अनुमान लगाने की आवश्यकता है। scikit-learn में एक डिब्बाबंद function and example है जो यह करता है।

from sklearn.neighbors import KernelDensity 
mc_function_trials = np.array(mc_function_trials) 
kde = (KernelDensity(kernel='gaussian', bandwidth=2) 
     .fit(mc_function_trials[:, np.newaxis])) 

density_function = lambda x: np.exp(kde.score_samples(x)) 

time_values = np.arange(200)[:, np.newaxis] 
plt.plot(time_values, density_function(time_values)) 

enter image description here

अब आप योग कम से कम 100 जा रहा है की संभावना की गणना कर सकते हैं, उदाहरण के लिए:

import scipy.integrate as integrate 
probability, accuracy = integrate.quad(density_function, 0, 100) 
print(probability) 
# prints 0.15809 
2

आप एक सरल for पाश के साथ की कोशिश की? सबसे पहले, अपने स्थिरांक और समारोह को परिभाषित करें। फिर, एक लूप एन बार (उदाहरण में 10'000) चलाएं, चर के लिए नए यादृच्छिक मान खींचें और प्रत्येक बार फ़ंक्शन परिणाम की गणना करें। अंत में, सभी परिणामों को results_dist पर संलग्न करें, फिर इसे साजिश करें।

import numpy as np 
import matplotlib.pyplot as plt 

gym = [30, 30, 35, 35, 35, 35, 35, 35, 40, 40, 40, 45, 45] 
brush_my_teeth = 2 
size = 1000 

def total_time(variables): 
    return np.sum(variables) 

results_dist = [] 
for i in range(10000): 
    shower = np.random.triangular(left=5, mode=9, right=10, size) 
    argument = np.random.choice([0, 45], size, p=[0.9, 0.1]) 
    dinner = np.random.normal(mu=15, sigma=5/3, size) 
    work = np.random.normal(mu=45, sigma=15/3, size) 

    variables = gym, shower, dinner, argument, work, brush_my_teeth 

    results_dist.append(total_time(variables)) 

plt.figure() 
plt.hist(results_dist) 
plt.show() 
+0

यह लगभग सही लगता है, हालांकि, मुझे लगता है कि पोस्टर ने 'जिम' सूची का उद्देश्य संभाव्यता वितरण का प्रतिनिधित्व करने के लिए किया था, और ऐसा लगता है कि आप अभी तक उस वितरण से नमूनाकरण नहीं कर रहे हैं। जिम वैरिएबल को सही तरीके से नमूना देने के लिए, आपको 'for' लूप में एक अतिरिक्त पंक्ति जोड़नी होगी जो अंतराल' np.arange (लेन (जिम)) पर एक यादृच्छिक पूर्णांक उत्पन्न करती है। फिर वितरण से नमूना देने के लिए उस जिम का उपयोग 'जिम' सूची में यादृच्छिक अनुक्रमणिका के रूप में करें। – stachyra

+0

इस कोड में वाक्यविन्यास त्रुटियां हैं। –

1

बात की इस तरह के लिए, मैं Halton sequences और इसी तरह करने के लिए देखने की सलाह देते अर्ध-यादृच्छिक कम विसंगति अनुक्रम।

values = sequence.get(10000) # generate a bunch of draws of 
for vals in values: 
    # vals will have a single sample of n quasi-random numbers 
    variables = # add whatever other stuff you need to your quasi-random values 
    results_dist.append(total_time(variables)) 

आप कुछ को देखें, तो:

import ghalton as gh 
sequence = gh.Halton(n) # n is the number of dimensions you want 

फिर अन्य उत्तर में से कुछ पर निर्माण, आप की तरह कुछ कर सकता है: ghalton पैकेज आसान एक नियतात्मक लेकिन कम विसंगति अनुक्रम उत्पन्न करने के लिए बनाता है अर्ध-यादृच्छिक अनुक्रमों पर शोध पत्रों के, उन्हें मोंटे कार्लो एकीकरण और नमूनाकरण जैसे अनुप्रयोगों के लिए अभिसरण का बेहतर काम करने के लिए दिखाया गया है। मूल रूप से आप अपने नमूने में यादृच्छिक-जैसी गुणों को बनाए रखते हुए खोज स्थान को समान रूप से कवर करते हैं, जिससे अधिकांश मामलों में तेज़ी से अभिसरण होता है।

यह मूल रूप से आपको n आयामों पर एक समान वितरण प्राप्त करता है। यदि आप कुछ आयामों में गैर-वर्दी वितरण चाहते हैं, तो आप तदनुसार अपने समान वितरण को बदल सकते हैं। मुझे यकीन नहीं है कि हैल्टन अनुक्रम की कम विसंगति संपत्ति पर इसका क्या असर होगा, लेकिन यह जांच के लायक हो सकता है।

संबंधित मुद्दे