প্রত্যাশা-ম্যাক্সিমাইজেশন বুঝতে সংখ্যার উদাহরণ


117

আমি এটি প্রয়োগ করতে এবং ব্যবহার করতে সক্ষম হতে ইএম অ্যালগরিদমকে ভালভাবে উপলব্ধি করার চেষ্টা করছি। আমি পুরো দিনটি তত্ত্ব এবং একটি কাগজ পড়তে কাটিয়েছি যেখানে রাডার থেকে আগত অবস্থানের তথ্য ব্যবহার করে একটি বিমান ট্র্যাক করতে ইএম ব্যবহার করা হয়। সত্য, আমি অন্তর্নিহিত ধারণাটি পুরোপুরি বুঝতে পারি বলে আমি মনে করি না। কেউ আমাকে একটি সহজ সংখ্যার জন্য ইএম এর কয়েকটি পুনরাবৃত্তি (3-4 বা 3-4) দেখানোর একটি সংখ্যাসূচক উদাহরণের দিকে ইঙ্গিত করতে পারে (যেমন গাউসীয় বিতরণের প্যারামিটারগুলি নির্ধারণ করতে বা সাইনোসয়েডাল সিরিজের ক্রমগুলি নির্ধারণ করে বা একটি লাইনে ফিট করে)।

এমনকি যদি কেউ আমাকে কোডের কোনও অংশে (সিন্থেটিক ডেটা সহ) নির্দেশ করতে পারে তবে আমি কোডটি দিয়ে পদক্ষেপ নেওয়ার চেষ্টা করতে পারি।


1
কে-মানেগুলি খুব ইম, তবে ধ্রুবক বৈচিত্র সহ এবং এটি তুলনামূলকভাবে সহজ।
EngrStudent

2
@ আরজস 21 আপনি কি দয়া করে বিমান সম্পর্কে উল্লিখিত কাগজ পোস্ট করতে পারেন? খুব আকর্ষণীয় মনে হচ্ছে। আপনাকে ধন্যবাদ
ওয়াকান টানকা

1
অনলাইনে একটি টিউটোরিয়াল রয়েছে যা এম অ্যালগরিদম "EM Demysified: একটি প্রত্যাশা-ম্যাক্সিমাইজেশন টিউটোরিয়াল" সম্পর্কে খুব স্পষ্ট গাণিতিক বোঝার সরবরাহ করার দাবি করেছে তবে উদাহরণটি এতটাই খারাপ যে এটি বোধগম্যতার সীমানারেখা তৈরি করে।
শমিসেন বিশেষজ্ঞ

উত্তর:


98

এটি একটি ব্যবহারিক এবং (আমার মতে) খুব স্বজ্ঞাত 'কয়েন-টস' উদাহরণ সহ ইএম শিখার একটি রেসিপি:

  1. এই সংক্ষিপ্ত EM টিউটোরিয়াল কাগজটি do এবং Batzoglou দ্বারা পড়ুন । এটি সেই স্কিমা যেখানে মুদ্রার টসের উদাহরণটি ব্যাখ্যা করা হয়েছে:

    এখানে চিত্র বর্ণনা লিখুন

  2. আপনার মাথায় প্রশ্ন চিহ্ন থাকতে পারে, বিশেষত প্রত্যাশা পদক্ষেপের সম্ভাবনাগুলি কোথা থেকে আসে regarding দয়া করে এই গণিতের স্ট্যাক এক্সচেঞ্জ পৃষ্ঠার ব্যাখ্যাগুলি দেখুন ।

  3. পাইথনে আমি লিখেছি এমন কোডটি দেখুন / চালান যা আইটেম 1 এর ইএম টিউটোরিয়াল পেপারে কয়েন-টস সমস্যার সমাধানের সিমুলেট করে:

    import numpy as np
    import math
    import matplotlib.pyplot as plt
    
    ## E-M Coin Toss Example as given in the EM tutorial paper by Do and Batzoglou* ##
    
    def get_binomial_log_likelihood(obs,probs):
        """ Return the (log)likelihood of obs, given the probs"""
        # Binomial Distribution Log PDF
        # ln (pdf)      = Binomial Coeff * product of probabilities
        # ln[f(x|n, p)] =   comb(N,k)    * num_heads*ln(pH) + (N-num_heads) * ln(1-pH)
    
        N = sum(obs);#number of trials  
        k = obs[0] # number of heads
        binomial_coeff = math.factorial(N) / (math.factorial(N-k) * math.factorial(k))
        prod_probs = obs[0]*math.log(probs[0]) + obs[1]*math.log(1-probs[0])
        log_lik = binomial_coeff + prod_probs
    
        return log_lik
    
    # 1st:  Coin B, {HTTTHHTHTH}, 5H,5T
    # 2nd:  Coin A, {HHHHTHHHHH}, 9H,1T
    # 3rd:  Coin A, {HTHHHHHTHH}, 8H,2T
    # 4th:  Coin B, {HTHTTTHHTT}, 4H,6T
    # 5th:  Coin A, {THHHTHHHTH}, 7H,3T
    # so, from MLE: pA(heads) = 0.80 and pB(heads)=0.45
    
    # represent the experiments
    head_counts = np.array([5,9,8,4,7])
    tail_counts = 10-head_counts
    experiments = zip(head_counts,tail_counts)
    
    # initialise the pA(heads) and pB(heads)
    pA_heads = np.zeros(100); pA_heads[0] = 0.60
    pB_heads = np.zeros(100); pB_heads[0] = 0.50
    
    # E-M begins!
    delta = 0.001  
    j = 0 # iteration counter
    improvement = float('inf')
    while (improvement>delta):
        expectation_A = np.zeros((len(experiments),2), dtype=float) 
        expectation_B = np.zeros((len(experiments),2), dtype=float)
        for i in range(0,len(experiments)):
            e = experiments[i] # i'th experiment
              # loglikelihood of e given coin A:
            ll_A = get_binomial_log_likelihood(e,np.array([pA_heads[j],1-pA_heads[j]])) 
              # loglikelihood of e given coin B
            ll_B = get_binomial_log_likelihood(e,np.array([pB_heads[j],1-pB_heads[j]])) 
    
              # corresponding weight of A proportional to likelihood of A 
            weightA = math.exp(ll_A) / ( math.exp(ll_A) + math.exp(ll_B) ) 
    
              # corresponding weight of B proportional to likelihood of B
            weightB = math.exp(ll_B) / ( math.exp(ll_A) + math.exp(ll_B) ) 
    
            expectation_A[i] = np.dot(weightA, e) 
            expectation_B[i] = np.dot(weightB, e)
    
        pA_heads[j+1] = sum(expectation_A)[0] / sum(sum(expectation_A)); 
        pB_heads[j+1] = sum(expectation_B)[0] / sum(sum(expectation_B)); 
    
        improvement = ( max( abs(np.array([pA_heads[j+1],pB_heads[j+1]]) - 
                        np.array([pA_heads[j],pB_heads[j]]) )) )
        j = j+1
    
    plt.figure();
    plt.plot(range(0,j),pA_heads[0:j], 'r--')
    plt.plot(range(0,j),pB_heads[0:j])
    plt.show()
    

