reference:
通過實驗可以得到:# -*- coding:utf-8 -*-
# from __future__ import print_function
# 知道投擲的是a或b,求coin a和b投擲結果是head的最大似然估計,用來評估em演算法
mle_a =
24.0/(
24+6)
mle_b =
9.0/(9
+11)print
("real:"
, mle_a, mle_b)
# 不知道投擲的是a還是b,用em演算法估計
# init
init_a =
0.6init_b =
0.5h1, t1 =5,
5h2, t2 =9,
1h3, t3 =8,
2h4, t4 =4,
6h5, t5 =7,
3list_h =
[h1, h2, h3, h4, h5]
list_t =
[t1, t2, t3, t4, t5]
iter_times =
20for i in
range
(iter_times)
:"""
e-step
假設為a,則出現該結果的概率為init_a的出現正的次數方乘以(1-init_a)的出現負的次數方
假設為b,則出現該結果的概率為init_b的出現正的次數方乘以(1-init_b)的出現負的次數方
歸一化後乘以真實資料中的正負數可以分別得到a,b中的正負數的估計值
"""result_list =
for j in
range
(len
(list_h)):
prob_a =
pow(init_a, list_h[j])*
pow(
1-init_a, list_t[j]
) prob_b =
pow(init_b, list_h[j])*
pow(
1-init_b, list_t[j]
) count_a_h = list_h[j]
* prob_a/
(prob_a + prob_b)
count_a_t = list_t[j]
* prob_a/
(prob_a + prob_b)
count_b_h = list_h[j]
* prob_b/
(prob_a + prob_b)
count_b_t = list_t[j]
* prob_b/
(prob_a + prob_b)
# print(count_a_h, count_a_t, count_b_h, count_b_t)
[count_a_h, count_a_t, count_b_h, count_b_t]
)"""
m-step
用當前結果更新引數init_a,init_b
"""sum_ah, sum_at, sum_bh, sum_bt =0,
0,0,
0for one_list in result_list:
sum_ah += one_list[0]
sum_at += one_list[1]
sum_bh += one_list[2]
sum_bt += one_list[3]
init_a = sum_ah /
(sum_ah + sum_at)
init_b = sum_bh /
(sum_bh + sum_bt)
(i+1
, init_a, init_b)
當初始化init_a = init_b時,最終結果均為0.66;
當init_a > init_b時,最終結果會收斂到0.8,0.52;
當init_a < init_b時,最終結果會收斂到0.52,0.8。
EM演算法例項及python實現
現在有兩個硬幣a和b,要估計的引數是它們各自翻正面 head 的概率。觀察的過程是先隨機選a或者b,然後扔10次。以上步驟重複5次。如果知道每次選的是a還是b,那可以直接估計 見下圖a 如果不知道選的是a還是b 隱變數 只觀測到5次迴圈共50次投幣的結果,這時就沒法直接估計a和b的正面概率。em演算...
EM演算法簡單理解
在求解概率模型的時候,如果需要的變數都是觀測變數,不涉及到隱藏變數的話,可以使用極大似然或者貝葉斯估計來求解模型的引數。比如 對於單高斯模型來講,如果知道觀測變數,那麼就可以使用極大似然或者最小均方誤差來估計高斯模型的均值和方差。如果模型同時包含觀察變數和隱藏變數的話,傳統的方法不能完成模型的估計,...
EM演算法之Python
之 示例一 二硬幣模型 假設現在有兩個硬幣a和b,我們想要知道兩枚硬幣各自為正面的概率啊即模型的引數。我們先隨機從a,b中選一枚硬幣,然後扔10次並記錄下相應的結果,h代表正面t代表反面。對以上的步驟重複進行5次。如果在記錄的過程中我們記錄下來每次是哪一枚硬幣 即知道每次選的是a還是b 那可以直接根...