簡與美(6)

在繼續之前,先說些別的。
有人問我最近在忙些什麼,爲什麼會研究起NLP(自然語言處理)。這和工作有一定關係,但也不全是。
總結一下我這三年來做的事情,圍繞着三個技術核心,一個是如何寫好代碼,一個是存儲技術,一個是數據挖掘。
在寫代碼方面,主要是實戰和理論學習相結合,在實戰中不斷改進,去粗存精,進一步從思想上改變認識,以期取得更深的體會。
存儲方面的研究,始於今年年初,通過這一年來幾次重要的存儲方案設計,我總結出存儲設計即索引設計的觀點。一切存儲關鍵在於索引,無論是使用數據庫,還是獨立的存儲方案,索引問題解決了,所有問題也就差不多了。我在這一方面並不太深入,這一方面技術也相對穩定,說實話,也是最容易的,因爲存儲設計是相對最不抽象的事兒。但是存儲開發卻是我認爲最重要的工作,是其他工作的基礎,做到完美並不容易,我會在這塊更深入下去,要能夠昇華思想,我也會在後面寫一些存儲設計和數學的那些事兒。
而數據挖掘,是工作項目把我引入了這一領域,兩年前我就開始做統計相關的工作,通過這些工作對數據逐漸從感性到理想認識的昇華,我現在有比較豐富的統計系統設計經驗了,一條龍的統計系統開發輕易就可以完成。是ted老大啓蒙了我做數據挖掘的想法,今年初ted老大讓我做用戶行爲方面的研究,我狠狠的啃了一個星期的論文和書籍,把數據挖掘的理論知識豐富了起來。而我真正認真的去思考並開始做數據挖掘相關工作是在我來到架構組之後,我開始了一個探索性的項目,這也是讓我研究NLP的原因,我參考了大量的paper和文章,系統的瞭解了NLP的相關理論和研究成果,並且也結合目前的項目做了一些嘗試,比如我用一週時間開發了中文分詞引擎,讀了幾十篇paper之後,我信心大增,最終實現了一個有一定工業強度的引擎,雖然這種引擎已經有人開發過,但是我還是決定自己去實現,因爲我接下來的研究和嘗試會比較深入的依賴於NLP,所以我需要深入細節。NLP只是一個方向,我同時還在研究自動推薦的相關技術,關聯規則挖掘和協同過濾算法,這些都是數據挖掘相關的技術,我也會在後面作出成績之後把他們都寫下來。
NLP和自動推薦等數據挖掘算法的研究並非我工作的全部,之前也只是用了40%的時間在這上面,下週開始,僅僅只會再用20%時間在這方面,之前的60%和以後的80%是用在產品的開發上面,理論研究是長線投入,最大的收穫可能是技術和思路的積累,工作的重點應該是開發能夠滿足用戶需求的產品。
這些研究是一個厚積薄發的過程,借用李小龍的一句話:剪枝蔓,立主腦。先掌握儘可能多的相關技術,然後結合實際項目的需要,抽取關鍵技術深耕。這就是我最單純直接的想法。
 
腦中的數學是抽象的,手中的數學是簡單的。
 