2
@ ঝুবার্ব: আপনি দয়া করে লুপ সমাপ্তির শর্তটি ব্যাখ্যা করতে পারেন (উদাহরণস্বরূপ যখন অ্যালগরিদম রূপান্তরিত হয়)? "উন্নতি" পরিবর্তনশীল গণনা করে কি?
stackoverflowuser2010 21

1) এর মধ্যে পরিবর্তন করুন: @ stackoverflowuser2010, উন্নতি দুই বদ্বীপ এ দেখায় pA_heads[j+1]এবং pA_heads[j]এবং 2) মধ্যে পরিবর্তন pB_heads[j+1]এবং pB_heads[j]। এবং এটি দুটি পরিবর্তন সর্বাধিক লাগে। উদাহরণ হিসেবে বলা যায় যদি Delta_A=0.001এবং Delta_B=0.02পদক্ষেপ থেকে উন্নতি jকরতে j+1হবে 0.02
ঝুবার্ব

1
@ ঝুবার্ব: ইএম-তে কম্পিউটিং কনভার্জেন্সের জন্য এটি কি একটি আদর্শ পদ্ধতি, বা আপনি যে কিছু নিয়ে এসেছিলেন? যদি এটি একটি আদর্শ পদ্ধতির হয়, আপনি দয়া করে একটি রেফারেন্স উদ্ধৃত করতে পারেন?
stackoverflowuser2010

এখানে ইএম এর রূপান্তর সম্পর্কে একটি উল্লেখ আছে। আমি কোডটি কিছু সময় আগে লিখেছিলাম তাই খুব ভাল মনে করতে পারে না। আমি বিশ্বাস করি আপনি কোডটিতে যা দেখছেন তা হ'ল এই বিশেষ মামলার জন্য আমার রূপান্তর মানদণ্ড crit ধারণাটি হ'ল পুনরাবৃত্তিগুলি বন্ধ করা যখন এ এবং বি এর সর্বাধিক উন্নতি কম হয় delta
ঝুবার্ব

1
চমত্কার, পাঠ্যের অনুচ্ছেদগুলি কী কী পারে না তা স্পষ্ট করার জন্য কিছু ভাল কোডের মতো কিছুই নেই
jon_simon

63

মনে হচ্ছে আপনার প্রশ্নের দুটি অংশ রয়েছে: অন্তর্নিহিত ধারণা এবং একটি দৃ concrete় উদাহরণ। আমি অন্তর্নিহিত ধারণা দিয়ে শুরু করব, তারপরে নীচে একটি উদাহরণে লিঙ্ক করব।


