Apa penjelasan intuitif dari teknik Maksimalisasi Harapan? [Tutup]

109

Expectation Maximization (EM) adalah sejenis metode probabilistik untuk mengklasifikasikan data. Harap perbaiki saya jika saya salah jika itu bukan pengklasifikasi.

Apa penjelasan intuitif dari teknik EM ini? Apa yang ada di expectationsini dan apakah makhluk itu maximized?

Pria London
sumber
12
Apa algoritma maksimalisasi ekspektasi? , Nature Biotechnology 26 , 897–899 (2008) memiliki gambaran bagus yang mengilustrasikan cara kerja algoritma.
chl
@chl Pada bagian b dari gambar yang bagus , bagaimana mereka mendapatkan nilai distribusi probabilitas pada Z (yaitu, 0,45xA, 0,55xB, dll.)?
Noob Saibot
3
Anda dapat melihat pertanyaan ini math.stackexchange.com/questions/25111/…
v4r
3
Tautan diperbarui ke gambar yang disebutkan @chl.
n1k31t4

Jawaban:

120

Catatan: kode di balik jawaban ini dapat ditemukan di sini .


Misalkan kita memiliki beberapa data yang diambil sampelnya dari dua kelompok yang berbeda, merah dan biru:

masukkan deskripsi gambar di sini

Di sini, kita bisa melihat titik data mana yang termasuk dalam grup merah atau biru. Ini memudahkan untuk menemukan parameter yang menjadi ciri setiap grup. Misalnya, rata-rata dari grup merah adalah sekitar 3, rata-rata grup biru adalah sekitar 7 (dan kita dapat menemukan cara yang tepat jika kita mau).

Ini, secara umum, dikenal sebagai estimasi kemungkinan maksimum . Dengan adanya beberapa data, kami menghitung nilai parameter (atau parameter) yang paling menjelaskan data tersebut.

Sekarang bayangkan bahwa kita tidak dapat melihat nilai mana yang diambil sampelnya dari kelompok mana. Semuanya tampak ungu bagi kami:

masukkan deskripsi gambar di sini

Di sini kita memiliki pengetahuan bahwa ada dua kelompok nilai, tetapi kita tidak tahu kelompok mana nilai tertentu itu termasuk.

Masih dapatkah kita memperkirakan sarana untuk kelompok merah dan biru yang paling sesuai dengan data ini?

Ya, seringkali kita bisa! Maksimalisasi Harapan memberi kita cara untuk melakukannya. Ide yang sangat umum di balik algoritme adalah ini:

  1. Mulailah dengan perkiraan awal tentang kemungkinan setiap parameter.
  2. Hitung kemungkinan setiap parameter menghasilkan titik data.
  3. Hitung bobot untuk setiap titik data yang menunjukkan apakah lebih merah atau lebih biru berdasarkan kemungkinan itu dihasilkan oleh parameter. Gabungkan bobot dengan data ( ekspektasi ).
  4. Hitung perkiraan yang lebih baik untuk parameter menggunakan data yang disesuaikan dengan berat badan ( maksimalisasi ).
  5. Ulangi langkah 2 hingga 4 hingga estimasi parameter bertemu (proses berhenti menghasilkan estimasi yang berbeda).

Langkah-langkah ini memerlukan penjelasan lebih lanjut, jadi saya akan membahas masalah yang dijelaskan di atas.

Contoh: memperkirakan mean dan deviasi standar

Saya akan menggunakan Python dalam contoh ini, tetapi kodenya harus cukup mudah dipahami jika Anda tidak terbiasa dengan bahasa ini.

Misalkan kita memiliki dua kelompok, merah dan biru, dengan nilai yang didistribusikan seperti pada gambar di atas. Secara spesifik, setiap grup berisi nilai yang diambil dari distribusi normal dengan parameter berikut:

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...

Berikut adalah gambar grup merah dan biru ini lagi (untuk menyelamatkan Anda dari keharusan menggulir ke atas):

masukkan deskripsi gambar di sini

