समस्या
मैं एक साधारण 2-गाऊसी मिश्रण आबादी के मॉडल मापदंडों को फिट करना चाहता हूं। Bayesian तरीकों के आसपास सभी प्रचार को देखते हुए मैं यह समझना चाहता हूं कि क्या इस समस्या के लिए Bayesian inference एक बेहतर उपकरण है जो पारंपरिक फिटिंग के तरीके हैं।
अब तक MCMC इस खिलौना उदाहरण में बहुत खराब प्रदर्शन करता है, लेकिन शायद मैं सिर्फ कुछ अनदेखी करता हूं। तो कोड देखते हैं।
उपकरण
मैं अजगर (2.7) + स्काइप स्टैक, lmfit 0.8 और PyMC 2.3 का उपयोग करूंगा।
विश्लेषण को पुन: पेश करने के लिए एक नोटबुक यहां पाया जा सकता है
डेटा जनरेट करें
पहले डेटा उत्पन्न करें:
from scipy.stats import distributions
# Sample parameters
nsamples = 1000
mu1_true = 0.3
mu2_true = 0.55
sig1_true = 0.08
sig2_true = 0.12
a_true = 0.4
# Samples generation
np.random.seed(3) # for repeatability
s1 = distributions.norm.rvs(mu1_true, sig1_true, size=round(a_true*nsamples))
s2 = distributions.norm.rvs(mu2_true, sig2_true, size=round((1-a_true)*nsamples))
samples = np.hstack([s1, s2])
इस samples
तरह दिखता है हिस्टोग्राम :
एक "व्यापक शिखर", घटकों को आंख से स्पॉट करना मुश्किल है।
शास्त्रीय दृष्टिकोण: हिस्टोग्राम फिट
आइए पहले शास्त्रीय दृष्टिकोण का प्रयास करें। Lmfit का उपयोग करके 2-चोटियों के मॉडल को परिभाषित करना आसान है:
import lmfit
peak1 = lmfit.models.GaussianModel(prefix='p1_')
peak2 = lmfit.models.GaussianModel(prefix='p2_')
model = peak1 + peak2
model.set_param_hint('p1_center', value=0.2, min=-1, max=2)
model.set_param_hint('p2_center', value=0.5, min=-1, max=2)
model.set_param_hint('p1_sigma', value=0.1, min=0.01, max=0.3)
model.set_param_hint('p2_sigma', value=0.1, min=0.01, max=0.3)
model.set_param_hint('p1_amplitude', value=1, min=0.0, max=1)
model.set_param_hint('p2_amplitude', expr='1 - p1_amplitude')
name = '2-gaussians'
अंत में हम सिंप्लेक्स एल्गोरिथ्म के साथ मॉडल फिट करते हैं:
fit_res = model.fit(data, x=x_data, method='nelder')
print fit_res.fit_report()
परिणाम निम्न छवि है (लाल धराशायी लाइनें केंद्र केंद्रित हैं):
भले ही समस्या कठिन हो, उचित प्रारंभिक मूल्यों और बाधाओं के साथ मॉडल काफी उचित अनुमान में परिवर्तित हो गए।
बायेसियन दृष्टिकोण: MCMC
मैं पीएमसीएच में पदानुक्रमित फैशन में मॉडल को परिभाषित करता हूं। centers
और sigmas
2 केंद्रों और 2 गाऊसी के 2 सिगमा का प्रतिनिधित्व करने वाले हाइपरपैरेटर्स के लिए पुजारी वितरण हैं। alpha
पहली जनसंख्या का अंश है और पूर्व वितरण यहाँ एक बीटा है।
एक श्रेणीगत चर दो आबादी के बीच चुनता है। यह मेरी समझ है कि इस चर को डेटा ( samples
) के समान आकार की आवश्यकता है ।
अंत में mu
और tau
नियतात्मक चर हैं जो सामान्य वितरण के मापदंडों को निर्धारित करते हैं (वे category
चर पर निर्भर करते हैं ताकि वे बेतरतीब ढंग से दो आबादी के लिए दो मूल्यों के बीच स्विच करें)।
sigmas = pm.Normal('sigmas', mu=0.1, tau=1000, size=2)
centers = pm.Normal('centers', [0.3, 0.7], [1/(0.1)**2, 1/(0.1)**2], size=2)
#centers = pm.Uniform('centers', 0, 1, size=2)
alpha = pm.Beta('alpha', alpha=2, beta=3)
category = pm.Categorical("category", [alpha, 1 - alpha], size=nsamples)
@pm.deterministic
def mu(category=category, centers=centers):
return centers[category]
@pm.deterministic
def tau(category=category, sigmas=sigmas):
return 1/(sigmas[category]**2)
observations = pm.Normal('samples_model', mu=mu, tau=tau, value=samples, observed=True)
model = pm.Model([observations, mu, tau, category, alpha, sigmas, centers])
फिर मैं एमसीएमसी को काफी लंबी संख्या में पुनरावृत्तियों के साथ चलाता हूं (1e5, ~ 60s मेरी मशीन पर):
mcmc = pm.MCMC(model)
mcmc.sample(100000, 30000)
हालाँकि परिणाम बहुत विषम हैं। उदाहरण के लिए ट्रेस (पहली आबादी का अंश) 0.4 के बजाय अभिसरण के लिए 0 पर जाता है और इसमें एक बहुत ही मजबूत ऑटोक्रेलेशन है:
इसके अलावा गौसियों के केंद्र भी रूपांतरित नहीं होते हैं। उदाहरण के लिए:
जैसा कि आप पूर्व चुनाव में देखते हैं, मैंने एमसीएमसी एल्गोरिथ्म को पूर्व की जनसंख्या अंश लिए बीटा वितरण का उपयोग करके "मदद" करने की कोशिश की । इसके अलावा केंद्र और सिग्मा के लिए पूर्व वितरण काफी उचित हैं (मुझे लगता है)।
तो यहां क्या हो रहा है? क्या मैं कुछ गलत कर रहा हूं या MCMC इस समस्या के लिए उपयुक्त नहीं है?
मैं समझता हूं कि MCMC विधि धीमी होगी, लेकिन तुच्छ हिस्टोग्राम फिट आबादी को हल करने में काफी बेहतर प्रदर्शन करता है।
proposal_distribution
और इसकाproposal_sd
उपयोगPrior
करना बेहतर क्यों है?