EM(Exception Maximization)算法
引言:在動筆之前,我在網上翻閱了許多的資料,生怕自己理解的不透徹,網上也有許多良心之作,對我理解該算法起到了巨大的幫助作用,EM算法既簡單又複雜,簡單在於它的思想是非常簡單的,僅包含兩個步驟就能完成強大的功能,複雜在於它對數學基礎要求比較高,公式推導相對比較繁瑣,可能世界上最偉大的東西都是這樣吧,越是簡單的東西卻有着複雜的機理,但是越複雜的東西有時又蘊含着簡單的道理。下面就把我在學習該算法的過程寫下來,希望對後面的人學習有所幫助!
一、極大似然估計
在介紹EM算法之前,需要先複習一下極大似然估計,什麼是極大似然估計呢?舉個例子,假定現在需要調查我們學校男生和女生的身高分佈,這麼多學生怎麼辦,不可能一個一個去問吧,所以就需要抽樣。現在在學校隨機抽取了100位男生和100位女生,分別統計他們的身高,從統計學角度可以知道男生和女生的身高分別是服從高斯分佈的,但是這兩個分佈的均值和方差都不知道,所以我們就需要從這些樣本中來估計這兩個參數,記作。下面先以男生的身高分佈說明,女生的同理。
在學校這麼多男生中,我們獨立的按照概率密度抽取了100個人,組成了樣本集X,我們想通過樣本集X來估計出參數,這裏的概率密度是高斯分佈的概率密度函數,其中的未知參數是,抽到的樣本集是,其中表示抽到的第i個人的身高,i在這裏最大值取100,表示抽到的樣本個數。這些樣本都是獨立選擇的,所以同時抽到這100個男生的概率就等於他們各自的概率乘積,即從分佈是的總體樣本中抽取到這100個樣本的概率,就是樣本集X中各個樣本的聯合概率,用下式表示:
就是我們的樣本值,是已知的,那麼上式就表示在參數已知的情況下抽取得到的這個樣本的概率,這裏的就是參數相對樣本集的似然函數(likehood function)。
似然函數在這裏可以這樣理解,X樣本代表一個目標函數或者是一個事實,現在的目標是通過調整參數使得剛纔的這些樣本出現的概率最大。這是一個反推過程,就是已經知道一個結果,就是找到了出現這個結果的最大概率。
的極大似然估計量,記爲:
爲了方便分析,可以定義對數似然函數,將其變爲連加的形式:
ok,現在我們知道,要求,只需要使的似然函數最大化,然後極大值對應的就是我們的估計。問題這個時候就轉化爲怎麼樣求解函數的極值,當然就是利用求導,令導數值爲0,此時解出就可以了,但是前提必須是函數是連續可導的。如果是包含多個參數的向量,那麼就對所有的參數求偏導,有n個未知的參數,就有n個方程,方程組的解就是似然函數的極值點了。
總結一下求最大似然估計值得一般步驟:
(1)寫出似然函數;
(2)對似然函數取對數,並整理;
(3)求導數,令導數爲0,得到似然函數;
(4)解似然方程,得到的參數即爲所求;
好了,說到這裏,還不知道似然函數和EM算法有什麼聯繫,我們注意到這裏的參數只是對應了一個類別,即男生的身高或者女生的身高,就是在已知這一羣人都是男生或者女生的情況下,獲得這個類別的參數。如果我抽取的100個樣本中既有男生又有女生,相當於兩個高斯分佈混合在一起,這個時候要想估計參數,就要用到下面介紹的EM(期望值最大化)算法了。
二、EM(期望值最大化)算法
1.Jensen不等式
這裏有一些優化理論的概念,沒聽過的也不用擔心。設f是定義域爲實數的函數,對於所有的實數x,,那麼f函數是凸函數。如果x是向量時,如果其hessian矩陣H是半正定的,那麼f是凸函數,如果或者,稱f是嚴格的凸函數。
Jensen不等式可以表述如下:
如果f是凸函數,X是隨機變量,那麼:
特別地,如果f是嚴格的凸函數,那麼當且僅當,即X是常量時成立。
用圖表示會比較直觀:
圖中,灰色實線f是凸函數,X是隨機變量,有0.5的概率取a,有0.5的概率取b,X的期望值就是a和b的中值了,從圖中可以看到成立。
Jensen不等式應用於凹函數是,不等號方向相反,即
2.EM算法的推導
給定一組訓練樣本,樣本間獨立,我們想找到每個樣本間隱含的類別z,能使最大,的最大似然估計如下:
式中第一個等號是對極大似然估計取對數,第二步是對每個樣例間的每個可能類別z求聯合分佈概率和,直接求一般比較困難,因爲有隱含變量z的存在,但是在確定了z之後,求解就相對比較容易了。
EM是一種解決存在隱含變量優化問題的有效方法,不能直接最大化,但是可以不斷的建立的下界(E步),然後優化下界(M步),具體是怎麼操作的,我們繼續往下走。
對於每一個樣本,用表示該樣本隱含變量z的某種分佈,若z是離散的,那麼滿足條件是:
如果z是連續變量,那麼表示的是概率密度,此時需要將求和改寫爲積分,即:
舉一個例子,比如要將班上同學聚類,假設隱藏變量z是身高,那麼就是連續的高斯分佈,但是如果隱藏變量z是男女性別,那麼就是伯努利分佈了。
由前面的內容可以得到下面的公式:
上面的式子中(1)到(2)比較直接,乘一項除一項,結果不變。而(2)到(3)就用到了上面介紹的Jensen不等式,這裏函數是凹函數(二階導數小於0)。
這裏的就是變量的期望。
這裏如果不懂的話,請看下面的這個期望公式。
對應於上面的問題,Y是,X對應於,是,g是到的映射,這樣就解釋了式子(2)中的期望,再根據凹函數的Jensen不等式:
得到(3)式。
上面的(2)式和(3)式可以寫成:似然函數,那麼我們可以通過不斷最大化這個下界,來使得不斷提高,最終達到它的最大值。
式(2),(3)過程可以看作是對求了下界,對於的選擇,有許多種可能,那麼哪一種更好呢?不妨假定已經給定,那麼的值就取決於和了。通過調整這兩個參數使得下界不斷上升,以逼近的真實值,那麼什麼時候算是調整好了呢?當然是當等號成立時,說明調整後的值等價於了。按照這個思路,我們要找到等式成立的條件,根據Jensen不等式,要想讓等式成立,需要讓隨機變量變成常數值,所以可以得到:
其中c爲常數,並不依賴於,對此式進行進一步推導,我們已知 ,那麼也就有,(多個等式分子分母相加不變,這個認爲每個樣例的兩個概率比值都是c)。那麼可以得到:
至此,我們在固定參數 後,的計算公式就是後驗概率,解決如何選擇的問題,這一步就是E步,建立的下界,接下來就是M步,就是在給定後,調整,去極大化的下界。那麼一般EM算法的步驟歸納起來如下:
循環重複直到收斂{ (E步)對於每一個i,計算
(M步) 計算
} |
那麼究竟怎麼樣確保EM算法收斂了呢?假定和是EM第t次和第t+1次迭代後的結果,如果證明了,也就是說極大似然估計單調增加,最終我們會到達最大似然估計的最大值,下面來證明一下,當選定後,得到E步:
這一步保證了在給定時,Jensen不等式中的等式成立,也就是說
然後進行M步,將看作是變量,最大化等式右側可以得到,於是有:
(4)式來自於之前得到這個公式,對所有和都成立:
我們在得到時,只是最大化,也就是的下界,此時等式還未成立,等式成立只有是在固定,並按照E步得到時才能成立。第(5)步利用了M步定義,M步就是將調整到,使得下界最大化,因此(5)式成立,(6)是之前定義的。
至此就證明了會單調增加,一種收斂方法是不在變化,還有一種就是變化的幅度很小。
這裏有必要在解釋一下(4)(5)(6),首先(4)對所有的參數成立,而其等號成立的條件只是在固定,並調整好時成立,而第(4)步只是固定,調整,不一定保證等式一定成立。(4)到(5)式就是M步的定義,(5)到(6)是前面E步所保證等式成立條件,也就是說E步會將下界拉到與一個特定值(這裏)一樣的高度,而此時發現下界仍然可以上升,因此經過M步後,下界又被拉昇了,但達不到與的另外一個特定值()一樣的高度,之後在經過E步又將下界拉到與這個特定值一樣的高度,重複下去,直到最大值。
如果我們定義:
從前面我們可以知道,EM算法可以看作是座標上升法,E步固定,優化,M步固定,優化。
座標上升法:
圖中的直線是迭代優化的路徑,可以看到每一步都會向最優值前進一步,而且前進路線是平行於座標軸的,因爲每一步只優化一個變量。
這猶如在x-y座標系中找到一個曲線的極值,然而曲線函數不能直接求導,因此什麼梯度下降法就不適用了,但固定一個變量後,另外一個可以通過求導得到,因此可以使用座標上升法,一次固定一個變量,對另外一個求極值,最後逐步逼近極值。對應到EM上,E步:固定θ,優化Q;M步:固定Q,優化θ;交替將極值推向最大。
3. 代碼實現(模擬兩個正態分佈的均值估計)
本代碼用於模擬k=2個正態分佈的均值估計,其中ini_data(Sigma,Mu1,Mu2,k,N)函數用於生成訓練樣本,此訓練樣本是從兩個高斯分佈中隨機生成的,其中高斯分佈a均值Mu1=40、均方差Sigma=6,高斯分佈b均值Mu2=20、均方差Sigma=6,生成的樣本分佈如下圖。本問題實現兩個無法直接從樣本數據中獲知的兩個高斯分佈參數,因此需要使用EM算法估算出具體的·Mu1,Mu2取值。
圖 樣本數據分佈
在圖1的樣本數據下,在第11步時,迭代終止,EM估計結果爲:Mu=[19.63731306 40.32233867]
import math
import copy
import numpy as np
import matplotlib.pyplot as plt
isdebug = False
# 指定k個高斯分佈參數,這裏指定k=2。注意2個高斯分佈具有相同均方差Sigma,分別爲Mu1,Mu2。
def ini_data(Sigma,Mu1,Mu2,k,N):
global X
global Mu
global Expectations
X = np.zeros((1,N))
Mu = np.random.random(2)
Expectations = np.zeros((N,k))
for i in range(0,N):
if np.random.random(1) > 0.5:
X[0,i] = np.random.normal()*Sigma + Mu1
else:
X[0,i] = np.random.normal()*Sigma + Mu2
if isdebug:
print ("***********")
print (u"初始觀測數據X:")
print (X)
# EM算法:步驟1,計算E[zij]
def e_step(Sigma,k,N):
global Expectations
global Mu
global X
for i in range(0,N):
Denom = 0
for j in range(0,k):
Denom += math.exp((-1/(2*(float(Sigma**2))))*(float(X[0,i]-Mu[j]))**2)
for j in range(0,k):
Numer = math.exp((-1/(2*(float(Sigma**2))))*(float(X[0,i]-Mu[j]))**2)
Expectations[i,j] = Numer / Denom
if isdebug:
print ("***********")
print (u"隱藏變量E(Z):")
print (Expectations)
# EM算法:步驟2,求最大化E[zij]的參數Mu
def m_step(k,N):
global Expectations
global X
for j in range(0,k):
Numer = 0
Denom = 0
for i in range(0,N):
Numer += Expectations[i,j]*X[0,i]
Denom +=Expectations[i,j]
Mu[j] = Numer / Denom
# 算法迭代iter_num次,或達到精度Epsilon停止迭代
def run(Sigma,Mu1,Mu2,k,N,iter_num,Epsilon):
ini_data(Sigma,Mu1,Mu2,k,N)
print ("初始<u1,u2>:", Mu)
for i in range(iter_num):
Old_Mu = copy.deepcopy(Mu)
e_step(Sigma,k,N)
m_step(k,N)
print (i,Mu)
if sum(abs(Mu-Old_Mu)) < Epsilon:
break
if __name__ == '__main__':
run(6,40,20,2,1000,1000,0.0001)
plt.hist(X[0,:],50)
plt.show()
4、EM算法的應用
如果將樣本看作觀察值,潛在類別看作是隱藏變量,那麼聚類問題也就是參數估計問題,只不過聚類問題中參數分爲隱含類別變量和其他參數。EM算法及其改進版本被用於機器學習算法的參數求解,常見的例子包括高斯混合模型(Gaussian Mixture Model, GMM) 、概率主成份分析(probabilistic Principal Component Analysis) 、隱馬爾科夫(Hidden Markov Model, HMM)等非監督學習算法。EM算法可以給出隱變量,即缺失數據的後驗分佈 ,因此在缺失數據問題(incomplete-data probelm)中有重要應用。
5、參考文獻
[1] https://blog.csdn.net/zouxy09/article/details/8537620
[2] https://blog.csdn.net/fuqiuai/article/details/79484421
[3] http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006936.html#!comments
[4] http://cs229.stanford.edu/notes/cs229-notes8.pdf
編輯:高宇航
2019年3月29日