Ketika kita dapat melihat warna dari setiap titik (yaitu kelompok mana tempat itu berada), sangat mudah untuk memperkirakan mean dan deviasi standar untuk setiap kelompok. Kami hanya meneruskan nilai merah dan biru ke fungsi bawaan di NumPy. Sebagai contoh:

>>> np.mean(red)
2.802
>>> np.std(red)
0.871
>>> np.mean(blue)
6.932
>>> np.std(blue)
2.195

Tetapi bagaimana jika kita tidak dapat melihat warna dari titik-titik tersebut? Artinya, alih-alih merah atau biru, setiap titik telah diwarnai ungu.

Untuk mencoba dan memulihkan parameter mean dan deviasi standar untuk grup merah dan biru, kita dapat menggunakan Expectation Maximization.

Langkah pertama kita ( langkah 1 di atas) adalah menebak nilai parameter untuk mean dan deviasi standar setiap grup. Kami tidak harus menebak dengan cerdas; kami dapat memilih nomor yang kami suka:

# 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

Estimasi parameter ini menghasilkan kurva lonceng yang terlihat seperti ini:

masukkan deskripsi gambar di sini

Ini adalah perkiraan yang buruk. Kedua cara (garis putus-putus vertikal) terlihat jauh dari "tengah" apapun untuk kelompok titik yang masuk akal, misalnya. Kami ingin meningkatkan perkiraan ini.

Langkah selanjutnya ( langkah 2 ) adalah menghitung kemungkinan setiap titik data muncul di bawah tebakan parameter saat ini:

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)

Di sini, kami hanya menempatkan setiap titik data ke dalam fungsi kepadatan probabilitas untuk distribusi normal menggunakan tebakan kami saat ini pada mean dan deviasi standar untuk merah dan biru. Ini memberitahu kita, misalnya, bahwa dengan dugaan kami saat ini titik data pada 1,761 adalah jauh lebih mungkin merah (0,189) dari biru (0,00003).

Untuk setiap titik data, kita dapat mengubah dua nilai kemungkinan ini menjadi bobot ( langkah 3 ) sehingga dijumlahkan menjadi 1 sebagai berikut:

likelihood_total = likelihood_of_red + likelihood_of_blue

red_weight = likelihood_of_red / likelihood_total
blue_weight = likelihood_of_blue / likelihood_total

Dengan perkiraan kami saat ini dan bobot yang baru kami hitung, kami sekarang dapat menghitung perkiraan baru untuk mean dan deviasi standar dari grup merah dan biru ( langkah 4 ).

Kami dua kali menghitung mean dan deviasi standar menggunakan semua titik data, tetapi dengan bobot yang berbeda: sekali untuk bobot merah dan satu kali untuk bobot biru.

Bagian penting dari intuisi adalah semakin besar bobot warna pada titik data, semakin banyak titik data yang memengaruhi perkiraan selanjutnya untuk parameter warna tersebut. Ini memiliki efek "menarik" parameter ke arah yang benar.

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)

Kami memiliki perkiraan baru untuk parameter. Untuk memperbaikinya lagi, kita dapat melompat kembali ke langkah 2 dan mengulangi prosesnya. Kami melakukan ini hingga perkiraan bertemu, atau setelah beberapa iterasi dilakukan ( langkah 5 ).

Untuk data kami, lima iterasi pertama dari proses ini terlihat seperti ini (iterasi terbaru memiliki tampilan yang lebih kuat):

masukkan deskripsi gambar di sini

Kami melihat bahwa rata-rata sudah menyatu pada beberapa nilai, dan bentuk kurva (diatur oleh deviasi standar) juga menjadi lebih stabil.

Jika kami melanjutkan untuk 20 iterasi, kami berakhir dengan yang berikut:

masukkan deskripsi gambar di sini

Proses EM telah menyatu ke nilai-nilai berikut, yang ternyata sangat dekat dengan nilai sebenarnya (di mana kita dapat melihat warna - tidak ada variabel tersembunyi):

          | 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