上篇已經介紹了隱馬爾科夫模型,我們知道HMM是一個五元組:(N,M,A,B,PI)。
N是一組狀態的集合。N={1,2,3,..n}。
M是一組觀察值組成的集合。M={v1,v2,..,vm}。
A是狀態轉移概率矩陣,描述狀態轉移概率分佈,n行n列。
A=[aij],aij=P(qt+1 = j | qt = i),1<=i,j<=n。
B是發射概率矩陣,描述觀察值的概率分佈。
B={bj(k)},bj(k)表示在狀態j時第k個觀察值vk的概率。即bj(k)=P(vk|j),1<=k<=m,1<=j<=n。
PI是初始概率,描述初始狀態概率分佈,PI={PIi}。
PIi=P(q1=i)表示時刻1選擇某個狀態i的概率。
隱馬爾科夫模型可解決三類問題。如下:
1)給定HMM=(A,B,PI),並給定觀察序列O=O1O2..OT,如何計算P(O|HMM),即觀察序列O的概率?
2)給定HMM=(A,B,PI),並給定觀察序列O=O1O2..OT,如何選擇一個狀態轉換序列S=q1q2..qT,使得S最可能產生觀察序列O,即求P(S|O,HMM)?
3)在模型參數未知或不確定的情況下,如何根據觀察序列O=O1O2..OT求得模型參數或調整模型參數,即如何確定一組模型參數,使得P(O|HMM)最大?
這三個問題都不容易解決,基本方法的計算量是計算機無法接受的,我們主要討論前兩個問題的解法,而第三個問題是關於參數的訓練過程,在介紹N元模型的時候討論。

爲了方便表述,我用一個例子來貫穿說明。

考慮水藻預測天氣的模型。民間的傳說告訴我們水藻的狀態和天氣有一定的概率關係,此時,我們就有了狀態集合和觀察值集合,觀察值集合就是水藻的狀態(dry,damp,soggy),即幹、潮、溼,狀態集合就是天氣的狀況(sunny,cloudy,rainy),即晴、多雲、雨。我們就可以通過HMM模型,通過觀察水藻的狀態變化得到天氣的變化情況。
 
對於水藻和天氣的關係,可以用窮舉搜索方法得到下面的狀態轉移圖:
 
kenbin
 
圖中,每兩個相鄰列各狀態之間的路徑長度由轉移概率決定,通過狀態轉移概率矩陣A獲得,而每一列的狀態和對應的觀察值則由發射概率決定,通過發射概率矩陣B決定。如果用窮舉法求某一觀察序列的概率,就要求所有可能的狀態轉換序列下的概率之和,圖中共有3*3=27個可能的狀態轉換序列,即:
P(dry,damp,soggy|HMM)=
P(dry,damp,soggy|sunny,sunny,sunny)+
P(dry,damp,soggy|sunny,sunny,cloudy)+
P(dry,damp,soggy|sunny,sunny,rainy)+..+
P(dry,damp,soggy|rainy,rainy,rainy)
計算複雜度很高,特別是當狀態空間較大,觀察序列較長的時候。
 
我們可以利用概率的時間不變性解決複雜度的問題。
 
我們採用動態規劃的方法計算觀察序列的概率,我們引入部分概率的概念,部分概率是到達某一中間狀態時的概率與該狀態下發射概率之積,可以認爲是要求的觀察序列概率的一個局部概率。
 
kenbin
 
而到達某一中間狀態的概率可以用所有可能到達該中間狀態的路徑之和表示。比如在t=2時刻,到達中間狀態cloudy的概率可以用如下的三條路徑之和計算:

kenbin
 
@t(j)表示在時刻t,狀態j的部分概率。則:
@t(j)=P(observation | state is j) * P(all paths to state j at time t)
即時刻t,狀態j的發射概率bj(Ot)乘以到達中間狀態j的概率。
 
結束時刻狀態的部分概率表示經過所有可能路徑到達這些結束狀態的概率,比如:
 
kenbin
 
結束時刻狀態的部分概率的和即爲圖中所有可能的路徑的和,也就是當前HMM下觀察序列的概率。
 
我們看看具體如何計算。
 
在初始狀態,沒有路徑到達這些狀態,我們令:@1(j)=PI(j)bj(O1),這樣初始時刻狀態的部分概率就只與初始概率和該時刻發射概率有關。
 
如何計算t>1時刻的部分概率呢?我們已經知道了計算部分概率公式:
@t(j)=P(observation | state is j) * P(all paths to state j at time t)
看下圖的計算路徑示意圖:
 
kenbin
 