যেখানে এটি দেখে মনে হচ্ছে আপনাকে জানতে হবে ই.এম. ক্যাচ-22 পরিস্থিতিতে দরকারী আগে আপনি নিরূপণ করতে পারেন এবং আপনাকে জানতে হবে আগে আপনি নিরূপণ করতে পারেন ।বি বি ABBA

লোকেদের মধ্যে সবচেয়ে সাধারণ ক্ষেত্রে সম্ভবত মিশ্রণ বিতরণ। আমাদের উদাহরণস্বরূপ, আসুন একটি সাধারণ গাউসিয়ান মিশ্রণ মডেলটি দেখুন:

আপনার বিভিন্ন উপায়ে এবং এককের বৈকল্পিকতার সাথে দুটি পৃথক অদ্বিতীয় গাউসীয় বিতরণ রয়েছে।

আপনার কাছে প্রচুর ডেটা পয়েন্ট রয়েছে তবে আপনি নিশ্চিত নন কোন পয়েন্টটি কোন বিতরণ থেকে এসেছে এবং আপনি দুটি বিতরণের মাধ্যম সম্পর্কেও নিশ্চিত নন।

এবং এখন আপনি আটকে আছেন:

  • আপনি যদি সত্যিকারের উপায়গুলি জানতেন তবে আপনি বুঝতে পারবেন কোন ডেটা পয়েন্টগুলি কোন গাউসিয়ান থেকে এসেছে। উদাহরণস্বরূপ, যদি কোনও ডেটা পয়েন্টের খুব উচ্চ মান থাকে তবে এটি সম্ভবত উচ্চতর গড় দিয়ে বিতরণ থেকে আসে। তবে আপনি কী জানেন এর অর্থ কী, তাই এটি কার্যকর হবে না।

  • আপনি যদি জানতেন যে প্রতিটি বিন্দুটি কোন বিতরণ থেকে এসেছে, তবে আপনি দুটি বিতরণের অর্থ প্রাসঙ্গিক পয়েন্টগুলির নমুনা ব্যবহার করে অনুমান করতে পারেন could তবে কোন বিতরণে কোন পয়েন্ট নির্ধারিত হবে তা আপনি আসলে জানেন না, সুতরাং এটি কোনও কাজ করে না either

সুতরাং উভয়েরই মতামত এটির মতো কাজ করে না বলে মনে হয়: উত্তরটি খুঁজে পাওয়ার আগে আপনাকে উত্তরটি জানতে হবে এবং আপনি আটকে আছেন।

ইএম আপনাকে যা করতে দেয় তা হ'ল পুরো প্রক্রিয়াটি একবারে সামলানোর পরিবর্তে এই দুটি ট্র্যাকটেবল পদক্ষেপের মধ্যে বিকল্প।

দুটি উপায় সম্পর্কে আপনার অনুমানের সাথে শুরু করতে হবে (যদিও আপনার অনুমানটি খুব সঠিক হতে হবে না তবে আপনাকে কোথাও শুরু করার দরকার নেই)।

যদি উপায়টির বিষয়ে আপনার অনুমানটি সঠিক হয় তবে উপরের আমার প্রথম বুলেট পয়েন্টের পদক্ষেপটি গ্রহণ করার জন্য আপনার কাছে পর্যাপ্ত তথ্য থাকতে হবে এবং আপনি (সম্ভাব্যতার সাথে) দুটি গাউসিয়ানদের মধ্যে একটিতে প্রতিটি তথ্য পয়েন্ট নির্ধারণ করতে পারবেন। যদিও আমরা জানি আমাদের অনুমানটি ভুল, তবে যাক যাইহোক এটি চেষ্টা করুন। এবং তারপরে, প্রতিটি পয়েন্টের নির্ধারিত বিতরণগুলি দেওয়া হলে আপনি দ্বিতীয় বুলেট পয়েন্টটি ব্যবহার করার জন্য নতুন অনুমান পেতে পারেন। দেখা যাচ্ছে যে, প্রতিবার আপনি এই দুটি পদক্ষেপের মধ্য দিয়ে লুপ করবেন, আপনি মডেলের সম্ভাবনার উপর নিম্ন সীমা উন্নতি করছেন।

এটি ইতিমধ্যে বেশ দুর্দান্ত: যদিও উপরের বুলেট পয়েন্টগুলিতে দুটি পরামর্শ স্বতন্ত্রভাবে কাজ করবে বলে মনে হচ্ছে না, তবুও আপনি তাদের মডেলটি উন্নত করতে একসাথে ব্যবহার করতে পারেন। EM এর আসল যাদুটি হ'ল, পর্যাপ্ত পুনরাবৃত্তির পরে, নিম্ন সীমাটি এত বেশি হবে যে এটির এবং স্থানীয় সর্বাধিকের মধ্যে কোনও স্থান থাকবে না। ফলস্বরূপ, এবং আপনি স্থানীয়ভাবে সম্ভাবনাটি অনুকূলিত করেছেন।