Dalam kode di atas, Anda mungkin telah memperhatikan bahwa estimasi baru untuk deviasi standar dihitung menggunakan estimasi mean dari iterasi sebelumnya. Pada akhirnya, tidak masalah jika kita menghitung nilai baru untuk mean terlebih dahulu karena kita hanya mencari varian nilai (tertimbang) di sekitar titik pusat. Kami masih akan melihat estimasi untuk parameter yang bertemu.

Alex Riley
sumber
bagaimana jika kita bahkan tidak tahu jumlah distribusi normal dari mana asalnya? Di sini Anda telah mengambil contoh distribusi k = 2, dapatkah kita juga memperkirakan k, dan set parameter k?
stackit
1
@stackit: Saya tidak yakin ada cara umum yang lugas untuk menghitung nilai k yang paling mungkin sebagai bagian dari proses EM dalam kasus ini. Masalah utamanya adalah kita perlu memulai EM dengan perkiraan untuk setiap parameter yang ingin kita temukan, dan itu mensyaratkan bahwa kita perlu mengetahui / memperkirakan k sebelum kita mulai. Namun, dimungkinkan untuk memperkirakan proporsi poin yang termasuk dalam suatu grup melalui EM di sini. Mungkin jika kita melebih-lebihkan k, proporsi semua kecuali dua grup akan turun mendekati nol. Saya belum bereksperimen dengan ini, jadi saya tidak tahu seberapa baik itu akan berhasil dalam praktiknya.
Alex Riley
1
@AlexRiley Dapatkah Anda menjelaskan lebih banyak tentang rumus untuk menghitung perkiraan mean dan deviasi standar yang baru?
Lemon
2
@AlexRiley Terima kasih atas penjelasannya. Mengapa perkiraan deviasi standar baru dihitung menggunakan perkiraan mean yang lama? Bagaimana jika estimasi mean yang baru ditemukan lebih dulu?
GoodDeeds
1
@Lemon GoodDeeds Kaushal - maaf atas jawaban saya yang terlambat atas pertanyaan Anda. Saya sudah mencoba mengedit jawaban untuk menjawab poin yang Anda angkat. Saya juga membuat semua kode yang digunakan dalam jawaban ini dapat diakses di buku catatan di sini (yang juga menyertakan penjelasan lebih rinci dari beberapa poin yang saya sentuh).
Alex Riley
36

EM adalah algoritme untuk memaksimalkan fungsi kemungkinan ketika beberapa variabel dalam model Anda tidak teramati (yaitu ketika Anda memiliki variabel laten).

Anda mungkin cukup bertanya, jika kita hanya mencoba memaksimalkan suatu fungsi, mengapa kita tidak menggunakan mesin yang ada untuk memaksimalkan suatu fungsi. Nah, jika Anda mencoba memaksimalkan ini dengan mengambil turunan dan menyetelnya ke nol, Anda menemukan bahwa dalam banyak kasus kondisi orde pertama tidak memiliki solusi. Ada masalah ayam-dan-telur yang untuk memecahkan parameter model Anda, Anda perlu mengetahui distribusi data Anda yang belum teramati; tetapi distribusi data Anda yang tidak teramati adalah fungsi dari parameter model Anda.

EM mencoba untuk menyiasatinya dengan menebak secara berulang distribusi untuk data yang tidak teramati, kemudian memperkirakan parameter model dengan memaksimalkan sesuatu yang merupakan batas bawah pada fungsi kemungkinan aktual, dan mengulangi hingga konvergensi:

Algoritme EM

Mulailah dengan menebak nilai parameter model Anda

Langkah-E: Untuk setiap titik data yang memiliki nilai yang hilang, gunakan persamaan model Anda untuk menyelesaikan distribusi data yang hilang berdasarkan tebakan Anda saat ini dari parameter model dan memberikan data yang diamati (perhatikan bahwa Anda sedang menyelesaikan distribusi untuk setiap yang hilang nilai, bukan untuk nilai yang diharapkan). Sekarang kita memiliki distribusi untuk setiap nilai yang hilang, kita dapat menghitung ekspektasi fungsi kemungkinan sehubungan dengan variabel yang tidak teramati. Jika tebakan kami untuk parameter model benar, kemungkinan yang diharapkan ini akan menjadi kemungkinan aktual dari data yang kami observasi; jika parameternya tidak benar, itu hanya akan menjadi batas bawah.

