यहाँ मतलब और मानक विचलन का अनुमान लगाने के लिए उपयोग किए जाने वाले एक्सपेक्टेशन मैक्सिमाइजेशन (ईएम) का एक उदाहरण है। कोड पाइथन में है, लेकिन यह आसान होना चाहिए, भले ही आप भाषा से परिचित न हों।
ईएम के लिए प्रेरणा
नीचे दिखाए गए लाल और नीले बिंदु दो अलग-अलग सामान्य वितरणों से तैयार किए गए हैं, जिनमें से प्रत्येक एक विशेष माध्य और मानक विचलन के साथ हैं:
लाल वितरण के लिए "सही" माध्य और मानक विचलन मापदंडों के उचित अनुमानों की गणना करने के लिए, हम बहुत आसानी से लाल बिंदुओं को देख सकते हैं और प्रत्येक की स्थिति को रिकॉर्ड कर सकते हैं, और फिर परिचित सूत्रों का उपयोग कर सकते हैं (और इसी तरह नीले समूह के लिए) ।
अब उस मामले पर विचार करें जहां हम जानते हैं कि अंकों के दो समूह हैं, लेकिन हम यह नहीं देख सकते हैं कि कौन सा बिंदु किस समूह का है। दूसरे शब्दों में, रंग छिपे हुए हैं:
यह बिल्कुल स्पष्ट नहीं है कि अंकों को दो समूहों में कैसे विभाजित किया जाए। अब हम केवल वितरण और लाल वितरण या नीले वितरण के मापदंडों के अनुमानों की गणना करने में असमर्थ हैं।
यह वह जगह है जहां ईएम का उपयोग समस्या को हल करने के लिए किया जा सकता है।
मापदंडों का अनुमान लगाने के लिए ईएम का उपयोग करना
यहाँ ऊपर दिखाए गए बिंदुओं को उत्पन्न करने के लिए उपयोग किया गया कोड है। आप सामान्य वितरण के वास्तविक साधनों और मानक विचलन को देख सकते हैं, जिनसे अंक खींचे गए थे। चर red
और blue
बिंदु क्रमशः लाल और नीले समूहों में प्रत्येक बिंदु को पकड़ते हैं:
import numpy as np
from scipy import stats
np.random.seed(110) # for reproducible random results
# set parameters
red_mean = 3
red_std = 0.8
blue_mean = 7
blue_std = 2
# draw 20 samples from normal distributions with red/blue parameters
red = np.random.normal(red_mean, red_std, size=20)
blue = np.random.normal(blue_mean, blue_std, size=20)
both_colours = np.sort(np.concatenate((red, blue)))
यदि हम प्रत्येक बिंदु का रंग देख सकते हैं, तो हम लाइब्रेरी फ़ंक्शंस का उपयोग करके साधनों और मानक विचलन को पुनर्प्राप्त करने का प्रयास करेंगे:
>>> np.mean(red)
2.802
>>> np.std(red)
0.871
>>> np.mean(blue)
6.932
>>> np.std(blue)
2.195
लेकिन जब से रंग हमसे छिपे हैं, हम EM प्रक्रिया शुरू करेंगे ...
सबसे पहले, हम केवल प्रत्येक समूह के मापदंडों ( चरण 1 ) के मूल्यों पर अनुमान लगाते हैं । इन अनुमानों का अच्छा होना जरूरी नहीं है:
# estimates for the mean
red_mean_guess = 1.1
blue_mean_guess = 9
# estimates for the standard deviation
red_std_guess = 2
blue_std_guess = 1.7
बहुत बुरा अनुमान है - मतलब यह है कि वे अंकों के समूह के किसी भी "मध्य" से एक लंबा रास्ता तय करते हैं।
ईएम के साथ जारी रखने और इन अनुमानों में सुधार करने के लिए, हम औसत और मानक विचलन ( चरण 2 ) के लिए इन अनुमानों के तहत दिखने वाले प्रत्येक डेटा बिंदु (इसके गुप्त रंग की परवाह किए बिना) की संभावना की गणना करते हैं ।
चर both_colours
प्रत्येक डेटा बिंदु रखता है। फ़ंक्शन stats.norm
दिए गए मापदंडों के साथ एक सामान्य वितरण के तहत बिंदु की संभावना की गणना करता है:
likelihood_of_red = stats.norm(red_mean_guess, red_std_guess).pdf(both_colours)
likelihood_of_blue = stats.norm(blue_mean_guess, blue_std_guess).pdf(both_colours)
यह हमें बताता है, उदाहरण के लिए, कि हमारे वर्तमान अनुमान से 1.761 पर डेटा बिंदु नीले (0.00003) की तुलना में लाल (0.189) होने की अधिक संभावना है।
हम इन दो संभावना मूल्यों को वज़न ( चरण 3 ) में बदल सकते हैं ताकि वे निम्नानुसार 1 का योग करें:
likelihood_total = likelihood_of_red + likelihood_of_blue
red_weight = likelihood_of_red / likelihood_total
blue_weight = likelihood_of_blue / likelihood_total
हमारे वर्तमान अनुमानों और हमारे नव-गणना किए गए भार के साथ, हम अब नए, संभवतः बेहतर, मापदंडों के लिए अनुमान ( चरण 4 ) की गणना कर सकते हैं । हमें माध्य के लिए एक फ़ंक्शन और मानक विचलन के लिए एक फ़ंक्शन की आवश्यकता है:
def estimate_mean(data, weight):
return np.sum(data * weight) / np.sum(weight)
def estimate_std(data, weight, mean):
variance = np.sum(weight * (data - mean)**2) / np.sum(weight)
return np.sqrt(variance)
ये डेटा के औसत और मानक विचलन के लिए सामान्य कार्यों के समान दिखते हैं। अंतर एक weight
पैरामीटर का उपयोग होता है जो प्रत्येक डेटा बिंदु पर एक वजन प्रदान करता है।
यह वेटिंग EM की कुंजी है। किसी डेटा बिंदु पर एक रंग का वजन जितना अधिक होता है, उतना अधिक डेटा बिंदु उस रंग के मापदंडों के लिए अगले अनुमानों को प्रभावित करता है। अंत में, यह प्रत्येक पैरामीटर को सही दिशा में खींचने का प्रभाव है।
इन कार्यों के साथ नए अनुमानों की गणना की जाती है:
# new estimates for standard deviation
blue_std_guess = estimate_std(both_colours, blue_weight, blue_mean_guess)
red_std_guess = estimate_std(both_colours, red_weight, red_mean_guess)
# new estimates for mean
red_mean_guess = estimate_mean(both_colours, red_weight)
blue_mean_guess = estimate_mean(both_colours, blue_weight)
बाद में चरण 2 से इन नए अनुमानों के साथ EM प्रक्रिया को दोहराया जाता है। हम दिए गए पुनरावृत्तियों की संख्या (20 कहते हैं) के लिए चरणों को दोहरा सकते हैं, या जब तक हम मापदंडों को नहीं देखते हैं।
पांच पुनरावृत्तियों के बाद, हम देखते हैं कि हमारे शुरुआती बुरे अनुमान बेहतर होने लगे हैं:
20 पुनरावृत्तियों के बाद, EM प्रक्रिया कमोबेश रूपांतरित हो गई है:
तुलना के लिए, यहां EM प्रक्रिया के परिणाम की गणना उन मूल्यों के साथ की गई है जहां रंग की जानकारी छिपी नहीं है:
| EM guess | Actual
----------+----------+--------
Red mean | 2.910 | 2.802
Red std | 0.854 | 0.871
Blue mean | 6.838 | 6.932
Blue std | 2.227 | 2.195
नोट: इस उत्तर को यहां स्टैक ओवरफ्लो पर मेरे उत्तर से अनुकूलित किया गया था ।