नोट: इस उत्तर के पीछे का कोड यहां पाया जा सकता है ।
मान लें कि हमारे पास कुछ डेटा दो अलग-अलग समूहों से लाल और नीले रंग के हैं:
यहां, हम देख सकते हैं कि कौन सा डेटा बिंदु लाल या नीले समूह का है। यह उन मापदंडों को खोजना आसान बनाता है जो प्रत्येक समूह को चिह्नित करते हैं। उदाहरण के लिए, लाल समूह का मतलब 3 के आसपास है, नीले समूह का मतलब लगभग 7 है (और अगर हम चाहते थे तो हम इसका सटीक मतलब पा सकते हैं)।
यह आम तौर पर बोल रहा है, अधिकतम संभावना अनुमान के रूप में जाना जाता है । कुछ आंकड़ों को देखते हुए, हम एक पैरामीटर (या पैरामीटर) के मूल्य की गणना करते हैं जो उस डेटा को सबसे अच्छा समझाता है।
अब कल्पना करें कि हम यह नहीं देख सकते हैं कि किस समूह से किस मूल्य का नमूना लिया गया है। सब कुछ हमें बैंगनी दिखता है:
यहां हमारे पास यह ज्ञान है कि मूल्यों के दो समूह हैं, लेकिन हम यह नहीं जानते कि कोई विशेष मूल्य किस समूह का है।
क्या हम अभी भी लाल समूह और नीले समूह के साधनों का अनुमान लगा सकते हैं जो इस डेटा को सबसे उपयुक्त मानते हैं?
हाँ, अक्सर हम कर सकते हैं! उम्मीद अधिकतमकरण हमें इसे करने का एक तरीका देता है। एल्गोरिथ्म के पीछे बहुत सामान्य विचार यह है:
- प्रत्येक पैरामीटर क्या हो सकता है, इसके प्रारंभिक अनुमान से शुरू करें।
- संभावना की गणना करें कि प्रत्येक पैरामीटर डेटा बिंदु का उत्पादन करता है।
- प्रत्येक डेटा बिंदु के लिए वजन की गणना करें, यह दर्शाता है कि यह एक पैरामीटर द्वारा उत्पादित होने की संभावना के आधार पर अधिक लाल या अधिक नीला है। डेटा ( अपेक्षा ) के साथ वजन को मिलाएं ।
- भार-समायोजित डेटा ( अधिकतमकरण ) का उपयोग करते हुए मापदंडों के लिए एक बेहतर अनुमान की गणना करें ।
- चरण 2 से 4 को तब तक दोहराएं जब तक कि पैरामीटर अनुमान न बदल जाए (प्रक्रिया अलग अनुमान लगाना बंद कर देती है)।
इन चरणों को कुछ और स्पष्टीकरण की आवश्यकता है, इसलिए मैं ऊपर वर्णित समस्या से गुजरूंगा।
उदाहरण: माध्य और मानक विचलन का अनुमान लगाना
मैं इस उदाहरण में पायथन का उपयोग करूँगा, लेकिन यदि आपको इस भाषा से परिचित नहीं है तो कोड को समझना काफी आसान होना चाहिए।
मान लें कि हमारे पास दो समूह हैं, लाल और नीला, जैसा कि ऊपर की छवि में वितरित मूल्यों के साथ है। विशेष रूप से, प्रत्येक समूह में निम्न मापदंडों के साथ एक सामान्य वितरण से लिया गया मूल्य होता है :
import numpy as np
from scipy import stats
np.random.seed(110) # for reproducible 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))) # for later use...
यहाँ इन लाल और नीले समूहों की एक छवि फिर से है (स्क्रॉल करने के लिए आपको बचाने के लिए):
जब हम प्रत्येक बिंदु का रंग देख सकते हैं (अर्थात यह किस समूह से संबंधित है), प्रत्येक समूह के लिए माध्य और मानक विचलन का अनुमान लगाना बहुत आसान है। हम सिर्फ NumPy में निर्मित कार्यों के लिए लाल और नीले मूल्यों को पास करते हैं। उदाहरण के लिए:
>>> np.mean(red)
2.802
>>> np.std(red)
0.871
>>> np.mean(blue)
6.932
>>> np.std(blue)
2.195
लेकिन क्या होगा अगर हम बिंदुओं के रंग नहीं देख सकते हैं? यही है, लाल या नीले रंग के बजाय, हर बिंदु को बैंगनी रंग दिया गया है।
लाल और नीले समूहों के लिए माध्य और मानक विचलन मापदंडों को आजमाने और पुनर्प्राप्त करने के लिए, हम एक्सपेक्टेशन मैक्सिमाइजेशन का उपयोग कर सकते हैं।
हमारा पहला चरण ( चरण 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 ) वर्तमान पैरामीटर अनुमान के तहत प्रदर्शित होने वाले प्रत्येक डेटा बिंदु की संभावना की गणना करना है:
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.189) नीले से (0.00003) की संभावना है।
प्रत्येक डेटा बिंदु के लिए, हम इन दो संभावना मानों को वज़न ( चरण 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):
"""
For each data point, multiply the point by the probability it
was drawn from the colour's distribution (its "weight").
Divide by the total weight: essentially, we're finding where
the weight is centred among our data points.
"""
return np.sum(data * weight) / np.sum(weight)
def estimate_std(data, weight, mean):
"""
For each data point, multiply the point's squared difference
from a mean value by the probability it was drawn from
that distribution (its "weight").
Divide by the total weight: essentially, we're finding where
the weight is centred among the values for the difference of
each data point from the mean.
This is the estimate of the variance, take the positive square
root to find the standard deviation.
"""
variance = np.sum(weight * (data - mean)**2) / np.sum(weight)
return np.sqrt(variance)
# 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 पर वापस जा सकते हैं और प्रक्रिया को दोहरा सकते हैं। हम अनुमानों के अभिसरण होने तक या कुछ पुनरावृत्तियों का प्रदर्शन करने के बाद ऐसा करते हैं ( चरण 5 )।
हमारे डेटा के लिए, इस प्रक्रिया के पहले पांच पुनरावृत्तियों इस तरह दिखते हैं (हाल ही में पुनरावृत्तियों की उपस्थिति मजबूत है):
हम देखते हैं कि साधन पहले से ही कुछ मूल्यों पर परिवर्तित हो रहे हैं, और घटता (मानक विचलन द्वारा शासित) का आकार भी अधिक स्थिर होता जा रहा है।
यदि हम 20 पुनरावृत्तियों के लिए जारी रखते हैं, तो हम निम्नलिखित को समाप्त करते हैं:
EM प्रक्रिया निम्न मानों में परिवर्तित हो गई है, जो वास्तविक मूल्यों के बहुत करीब पहुंच जाती हैं (जहां हम रंगों को देख सकते हैं - कोई छिपा हुआ चर नहीं):
| EM guess | Actual | Delta
----------+----------+--------+-------
Red mean | 2.910 | 2.802 | 0.108
Red std | 0.854 | 0.871 | -0.017
Blue mean | 6.838 | 6.932 | -0.094
Blue std | 2.227 | 2.195 | 0.032
ऊपर दिए गए कोड में आपने देखा होगा कि मानक विचलन के लिए नए अनुमान की गणना इस अर्थ के लिए पिछले पुनरावृत्ति अनुमान का उपयोग करके की गई थी। अंतत: इससे कोई फर्क नहीं पड़ता कि हम इस मतलब के लिए एक नए मूल्य की गणना करते हैं क्योंकि हम केवल कुछ केंद्रीय बिंदु के आसपास मूल्यों का विचरण (भारित) संस्करण खोज रहे हैं। हम अभी भी मापदंडों के अभिसरण के अनुमान देखेंगे।