從圖中可以看出,隨着觀察序列數的增長(時刻遞增),計算的路徑數呈指數增長。但是在時刻t我們已經計算出任何狀態的部分概率,因此t+1時刻狀態的部分概率利用時刻t的計算結果進行計算,而不用再重複計算時刻t之前的路徑。
@t+1(j)=bj(Ot+1)[@t(1)a1j+@t(2)a2j+..+@t(n)anj]
 
對於觀察序列長度T,窮舉法複雜度爲T的指數級,而上述方法的複雜度爲T的線性。
 
這個算法叫做前向算法,採用動態規劃的思想,把求解全局概率分解成求解局部概率來化簡問題。
 
多數情況下,我們更希望能夠根據一個給定的HMM模型,通過觀察序列找到產生這個序列的最可能的狀態轉換序列(隱含的)。
 
通過窮舉法,列出所有可能的狀態轉換序列,並計算出每種狀態轉換序列對應的觀察序列的概率,概率最大的情況對應的就是最可能的狀態轉換序列。
 
比如水藻預測天氣模型中,最有可能的狀態轉換序列是使得概率:
P(dry,damp,soggy|sunny,sunny,sunny),
P(dry,damp,soggy|sunny,sunny,cloudy),
P(dry,damp,soggy|sunny,sunny,rainy),..,
P(dry,damp,soggy|rainy,rainy,rainy)
得到最大值的序列。
 
這種窮舉法的計算量很大。爲了解決這個問題,我們利用和前向算法一樣的原理--概率的時間不變性來減少計算量。
 
我們同樣定義一個部分概率。這個部分概率和前向算法定義的部分概率類似,都是局部概率,但是這裏的部分概率是到達某一中間狀態的概率最大的路徑而不是所有路徑之和。
 
對於每個中間狀態和結束狀態,都存在一條到達它的最優路徑,它可能是如下圖這樣:
 
kenbin
 
這些路徑爲部分最優路徑,每一條部分最優路徑都對應一個關聯概率--部分概率$。與前向算法不同,$是最有可能到達該狀態的一條路徑的概率。
 
$t(i)是時刻t,狀態i的部分概率,它對應的那條路徑就是部分最優路徑。$t(i)在任何時刻都存在,這樣就可以在時刻T(結束時刻)找到全局的最優路徑。
 
我們看看具體如何計算。
 
由於在t=1不存在任何部分最優路徑,可以計算:$1(i)=PI(i)bi(O1)。與前向算法相同。
 
那麼如何計算t>1時刻的部分概率呢?
同樣我們只用時刻t-1的結果來得到時刻t的部分概率。
 
kenbin
 
圖中可以看出到達X的最優路徑是下面其中一條:
(sequence of states),..,A,X
(sequence of states),..,B,X
(sequence of states),..,C,X
我們希望找到一條概率最大的。回想馬爾科夫模型的假設,一個狀態只和它前一時刻的狀態有關。
$t(i)=max{$t-1(1)*a1i*bi(Ot),$t-1(2)*a2i*bi(Ot),..,$t-1(n)*ani*bi(Ot)}
其中第一部分是時刻t-1的部分概率,第二部分是狀態轉移概率,第三部分是發射概率。
 
現在我們已經得到到達每一箇中間或者結束狀態的概率最大的路徑,但是我們需要採取一些方法來記錄這條路徑,這就需要在每個狀態記錄最優路徑的前一個狀態。
&t(i)=argmax{$t-1(1)*a1i,..,$t-1(n)*ani}
argmax操作符會選擇使得括號中式子最大的索引j(1<=j<=n)。這裏沒有乘以發射概率是因爲我們關心的是在到達當前狀態的最優路徑中前一狀態的信息,而與它對應的觀察值無關。
 
這個算法叫做viterbi算法,很著名的一個解碼算法,也是信息論中的一個重要算法。它的思路就是動態規劃,把尋找全局最優解分解成尋找局部最優解來化簡問題。
 
待續...
發佈了30 篇原創文章 · 獲贊 1 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章