M-step: Sekarang kita memiliki fungsi kemungkinan yang diharapkan tanpa variabel yang tidak teramati di dalamnya, maksimalkan fungsi seperti yang Anda lakukan dalam kasus yang diamati sepenuhnya, untuk mendapatkan perkiraan baru dari parameter model Anda.

Ulangi sampai konvergensi.

Marc Shivers
sumber
5
Saya tidak mengerti E-step Anda. Sebagian dari masalahnya adalah saat saya mempelajari hal ini, saya tidak dapat menemukan orang yang menggunakan terminologi yang sama. Jadi apa yang Anda maksud dengan persamaan model? Saya tidak tahu apa yang Anda maksud dengan memecahkan distribusi probabilitas?
pengguna678392
27

Berikut adalah resep langsung untuk memahami algoritme Maksimalisasi Ekspektasi:

1- Baca makalah tutorial EM ini oleh Do dan Batzoglou.

2- Anda mungkin memiliki tanda tanya di kepala Anda, lihat penjelasan di halaman pertukaran tumpukan matematika ini .

3- Lihat kode ini yang saya tulis dengan Python yang menjelaskan contoh di kertas tutorial EM item 1:

Peringatan: Kode mungkin berantakan / suboptimal, karena saya bukan pengembang Python. Tapi itu berhasil.

import numpy as np
import math

#### E-M Coin Toss Example as given in the EM tutorial paper by Do and Batzoglou* #### 

def get_mn_log_likelihood(obs,probs):
    """ Return the (log)likelihood of obs, given the probs"""
    # Multinomial Distribution Log PMF
    # ln (pdf)      =             multinomial coeff            *   product of probabilities
    # ln[f(x|n, p)] = [ln(n!) - (ln(x1!)+ln(x2!)+...+ln(xk!))] + [x1*ln(p1)+x2*ln(p2)+...+xk*ln(pk)]     

    multinomial_coeff_denom= 0
    prod_probs = 0
    for x in range(0,len(obs)): # loop through state counts in each observation
        multinomial_coeff_denom = multinomial_coeff_denom + math.log(math.factorial(obs[x]))
        prod_probs = prod_probs + obs[x]*math.log(probs[x])

    multinomial_coeff = math.log(math.factorial(sum(obs))) -  multinomial_coeff_denom
    likelihood = multinomial_coeff + prod_probs
    return likelihood

# 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((5,2), dtype=float) 
    expectation_B = np.zeros((5,2), dtype=float)
    for i in range(0,len(experiments)):
        e = experiments[i] # i'th experiment
        ll_A = get_mn_log_likelihood(e,np.array([pA_heads[j],1-pA_heads[j]])) # loglikelihood of e given coin A
        ll_B = get_mn_log_likelihood(e,np.array([pB_heads[j],1-pB_heads[j]])) # loglikelihood of e given coin B

        weightA = math.exp(ll_A) / ( math.exp(ll_A) + math.exp(ll_B) ) # corresponding weight of A proportional to likelihood of A 
        weightB = math.exp(ll_B) / ( math.exp(ll_A) + math.exp(ll_B) ) # corresponding weight of B proportional to likelihood of 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
Zhubarb
sumber
Saya menemukan bahwa program Anda akan menghasilkan A dan B menjadi 0,66, saya juga menerapkannya menggunakan scala, juga menemukan bahwa hasilnya adalah 0,66, dapatkah Anda membantu memeriksanya?
zjffdu
Menggunakan spreadsheet, saya hanya menemukan hasil 0,66 Anda jika tebakan awal saya sama. Jika tidak, saya dapat mereproduksi keluaran tutorial.
soakley
@zjffdu, berapa banyak iterasi yang dijalankan EM sebelum mengembalikan Anda 0,66? Jika Anda menginisialisasi dengan nilai yang sama, mungkin macet di maksimum lokal dan Anda akan melihat bahwa jumlah iterasi sangat rendah (karena tidak ada peningkatan).
Zhubarb
Anda juga dapat melihat slide ini oleh Andrew Ng dan catatan kursus Harvard
Minh Phan
16