সুতরাং আপনি কেবলমাত্র মডেলটির উন্নতি করেননি , আপনি বর্ধিত আপডেটের সাথে সর্বাধিক সম্ভাব্য মডেল খুঁজে পেতে পারেন।


উইকিপিডিয়া থেকে এই পৃষ্ঠাটি আরও কিছু জটিল উদাহরণ দেখায় (দ্বি-মাত্রিক গাউসিয়ান এবং অজানা সমবায়), তবে মূল ধারণাটি একই। Rউদাহরণটি কার্যকর করার জন্য এটিতে ভাল মন্তব্য করা কোডও রয়েছে ।

কোডটিতে, "প্রত্যাশা" পদক্ষেপটি (ই-পদক্ষেপ) আমার প্রথম বুলেট পয়েন্টের সাথে সামঞ্জস্য করে: প্রতিটি গাউসিয়ান বর্তমান প্যারামিটারগুলি প্রদান করে গাউসীয় প্রতিটি ডেটার পয়েন্টের জন্য কোন দায়বদ্ধতা অর্জন করবে তা নির্ধারণ করে। "ম্যাক্সিমাইজেশন" পদক্ষেপ (এম-পদক্ষেপ) আমার দ্বিতীয় বুলেট পয়েন্টের মতো এই অ্যাসাইনমেন্টগুলি প্রদত্ত উপায়গুলি এবং সমবায়িকাগুলি আপডেট করে।

অ্যানিমেশনটিতে আপনি দেখতে পাচ্ছেন, এই আপডেটগুলি দ্রুত অ্যালগরিদমকে ভয়ঙ্কর অনুমানের সেট থেকে খুব ভাল একটি সেটগুলিতে যেতে দেয়: ইএম খুঁজে পাওয়া দুটি গাউসীয় বিতরণকে কেন্দ্র করে সেখানে দুটি পয়েন্টের মেঘই সত্যই উপস্থিত রয়েছে বলে মনে হয়।


12

গড় এবং স্ট্যান্ডার্ড বিচ্যুতি অনুমান করার জন্য এখানে প্রত্যাশা ম্যাক্সিমাইজেশন (ইএম) এর একটি উদাহরণ রয়েছে। কোডটি পাইথনে রয়েছে, তবে আপনি ভাষাটির সাথে পরিচিত না থাকলেও এটি অনুসরণ করা সহজ হওয়া উচিত।

ইমের জন্য প্রেরণা

নীচে দেখানো লাল এবং নীল পয়েন্ট দুটি পৃথক সাধারণ বিতরণ থেকে আঁকা, যার প্রতিটি নির্দিষ্ট গড় এবং মানক বিচ্যুতি:

এখানে চিত্র বর্ণনা লিখুন

লাল বিতরণের জন্য "সত্য" গড় এবং স্ট্যান্ডার্ড বিচ্যুতি পরামিতিগুলির যুক্তিসঙ্গত অনুমানগুলি গণনা করতে আমরা খুব সহজেই লাল পয়েন্টগুলিতে নজর দিতে পারি এবং প্রত্যেকের অবস্থান রেকর্ড করতে পারি, এবং তারপরে পরিচিত সূত্রগুলি (এবং একইভাবে নীল দলের জন্য) ব্যবহার করতে পারি ।

এখন কেসটি বিবেচনা করুন যেখানে আমরা জানি যে পয়েন্টের দুটি গ্রুপ রয়েছে তবে আমরা দেখতে পাচ্ছি না কোন পয়েন্টটি কোন গ্রুপের অন্তর্গত। অন্য কথায়, রঙগুলি লুকানো রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

কীভাবে পয়েন্টগুলি দুটি গ্রুপে ভাগ করা যায় তা মোটেই সুস্পষ্ট নয়। আমরা এখন কেবলমাত্র লাল বিতরণ বা নীল বিতরণের পরামিতিগুলির অবস্থানগুলি এবং গণনা অনুমানগুলি সন্ধান করতে অক্ষম।

এই সমস্যাটি সমাধান করতে ইএম ব্যবহার করা যেতে পারে।

প্যারামিটারগুলি অনুমান করতে EM ব্যবহার করা হচ্ছে

উপরে বর্ণিত পয়েন্টগুলি তৈরি করতে এখানে কোড ব্যবহৃত হচ্ছে। আপনি যে পয়েন্টগুলি থেকে আঁকেন সেগুলি সাধারণ বিতরণের প্রকৃত উপায় এবং মানক বিচ্যুতিগুলি আপনি দেখতে পারেন। ভেরিয়েবলগুলি 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

তবে যেহেতু রঙগুলি আমাদের থেকে লুকানো রয়েছে, তাই আমরা ইএম প্রক্রিয়াটি শুরু করব ...