Secara teknis istilah "EM" agak kurang ditentukan, tapi saya asumsikan Anda mengacu pada teknik analisis cluster Gaussian Mixture Modeling, yang merupakan contoh dari prinsip EM umum.

Sebenarnya, analisis cluster EM bukanlah pengklasifikasi . Saya tahu bahwa beberapa orang menganggap pengelompokan sebagai "klasifikasi tanpa pengawasan", tetapi sebenarnya analisis kluster adalah sesuatu yang sangat berbeda.

Perbedaan utama, dan klasifikasi kesalahpahaman besar yang selalu dimiliki orang dengan analisis cluster adalah bahwa: dalam analisis cluster, tidak ada "solusi yang benar" . Ini adalah metode penemuan pengetahuan , sebenarnya dimaksudkan untuk menemukan sesuatu yang baru ! Ini membuat evaluasi menjadi sangat rumit. Ini sering dievaluasi menggunakan klasifikasi yang dikenal sebagai referensi, tetapi itu tidak selalu sesuai: klasifikasi yang Anda miliki mungkin atau mungkin tidak mencerminkan apa yang ada dalam data.

Izinkan saya memberi contoh: Anda memiliki kumpulan data pelanggan yang besar, termasuk data jenis kelamin. Metode yang membagi kumpulan data ini menjadi "pria" dan "wanita" adalah optimal jika Anda membandingkannya dengan kelas yang ada. Dalam cara berpikir "prediksi", ini bagus, karena untuk pengguna baru Anda sekarang dapat memprediksi jenis kelamin mereka. Dalam cara berpikir "penemuan pengetahuan", ini sebenarnya buruk, karena Anda ingin menemukan beberapa struktur baru dalam data. Sebuah metode yang misalnya akan membagi data menjadi orang tua dan anak-anak, namun akan mendapatkan skor yang lebih buruk dibandingkan dengan kelas pria / wanita. Namun, itu akan menjadi hasil pengelompokan yang sangat baik (jika usia tidak diberikan).

Sekarang kembali ke EM. Pada dasarnya ini mengasumsikan bahwa data Anda terdiri dari beberapa distribusi normal multivariasi (perhatikan bahwa ini adalah asumsi yang sangat kuat, khususnya saat Anda memperbaiki jumlah cluster!). Kemudian mencoba menemukan model optimal lokal untuk ini dengan secara bergantian meningkatkan model dan penugasan objek ke model .

Untuk hasil terbaik dalam konteks klasifikasi, pilih jumlah cluster yang lebih besar dari jumlah kelas, atau bahkan terapkan pengelompokan ke kelas tunggal saja (untuk mengetahui apakah ada beberapa struktur di dalam kelas!).

Misalnya Anda ingin melatih pengklasifikasi untuk membedakan "mobil", "sepeda", dan "truk". Ada sedikit gunanya mengasumsikan data terdiri dari tepat 3 distribusi normal. Namun, Anda mungkin berasumsi bahwa ada lebih dari satu jenis mobil (dan truk serta sepeda). Jadi, alih-alih melatih pengklasifikasi untuk ketiga kelas ini, Anda mengelompokkan mobil, truk, dan sepeda menjadi 10 kelompok (atau mungkin 10 mobil, 3 truk, dan 3 sepeda, apa pun), lalu melatih pengklasifikasi untuk membedakan 30 kelas ini, lalu menggabungkan hasil kelas kembali ke kelas aslinya. Anda mungkin juga menemukan bahwa ada satu cluster yang sangat sulit untuk diklasifikasikan, misalnya Trikes. Mereka agak mobil, dan agak sepeda. Atau truk pengiriman, yang lebih mirip mobil besar daripada truk.