প্রথমত, আমরা কেবলমাত্র প্রতিটি গ্রুপের পরামিতিগুলির জন্য মানগুলি অনুমান করি ( পদক্ষেপ 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 ( ধাপ 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)

EM প্রক্রিয়াটি এই ধাপে দ্বিতীয় ধাপ থেকে পরবর্তী ধাপে পুনরাবৃত্তি হয়। প্রদত্ত সংখ্যার পুনরাবৃত্তির জন্য পদক্ষেপগুলি পুনরায় বলতে পারি (20 বলুন), বা প্যারামিটারগুলি রূপান্তর না হওয়া পর্যন্ত।

পাঁচটি পুনরাবৃত্তির পরে, আমরা দেখতে পাই আমাদের প্রাথমিক খারাপ অনুমানগুলি আরও ভাল হতে শুরু করে:

এখানে চিত্র বর্ণনা লিখুন

20 টি পুনরাবৃত্তির পরে, 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

দ্রষ্টব্য: এই উত্তরটি এখানে স্ট্যাক ওভারফ্লোতে আমার উত্তর থেকে অভিযোজিত হয়েছিল ।


10

ঝুবার্বের জবাব অনুসরণ করে, আমি জিএনইউ আর-তে ডো এবং বাটজোগ্লো "কয়েন টসিং" ইএম উদাহরণটি প্রয়োগ করেছি। নোট করুন যে আমি প্যাকেজের mleফাংশনটি ব্যবহার করি stats4- এটি আমাকে এমএম এবং এমএলএর সাথে কীভাবে সম্পর্কিত তা আরও পরিষ্কারভাবে বুঝতে সাহায্য করেছিল।

require("stats4");

## sample data from Do and Batzoglou
ds<-data.frame(heads=c(5,9,8,4,7),n=c(10,10,10,10,10),
    coin=c("B","A","A","B","A"),weight_A=1:5*0)

## "baby likelihood" for a single observation
llf <- function(heads, n, theta) {
  comb <- function(n, x) { #nCr function
    return(factorial(n) / (factorial(x) * factorial(n-x)))
  }
  if (theta<0 || theta >1) { # probabilities should be in [0,1]
    return(-Inf);
  }
  z<-comb(n,heads)* theta^heads * (1-theta)^(n-heads);
  return (log(z))
}

## the "E-M" likelihood function
em <- function(theta_A,theta_B) {
  # expectation step: given current parameters, what is the likelihood
  # an observation is the result of tossing coin A (vs coin B)?
  ds$weight_A <<- by(ds, 1:nrow(ds), function(row) {
    llf_A <- llf(row$heads,row$n, theta_A);
    llf_B <- llf(row$heads,row$n, theta_B);

    return(exp(llf_A)/(exp(llf_A)+exp(llf_B)));
  })

  # maximisation step: given params and weights, calculate likelihood of the sample
  return(- sum(by(ds, 1:nrow(ds), function(row) {
    llf_A <- llf(row$heads,row$n, theta_A);
    llf_B <- llf(row$heads,row$n, theta_B);

    return(row$weight_A*llf_A + (1-row$weight_A)*llf_B);
  })))
}

est<-mle(em,start = list(theta_A=0.6,theta_B=0.5), nobs=NROW(ds))

1
@ ব্যবহারকারী 3096626 আপনি দয়া করে ব্যাখ্যা করতে পারেন কেন সর্বাধিকীকরণের পদক্ষেপে আপনি কোনও লগের সম্ভাবনা (এলএলএফ_এ) দ্বারা একটি কয়েনের (সারি $ ওজন_এ) সম্ভাবনা বৃদ্ধি করেন? আমরা এটি করার একটি বিশেষ নিয়ম বা কারণ আছে? আমি বোঝাতে চাইছি যে কেউ কেবল সম্ভাবনা বা লগ লাইকহুলসগুলিকে গুন করে তবে হেমকে একসাথে মিশ্রিত করে না। আমি একটি নতুন খোলা বিষয়
আলিনা

9

উপরের সমস্তগুলি দুর্দান্ত সংস্থানগুলির মতো দেখায় তবে আমি অবশ্যই এই দুর্দান্ত উদাহরণটির সাথে লিঙ্ক করব। এটি বিন্দুগুলির একটি সেট দুটি লাইনের জন্য পরামিতিগুলি সন্ধানের জন্য খুব সাধারণ ব্যাখ্যা উপস্থাপন করে। টিউটোরিয়ালটি এমআইটিতে থাকাকালীন ইয়ার ওয়েইসের লেখা।

http://www.cs.huji.ac.il/~yweiss/emTutorial.pdf
http://www.cs.huji.ac.il/~yweiss/tutorials.html


5

ঝুবার্বের দেওয়া উত্তরটি দুর্দান্ত তবে দুর্ভাগ্যক্রমে এটি পাইথনে রয়েছে। নীচে একই সমস্যার উপর কার্যকর EM অ্যালগরিদমের জাভা বাস্তবায়ন দেওয়া হয়েছে (দো এবং ব্যাটজোগ্লো, ২০০৮ এর নিবন্ধে পোজ দেওয়া হয়েছে)। প্যারামিটারগুলি কীভাবে রূপান্তরিত হয় তা দেখতে আমি স্ট্যান্ডার্ড আউটপুটে কিছু প্রিন্টফ যুক্ত করেছি।

thetaA = 0.71301, thetaB = 0.58134
thetaA = 0.74529, thetaB = 0.56926
thetaA = 0.76810, thetaB = 0.54954
thetaA = 0.78316, thetaB = 0.53462
thetaA = 0.79106, thetaB = 0.52628
thetaA = 0.79453, thetaB = 0.52239
thetaA = 0.79593, thetaB = 0.52073
thetaA = 0.79647, thetaB = 0.52005
thetaA = 0.79667, thetaB = 0.51977
thetaA = 0.79674, thetaB = 0.51966
thetaA = 0.79677, thetaB = 0.51961
thetaA = 0.79678, thetaB = 0.51960
thetaA = 0.79679, thetaB = 0.51959
Final result:
thetaA = 0.79678, thetaB = 0.51960

জাভা কোড নীচে অনুসরণ:

import java.util.*;

/*****************************************************************************
This class encapsulates the parameters of the problem. For this problem posed
in the article by (Do and Batzoglou, 2008), the parameters are thetaA and
thetaB, the probability of a coin coming up heads for the two coins A and B.
*****************************************************************************/
class Parameters
{
    double _thetaA = 0.0; // Probability of heads for coin A.
    double _thetaB = 0.0; // Probability of heads for coin B.

    double _delta = 0.00001;

    public Parameters(double thetaA, double thetaB)
    {
        _thetaA = thetaA;
        _thetaB = thetaB;
    }

    /*************************************************************************
    Returns true if this parameter is close enough to another parameter
    (typically the estimated parameter coming from the maximization step).
    *************************************************************************/
    public boolean converged(Parameters other)
    {
        if (Math.abs(_thetaA - other._thetaA) < _delta &&
            Math.abs(_thetaB - other._thetaB) < _delta)
        {
            return true;
        }

        return false;
    }

    public double getThetaA()
    {
        return _thetaA;
    }

    public double getThetaB()
    {
        return _thetaB;
    }

    public String toString()
    {
        return String.format("thetaA = %.5f, thetaB = %.5f", _thetaA, _thetaB);
    }

}


/*****************************************************************************
This class encapsulates an observation, that is the number of heads
and tails in a trial. The observation can be either (1) one of the
observed observations, or (2) an estimated observation resulting from
the expectation step.
*****************************************************************************/
class Observation
{
    double _numHeads = 0;
    double _numTails = 0;

    public Observation(String s)
    {
        for (int i = 0; i < s.length(); i++)
        {
            char c = s.charAt(i);

            if (c == 'H')
            {
                _numHeads++;
            }
            else if (c == 'T')
            {
                _numTails++;
            }
            else
            {
                throw new RuntimeException("Unknown character: " + c);
            }
        }
    }

    public Observation(double numHeads, double numTails)
    {
        _numHeads = numHeads;
        _numTails = numTails;
    }

    public double getNumHeads()
    {
        return _numHeads;
    }

    public double getNumTails()
    {
        return _numTails;
    }

    public String toString()
    {
        return String.format("heads: %.1f, tails: %.1f", _numHeads, _numTails);
    }

}

/*****************************************************************************
This class runs expectation-maximization for the problem posed by the article
from (Do and Batzoglou, 2008).
*****************************************************************************/
public class EM
{
    // Current estimated parameters.
    private Parameters _parameters;

    // Observations from the trials. These observations are set once.
    private final List<Observation> _observations;

    // Estimated observations per coin. These observations are the output
    // of the expectation step.
    private List<Observation> _expectedObservationsForCoinA;
    private List<Observation> _expectedObservationsForCoinB;

    private static java.io.PrintStream o = System.out;

    /*************************************************************************
    Principal constructor.
    @param observations The observations from the trial.
    @param parameters The initial guessed parameters.
    *************************************************************************/
    public EM(List<Observation> observations, Parameters parameters)
    {
        _observations = observations;
        _parameters = parameters;
    }

    /*************************************************************************
    Run EM until parameters converge.
    *************************************************************************/
    public Parameters run()
    {

        while (true)
        {
            expectation();

            Parameters estimatedParameters = maximization();

            o.printf("%s\n", estimatedParameters);

            if (_parameters.converged(estimatedParameters)) {
                break;
            }

            _parameters = estimatedParameters;
        }

        return _parameters;

    }

    /*************************************************************************
    Given the observations and current estimated parameters, compute new
    estimated completions (distribution over the classes) and observations.
    *************************************************************************/
    private void expectation()
    {

        _expectedObservationsForCoinA = new ArrayList<Observation>();
        _expectedObservationsForCoinB = new ArrayList<Observation>();

        for (Observation observation : _observations)
        {
            int numHeads = (int)observation.getNumHeads();
            int numTails = (int)observation.getNumTails();

            double probabilityOfObservationForCoinA=
                binomialProbability(10, numHeads, _parameters.getThetaA());

            double probabilityOfObservationForCoinB=
                binomialProbability(10, numHeads, _parameters.getThetaB());

            double normalizer = probabilityOfObservationForCoinA +
                                probabilityOfObservationForCoinB;

            // Compute the completions for coin A and B (i.e. the probability
            // distribution of the two classes, summed to 1.0).

            double completionCoinA = probabilityOfObservationForCoinA /
                                     normalizer;
            double completionCoinB = probabilityOfObservationForCoinB /
                                     normalizer;

            // Compute new expected observations for the two coins.

            Observation expectedObservationForCoinA =
                new Observation(numHeads * completionCoinA,
                                numTails * completionCoinA);

            Observation expectedObservationForCoinB =
                new Observation(numHeads * completionCoinB,
                                numTails * completionCoinB);

            _expectedObservationsForCoinA.add(expectedObservationForCoinA);
            _expectedObservationsForCoinB.add(expectedObservationForCoinB);
        }
    }

    /*************************************************************************
    Given new estimated observations, compute new estimated parameters.
    *************************************************************************/
    private Parameters maximization()
    {

        double sumCoinAHeads = 0.0;
        double sumCoinATails = 0.0;
        double sumCoinBHeads = 0.0;
        double sumCoinBTails = 0.0;

        for (Observation observation : _expectedObservationsForCoinA)
        {
            sumCoinAHeads += observation.getNumHeads();
            sumCoinATails += observation.getNumTails();
        }

        for (Observation observation : _expectedObservationsForCoinB)
        {
            sumCoinBHeads += observation.getNumHeads();
            sumCoinBTails += observation.getNumTails();
        }

        return new Parameters(sumCoinAHeads / (sumCoinAHeads + sumCoinATails),
                              sumCoinBHeads / (sumCoinBHeads + sumCoinBTails));

        //o.printf("parameters: %s\n", _parameters);

    }

    /*************************************************************************
    Since the coin-toss experiment posed in this article is a Bernoulli trial,
    use a binomial probability Pr(X=k; n,p) = (n choose k) * p^k * (1-p)^(n-k).
    *************************************************************************/
    private static double binomialProbability(int n, int k, double p)
    {
        double q = 1.0 - p;
        return nChooseK(n, k) * Math.pow(p, k) * Math.pow(q, n-k);
    }

    private static long nChooseK(int n, int k)
    {
        long numerator = 1;

        for (int i = 0; i < k; i++)
        {
            numerator = numerator * n;
            n--;
        }

        long denominator = factorial(k);

        return (long)(numerator / denominator);
    }

    private static long factorial(int n)
    {
        long result = 1;
        for (; n >0; n--)
        {
            result = result * n;
        }

        return result;
    }

    /*************************************************************************
    Entry point into the program.
    *************************************************************************/
    public static void main(String argv[])
    {
        // Create the observations and initial parameter guess
        // from the (Do and Batzoglou, 2008) article.

        List<Observation> observations = new ArrayList<Observation>();
        observations.add(new Observation("HTTTHHTHTH"));
        observations.add(new Observation("HHHHTHHHHH"));
        observations.add(new Observation("HTHHHHHTHH"));
        observations.add(new Observation("HTHTTTHHTT"));
        observations.add(new Observation("THHHTHHHTH"));

        Parameters initialParameters = new Parameters(0.6, 0.5);

        EM em = new EM(observations, initialParameters);

        Parameters finalParameters = em.run();

        o.printf("Final result:\n%s\n", finalParameters);
    }
}

5
% Implementation of the EM (Expectation-Maximization)algorithm example exposed on:
% Motion Segmentation using EM - a short tutorial, Yair Weiss, %http://www.cs.huji.ac.il/~yweiss/emTutorial.pdf
% Juan Andrade, jandrader@yahoo.com

clear all
clc

%% Setup parameters
m1 = 2;                 % slope line 1
m2 = 6;                 % slope line 2
b1 = 3;                 % vertical crossing line 1
b2 = -2;                % vertical crossing line 2
x = [-1:0.1:5];         % x axis values
sigma1 = 1;             % Standard Deviation of Noise added to line 1
sigma2 = 2;             % Standard Deviation of Noise added to line 2

%% Clean lines
l1 = m1*x+b1;           % line 1
l2 = m2*x+b2;           % line 2

%% Adding noise to lines
p1 = l1 + sigma1*randn(size(l1));
p2 = l2 + sigma2*randn(size(l2));

%% showing ideal and noise values
figure,plot(x,l1,'r'),hold,plot(x,l2,'b'), plot(x,p1,'r.'),plot(x,p2,'b.'),grid

%% initial guess
m11(1) = -1;            % slope line 1
m22(1) = 1;             % slope line 2
b11(1) = 2;             % vertical crossing line 1
b22(1) = 2;             % vertical crossing line 2

%% EM algorithm loop
iterations = 10;        % number of iterations (a stop based on a threshold may used too)

for i=1:iterations

    %% expectation step (equations 2 and 3)
    res1 = m11(i)*x + b11(i) - p1;
    res2 = m22(i)*x + b22(i) - p2;
    % line 1
    w1 = (exp((-res1.^2)./sigma1))./((exp((-res1.^2)./sigma1)) + (exp((-res2.^2)./sigma2)));

    % line 2
    w2 = (exp((-res2.^2)./sigma2))./((exp((-res1.^2)./sigma1)) + (exp((-res2.^2)./sigma2)));

    %% maximization step  (equation 4)
    % line 1
    A(1,1) = sum(w1.*(x.^2));
    A(1,2) = sum(w1.*x);
    A(2,1) = sum(w1.*x);
    A(2,2) = sum(w1);
    bb = [sum(w1.*x.*p1) ; sum(w1.*p1)];
    temp = A\bb;
    m11(i+1) = temp(1);
    b11(i+1) = temp(2);

    % line 2
    A(1,1) = sum(w2.*(x.^2));
    A(1,2) = sum(w2.*x);
    A(2,1) = sum(w2.*x);
    A(2,2) = sum(w2);
    bb = [sum(w2.*x.*p2) ; sum(w2.*p2)];
    temp = A\bb;
    m22(i+1) = temp(1);
    b22(i+1) = temp(2);

    %% plotting evolution of results
    l1temp = m11(i+1)*x+b11(i+1);
    l2temp = m22(i+1)*x+b22(i+1);
    figure,plot(x,l1temp,'r'),hold,plot(x,l2temp,'b'), plot(x,p1,'r.'),plot(x,p2,'b.'),grid
end

3
আপনি কি কাঁচা কোডে কিছু আলোচনা বা ব্যাখ্যা যোগ করতে সক্ষম হন? কমপক্ষে আপনি যে ভাষায় লিখছেন তা উল্লেখ করা অনেক পাঠকের পক্ষে কার্যকর হবে
Glen_b

1
@ গ্লেন_বি - এটি ম্যাটল্যাব। আমি আশ্চর্য হয়েছি যে কতটা নম্রভাবে তাদের উত্তরে কারও কোডটিকে আরও বিস্তৃত হিসাবে বিবেচনা করা হয়।
EngrStudent

4

ঠিক আছে, আমি আপনাকে মারিয়া এল রিজোর একটি আর বই পড়ার পরামর্শ দিচ্ছি। একটি অধ্যায় একটি সংখ্যার উদাহরণ সহ EM অ্যালগরিদম ব্যবহার ধারণ করে। আমি মনে করি আরও ভাল বোঝার জন্য কোডটি দিয়ে যাচ্ছি।

এছাড়াও, শুরুতে এটি ক্লাস্টারিং দৃষ্টিকোণ থেকে দেখার চেষ্টা করুন। হাত দিয়ে কাজ করুন, একটি ক্লাস্টারিং সমস্যা যেখানে দুটি পর্যবেক্ষণ দুটি ভিন্ন ভিন্ন ঘনত্ব থেকে নেওয়া হয়। এটি সাহায্য করবে R আর এর সাহায্য নিন :)