Memiliki QUIT - Anony-Mousse
sumber
bagaimana EM kurang ditentukan?
sam boosalis
Ada lebih dari satu versi. Secara teknis, Anda juga dapat memanggil gaya Lloyd k-means "EM". Anda perlu menentukan model apa yang Anda gunakan.
Memiliki QUIT - Anony-Mousse
2

Jawaban lain yang bagus, saya akan mencoba memberikan perspektif lain dan menangani bagian intuitif dari pertanyaan itu.

Algoritma EM (Expectation-Maximization) adalah varian dari kelas algoritma iteratif yang menggunakan dualitas

Kutipan (penekanan saya):

Dalam matematika, dualitas, secara umum, menerjemahkan konsep, teorema atau struktur matematika ke dalam konsep, teorema atau struktur lain, dengan cara satu-ke-satu, sering (tetapi tidak selalu) melalui operasi involusi: jika dualitas A adalah B, maka rangkap B adalah A. Revolusi semacam itu terkadang memiliki titik-titik tetap , sehingga rangkap A adalah A itu sendiri

Biasanya dual B dari sebuah objek A terkait dengan A dalam beberapa cara yang menjaga kesimetrisan atau kompatibilitas . Misalnya AB = const

Contoh algoritme iteratif yang menggunakan dualitas (dalam pengertian sebelumnya) adalah:

  1. Algoritma Euclidean untuk Greatest Common Divisor, dan variannya
  2. Algoritma dan varian Gram – Schmidt Vector Basis
  3. Rerata Aritmatika - Pertidaksamaan Rata-rata Geometris, dan variannya
  4. Algoritme Harapan-Maksimalisasi dan variannya (lihat juga di sini untuk tampilan informasi-geometris )
  5. (.. algoritme serupa lainnya ..)

Dengan cara yang sama, algoritma EM juga dapat dilihat sebagai dua langkah maksimalisasi ganda :

.. [EM] dipandang sebagai memaksimalkan fungsi gabungan dari parameter dan distribusi pada variabel yang tidak teramati .. E-step memaksimalkan fungsi ini sehubungan dengan distribusi pada variabel yang tidak teramati; langkah-M sehubungan dengan parameter ..

Dalam algoritma iteratif menggunakan dualitas ada asumsi eksplisit (atau implisit) dari titik ekuilibrium (atau tetap) konvergensi (untuk EM ini dibuktikan dengan menggunakan pertidaksamaan Jensen)

Jadi garis besar dari algoritma tersebut adalah:

  1. Langkah mirip-E: Temukan solusi terbaik x sehubungan dengan y yang diberikan tetap.
  2. Langkah seperti-M (ganda): Temukan solusi terbaik y sehubungan dengan x (seperti yang dihitung pada langkah sebelumnya) dipertahankan konstan.
  3. Criterion of Termination / Convergence step: Ulangi langkah 1, 2 dengan nilai x , y yang diperbarui hingga konvergensi (atau jumlah iterasi yang ditentukan tercapai)

Catatan bahwa ketika seperti algoritma konvergen ke optimum (global), telah menemukan konfigurasi yang terbaik di kedua indra (yaitu di kedua x domain / parameter dan y domain / parameter). Namun algoritme hanya dapat menemukan optimal lokal dan bukan optimal global .

saya akan mengatakan ini adalah deskripsi intuitif dari garis besar algoritma

Untuk argumentasi dan penerapan statistik, jawaban lain telah memberikan penjelasan yang baik (periksa juga referensi dalam jawaban ini)

Nikos M.
sumber
2

Jawaban yang diterima merujuk pada Makalah Chuong EM , yang menjelaskan EM dengan baik. Ada juga video youtube yang menjelaskan makalah tersebut lebih detail.

Singkatnya, berikut adalah skenarionya:

1st:  {H,T,T,T,H,H,T,H,T,H} 5 Heads, 5 Tails; Did coin A or B generate me?
2nd:  {H,H,H,H,T,H,H,H,H,H} 9 Heads, 1 Tails
3rd:  {H,T,H,H,H,H,H,T,H,H} 8 Heads, 2 Tails
4th:  {H,T,H,T,T,T,H,H,T,T} 4 Heads, 6 Tails
5th:  {T,H,H,H,T,H,H,H,T,H} 7 Heads, 3 Tails

Two possible coins, A & B are used to generate these distributions.
A & B have an unknown parameter: their bias towards heads.

We don't know the biases, but we can simply start with a guess: A=60% heads, B=50% heads.

Dalam kasus pertanyaan percobaan pertama, secara intuitif kami akan berpikir B menghasilkannya karena proporsi kepala cocok dengan bias B dengan sangat baik ... tetapi nilai itu hanya tebakan, jadi kami tidak dapat memastikan.

Dengan pemikiran tersebut, saya suka memikirkan solusi EM seperti ini:

  • Setiap percobaan membalik mendapat 'voting' pada koin mana yang paling disukainya
    • Ini didasarkan pada seberapa cocok setiap koin dengan distribusinya
    • ATAU, dari sudut pandang koin, ada harapan tinggi untuk melihat percobaan ini dibandingkan dengan koin lainnya (berdasarkan kemungkinan log ).
  • Bergantung pada seberapa banyak setiap percobaan menyukai setiap koin, itu dapat memperbarui perkiraan parameter koin itu (bias).
    • Semakin banyak percobaan menyukai koin, semakin ia memperbarui bias koin untuk mencerminkan miliknya!
    • Pada dasarnya, bias koin diperbarui dengan menggabungkan pembaruan berbobot ini di semua uji coba, sebuah proses yang disebut ( maksimalisasi ), yang mengacu pada upaya mendapatkan tebakan terbaik untuk setiap bias koin dengan serangkaian uji coba.

Ini mungkin penyederhanaan yang berlebihan (atau bahkan secara fundamental salah pada beberapa level), tapi saya harap ini membantu pada level intuitif!

lucidv01d
sumber
1

EM digunakan untuk memaksimalkan kemungkinan model Q dengan variabel laten Z.

Ini adalah pengoptimalan berulang.

theta <- initial guess for hidden parameters
while not converged:
    #e-step
    Q(theta'|theta) = E[log L(theta|Z)]
    #m-step
    theta <- argmax_theta' Q(theta'|theta)

e-step: berdasarkan estimasi saat ini dari Z menghitung fungsi loglikelihood yang diharapkan

m-step: temukan theta yang memaksimalkan Q ini

Contoh GMM:

e-step: estimasi penugasan label untuk setiap titik data dengan mempertimbangkan estimasi parameter gmm saat ini

m-step: memaksimalkan theta baru dengan tugas label baru

K-means juga merupakan algoritme EM dan ada banyak animasi penjelasan di K-means.

SlimJim
sumber
1

Menggunakan artikel yang sama oleh Do dan Batzoglou yang dikutip dalam jawaban Zhubarb, saya menerapkan EM untuk masalah itu di Java . Komentar untuk jawabannya menunjukkan bahwa algoritme macet di optimal lokal, yang juga terjadi dengan implementasi saya jika parameter thetaA dan thetaB sama.

Di bawah ini adalah keluaran standar dari kode saya, menunjukkan konvergensi parameter.

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

Di bawah ini adalah implementasi EM Java saya untuk memecahkan masalah di (Do dan Batzoglou, 2008). Bagian inti dari implementasi adalah loop untuk menjalankan EM hingga parameter bertemu.

private Parameters _parameters;

public Parameters run()
{
    while (true)
    {
        expectation();

        Parameters estimatedParameters = maximization();

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

        _parameters = estimatedParameters;
    }

    return _parameters;
}

Di bawah ini adalah seluruh kode.

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,
respectively.
*****************************************************************************/
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
experimental 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);
    }
}
stackoverflowuser2010
sumber