2

ঠিক সেক্ষেত্রে আমি উপরোক্ত মুদ্রা টস উদাহরণটি ডু ও ব্যাটজোগ্লো দ্বারা রবি রূপায়ণ লিখেছি এবং এটি ঠিক একই সংখ্যক উত্পাদন করে কারণ তারা একই ইনপুট পরামিতিগুলি তৈরি করে এবং । θ বি = 0.5θA=0.6θB=0.5

# gem install distribution
require 'distribution'

# error bound
EPS = 10**-6

# number of coin tosses
N = 10

# observations
X = [5, 9, 8, 4, 7]

# randomly initialized thetas
theta_a, theta_b = 0.6, 0.5

p [theta_a, theta_b]

loop do
  expectation = X.map do |h|
    like_a = Distribution::Binomial.pdf(h, N, theta_a)
    like_b = Distribution::Binomial.pdf(h, N, theta_b)

    norm_a = like_a / (like_a + like_b)
    norm_b = like_b / (like_a + like_b)

    [norm_a, norm_b, h]
  end

  maximization = expectation.each_with_object([0.0, 0.0, 0.0, 0.0]) do |(norm_a, norm_b, h), r|
    r[0] += norm_a * h; r[1] += norm_a * (N - h)
    r[2] += norm_b * h; r[3] += norm_b * (N - h)
  end

  theta_a_hat = maximization[0] / (maximization[0] + maximization[1])
  theta_b_hat = maximization[2] / (maximization[2] + maximization[3])

  error_a = (theta_a_hat - theta_a).abs / theta_a
  error_b = (theta_b_hat - theta_b).abs / theta_b

  theta_a, theta_b = theta_a_hat, theta_b_hat

  p [theta_a, theta_b]

  break if error_a < EPS && error_b < EPS
end
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.