【火炉炼AI】机器学习044-创建隐马尔科夫模型
【火爐煉AI】機器學(xué)習(xí)044-創(chuàng)建隱馬爾科夫模型
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
隱馬爾科夫模型(Hidden Markov Model, HMM)是非常經(jīng)典的機器學(xué)習(xí)模型,在語音識別,自然語言處理,模式識別等領(lǐng)域中有著非常廣泛的應(yīng)用。故而理解和熟練掌握HMM是機器學(xué)習(xí)領(lǐng)域中一項重要的技能。
1. 什么是隱馬爾科夫模型
隱馬爾科夫模型是統(tǒng)計模型,用來描述一個含有隱含未知參數(shù)的馬爾科夫過程,其難點是從可觀察參數(shù)確定過程中的隱含參數(shù),然后利用這些參數(shù)做進(jìn)一步的分析。
隱馬爾科夫模型是關(guān)于時序的概率模型,描述一個由隱藏的馬爾科夫鏈隨機生成不可觀測的狀態(tài)隨機序列,再由各個狀態(tài)生成一個可觀測的觀測隨機序列的過程。
1.1 馬爾科夫過程
什么是馬爾科夫過程?一種無記憶的隨機過程,注意三個時間點:過去,現(xiàn)在,將來,(或者說:昨天,今天,明天)。在已知現(xiàn)在的狀態(tài)的情況下,將來會處于哪種狀態(tài)只取決于已知的現(xiàn)在狀態(tài),而與過去的狀態(tài)無關(guān)。即,已知“現(xiàn)在”的狀態(tài)情況下,“將來”的狀態(tài)和“過去”的狀態(tài)是相互獨立的,這種特性成為馬爾科夫性,具有這種性質(zhì)的隨機過程叫做馬爾科夫過程,也稱為馬爾科夫鏈。
舉個例子:荷花池中一只青蛙在跳動,從一片荷葉跳到下一片上。假設(shè)青蛙跳過的荷葉編號為X0,X1,X2,…Xn,且現(xiàn)在青蛙處于Xn這片荷葉上,那么青蛙下一刻要跳到哪片荷葉完全是由現(xiàn)在的荷葉Xn來決定的,而與X0,X1…Xn-1這些荷葉無關(guān)。這一過程可以認(rèn)為是馬爾科夫過程。
所以馬爾科夫鏈有很強的時間觀念,在t0時刻,青蛙位于X0荷葉上,t1時刻,青蛙位于X1荷葉上。
1.2 一個鏈條,兩個序列,三個概率
在馬爾科夫模型中,有六個參數(shù)非常重要,一個鏈條是指一個馬爾科夫過程,由時間來連接整個鏈條。兩個序列是每個時間點(鏈條上的每個節(jié)點)都具有兩個值,由這兩個值組成的鏈條(或序列):
1)狀態(tài)序列(State Sequence): 由隱藏的馬爾科夫鏈生成的狀態(tài)的序列,當(dāng)前處于某種狀態(tài),由這些狀態(tài)組成的序列。
2)觀測序列(Observation Sequence):很多情況下,狀態(tài)并不能完全被我們所看到,我們只能看到某一個狀態(tài)所表現(xiàn)出來的結(jié)果,這些結(jié)果可以被我們觀測到,故而這些觀測結(jié)果所組成的序列就是觀測序列,它能部分地代表狀態(tài)序列,但是不能完整的展現(xiàn)狀態(tài)序列。
三個概率是指馬爾科夫鏈往下推動的動力,代表這鏈條走勢的方向。
1)初始狀態(tài)概率:表示最開始時刻處于各個狀態(tài)的概率。
2)狀態(tài)轉(zhuǎn)移概率:tn時刻的狀態(tài)轉(zhuǎn)移到下一個tn+1時刻狀態(tài)的概率。
3)觀測概率:如果將馬爾科夫鏈看成一個矩陣,每一行代表每一個時刻,從上往下都是按照時間來排列的,每一行就代表某一個時刻,也對應(yīng)于某一個狀態(tài)值,每一列就是這個狀態(tài)下的觀測值,觀測概率就是在某狀態(tài)下,出現(xiàn)某個觀測值的概率。
還有兩個基本假設(shè):
1)齊次馬爾科夫假設(shè):隱馬爾科夫鏈在任意時刻T的狀態(tài)值,只依賴于他前一個時刻的狀態(tài)值,而與其他的狀態(tài)值和觀測值無關(guān),這也是隱馬爾科夫的特點。
2)觀測獨立性假設(shè):任意時刻的觀測值只依賴于該時刻的狀態(tài),而與其他的觀測值和其他狀態(tài)無關(guān)。
有一篇博文講的非常好,有助于對隱馬爾科夫模型的理解,該博文是:一文搞懂HMM(隱馬爾可夫模型)
下面我借用這篇博文中的圖片和例子來說明一下上述幾個關(guān)鍵參數(shù)。
1.3 舉例說明
假如有三個不同骰子,如下圖所示,第一個為平時我們所見的正方體型,有六個面,標(biāo)號為D6,每擲一次可以得到1-6中的任意一個數(shù)字,每個數(shù)字的概率為1/6.第二個為四面體,標(biāo)號為D4,會得到1-4中的任意一個數(shù)字,概率為1/4,第三個為八面體,標(biāo)號D8,會得到1-8中的任意一個數(shù)字,概率為1/8.
現(xiàn)在我們從這三個骰子中隨機選擇一個,然后每個骰子擲一次,得到一個數(shù)字,一共選10詞,擲10次。那么我們可能選擇的骰子序列是:D6 D8 D8 D6 D4 D8 D6 D6 D4 D8,得到的數(shù)字可能是:1 6 3 5 2 7 3 5 2 4。在每一次時,我們選擇的骰子組成的序列就是狀態(tài)序列,如上的(D6 D8 D8 D6 D4 D8 D6 D6 D4 D8),而由該骰子得到的數(shù)字就是我們的觀測值,組成的就是觀測序列(如數(shù)字1 6 3 5 2 7 3 5 2 4)。
很明顯,觀測序列是我們可以輕而易舉得到的,也是很容易觀察到的,故而有時也稱為可見狀態(tài)鏈,而很多時候,我們不知道選用的是哪個骰子,所以骰子這個狀態(tài)序列就是一個隱藏的序列,也被稱為隱含狀態(tài)鏈。
隱馬爾科夫模型中所說的馬爾科夫鏈其實就是隱含狀態(tài)鏈。
上面講到的初始狀態(tài)概率就是最開始我們選擇某個骰子的概率,比如此處我們隨機選擇,那么初始狀態(tài)概率就是1/3。
狀態(tài)轉(zhuǎn)移概率就是從一個骰子到下一個骰子的轉(zhuǎn)換概率,也就是,這一次我們用的是D4骰子,那么下一次我們應(yīng)該選擇哪個骰子?此處我們是隨機選擇,故而下一個骰子是D4,D6,D8的概率都是1/3,假如我們修改一下規(guī)則,比如D6后面不能選擇D4,且D6后面再選擇D6的概率是0.9,D8的概率是0.1,那么此時的狀態(tài)轉(zhuǎn)移概率就是(0,0.9,0.1)。由于規(guī)則改變,故而狀態(tài)轉(zhuǎn)移概率也發(fā)生改變,得到的就是另外一個全新的HMM。需要注意的是,狀態(tài)轉(zhuǎn)移概率只存在于狀態(tài)之間的轉(zhuǎn)移過程中,而不存在觀測值的改變過程中。
觀測概率是指,某一個狀態(tài)下得到某個觀測值的概率,這個例子中,加入當(dāng)前骰子是D6,那么正常情況下,此處我們得到的觀測值是1-6中的任意一個數(shù)字,每個數(shù)字的概率為1/6,那么此時狀態(tài)的觀測概率就是每個都是1/6。假如有人出老千,對D6骰子動過手腳,比如使得得到1的概率是1/2,其他數(shù)字(2-6)的概率都是1/10,那么此時的觀測概率也發(fā)生改變,也是一個全新的HMM模型。
用圖表示為:注意圖中的隱含狀態(tài)鏈就是狀態(tài)序列,可見狀態(tài)組成的鏈條就是觀測序列,黑色箭頭表示的從一個隱含狀態(tài)到下一個銀行狀態(tài)的轉(zhuǎn)換的概率就是狀態(tài)轉(zhuǎn)移概率,紅色箭頭表示的從一個隱含狀態(tài)到一個觀測值的輸出概率就是觀測概率。
對于完全隨機的選擇骰子的過程,那么下一次選擇骰子的概率都是1/3,這種狀態(tài)轉(zhuǎn)移概率可以表示為:
1.4 算法種類
在真實世界中,很多時候我們并不能知道所有的上述五個參數(shù)值,只知道其中的某幾個,那么這些問題的解決方式也各種各樣,下面主要講解和HMM模型有關(guān)的三類算法,分別解決三種問題。
1)已知狀態(tài)數(shù)量,狀態(tài)轉(zhuǎn)移概率,觀測序列,求解狀態(tài)序列。–解碼問題,用維特比算法解決。
這類問題就是:假如我知道有哪幾種骰子(狀態(tài)數(shù)量),每種骰子后面應(yīng)該怎么選擇下一個骰子(狀態(tài)轉(zhuǎn)移概率),也知道骰子擲出來的結(jié)果(觀測序列),比如擲出來的一系列結(jié)果是(數(shù)字1 6 3 5 2 7 3 5 2 4),那么我們怎么知道每一個步驟都是哪個骰子擲出來的(求解狀態(tài)序列),比如數(shù)字1是D4,D6,D8哪個骰子的的來的?
這個問題在語音識別領(lǐng)域叫做解碼問題,有兩種解法,第一種解法是求最大似然狀態(tài)路徑,也就是,求解一串骰子序列,這串骰子序列產(chǎn)生的觀測結(jié)果(即得到1 6 3 5 2 7 3 5 2 4這一串?dāng)?shù)字)的概率最大。第二種解法是,求每次擲出的骰子分別是某種骰子的概率,比如可以求得第一次擲D4的概率是0.5,D6的概率是0.3,D8的概率是0.2.具體的解法過程請參考其他博文。
2)已知狀態(tài)數(shù)量,狀態(tài)轉(zhuǎn)移概率,觀測序列,求解得到某個觀測值的概率。 --概率問題,向前向后算法。
這類問題和上面類似,但是這次我們想知道在某一個時刻得到某個數(shù)字的概率。這個問題的求解貌似沒有太多意義,因為得到的只是某個數(shù)字的概率,而不是真正的這個數(shù)字,但是在賭彩,股價預(yù)測等方面,卻又很大的實用價值,如果在賭彩中知道下一刻某個數(shù)字出現(xiàn)的概率,或者在股價運行上,知道下一個交易日出現(xiàn)某個價格的概率,那么我們就能在這個上面賺大把銀子。
3)已知狀態(tài)數(shù)量,觀測序列,求解狀態(tài)轉(zhuǎn)移概率。–學(xué)習(xí)問題,B-W算法。
這是最常見的情況,很多時候我們只知道有幾個骰子,并且擲這些骰子得到了很多數(shù)字,那么怎么計算每種骰子后面該怎么選擇下一個骰子了?
關(guān)于這些問題的解法,請參考博文: 一文搞懂HMM(隱馬爾可夫模型)
2. 創(chuàng)建HMM模型
隱馬爾科夫模型是一個生成模型,也就意味著一旦掌握了其底層結(jié)構(gòu),就可以產(chǎn)生數(shù)據(jù)。
2.1. 查看數(shù)據(jù)集序列
本次構(gòu)建HMM模型的數(shù)據(jù)都存放在data_hmm.txt中,首先我們加載這個數(shù)據(jù)集到內(nèi)存中來。這個數(shù)據(jù)集前兩列是日期,第三列是我們所要分析的序列數(shù)據(jù)。對這列數(shù)據(jù)繪圖可以看出其內(nèi)在邏輯和結(jié)構(gòu),如下:
2.2. 構(gòu)建HMM模型
構(gòu)建HMM模型的代碼為:
dataset_X=df.iloc[:,2].values.reshape(1,-1).T # 前面兩列是日期,用第2列作數(shù)據(jù)集 # 需要構(gòu)建成二維數(shù)組形式,故而需要加上一個軸 print(dataset_X.shape) # 有3312個訓(xùn)練樣本組成一列# 建立HMM模型,并訓(xùn)練 from hmmlearn.hmm import GaussianHMM model = GaussianHMM(n_components=4, covariance_type="diag", n_iter=1000) model.fit(dataset_X)由于此處我們只有一列數(shù)據(jù),故而需要對這列數(shù)據(jù)準(zhǔn)備一下,將其轉(zhuǎn)變?yōu)槎S數(shù)組,此處得到(3312,1)的二維數(shù)組,每一行就是一個觀測值,構(gòu)成了一個觀測序列。
這個代碼中用到了hmmlearn模塊,這個模塊需要自己通過pip install hmmlearn來安裝。這個模塊實現(xiàn)了三種HMM模型類,按照觀測狀態(tài)是連續(xù)狀態(tài)還是離散狀態(tài),可以分為兩類,GaussianHMM和GMMHMM是連續(xù)觀測狀態(tài)的HMM模型,而MultinomialHMM是離散觀測狀態(tài)的模型
本項目第一,二列代表時間,且可以看出時間上是連續(xù)的,故而使用GaussianHMM模型,這個模型假設(shè)觀測狀態(tài)符合高斯分布,而GMMHMM類則假設(shè)觀測狀態(tài)符合混合高斯分布。一般我們使用GaussianHMM即可。
GuassianHMM的幾個參數(shù):
1,n_components: 狀態(tài)數(shù)量,默認(rèn)為1。
2,covariance_type:有四種: spherical: 在每個狀態(tài)下,觀測值的所有特性分量都使用相同的方差值,對應(yīng)協(xié)方差矩陣的非對角為0,對角值相等,即球面特性,這是最簡單的高斯分布PDF。diag: 在每個狀態(tài)下,觀測值使用對角協(xié)方差矩陣,該矩陣非對角為0,對角值不相等,是covariance_type的默認(rèn)參數(shù)。full:在每個狀態(tài)下,觀測值使用完全協(xié)方差矩陣,里面的元素都為非零。tied: 指所有的狀態(tài)使用相同的完全協(xié)方差矩陣。這四種PDF類型里面,spherical, diag和full代表三種不同的高斯分布概率密度函數(shù),而tied則可以看作是GaussianHMM和GMMHMM的特有實現(xiàn)。其中,full是最強大的,但是需要足夠多的數(shù)據(jù)來做合理的參數(shù)估計;spherical是最簡單的,通常用在數(shù)據(jù)不足或者硬件平臺性能有限的情況之下;而diag則是這兩者一個折中。在使用的時候,需要根據(jù)可觀察態(tài)向量不同特性的相關(guān)性來選擇合適的類型。
3,n_iter: 最大循環(huán)次數(shù)。
還有一些其他參數(shù),但是只有上面三個參數(shù)最重要,其他可以用默認(rèn)值即可。
對上面的HMM模型進(jìn)行訓(xùn)練之后,可以查看該模型內(nèi)部的一些結(jié)構(gòu)和內(nèi)容,比如:計算每一個隱含狀態(tài)的均值和方差:
for i in range(model.n_components): # 打印出每個隱含狀態(tài)mean=model.means_[i][0]variance=np.diag(model.covars_[i])[0]print('Hidden state: {}, Mean={:.3f}, Variance={:.3f}'.format((i+1),mean,variance))-------------------------------------輸---------出--------------------------------
Hidden state: 1, Mean=5.092, Variance=0.677
Hidden state: 2, Mean=2.601, Variance=0.257
Hidden state: 3, Mean=8.099, Variance=0.678
Hidden state: 4, Mean=0.600, Variance=0.254
--------------------------------------------完-------------------------------------
2.3. 查看HMM模型的預(yù)測效果
HMM模型是生成模型,我們訓(xùn)練這個模型的最終目的是希望它能夠預(yù)測未來某個時點的值,對于這個模型,我們預(yù)測出1000個數(shù)據(jù)點,看看模型的效果如何。
# 使用HMM模型生成數(shù)據(jù) N=1000 samples,_=model.sample(N) plt.plot(samples[:,0])2.4. 提升HMM模型的性能
上面可以看出,這個模型生成的數(shù)據(jù)的序列圖和原始的數(shù)據(jù)序列圖相差甚遠(yuǎn),雖然有點起伏波動貌似一致,但是還難以滿足我們需要,我們需要的是兩者的相似度越大越好,越大表示HMM模型已經(jīng)找到了數(shù)據(jù)的變動規(guī)律。
# 模型的提升,修改n_componentsfor i in [8,12,16,18,20]:model = GaussianHMM(n_components=i, covariance_type="diag", n_iter=1000)model.fit(dataset_X)samples,_=model.sample(1000)plt.plot(samples[:,0])plt.title('hidden state N={}'.format(i))plt.show()運行后會得到五副圖,可以看我的源代碼,此處只貼出最后一幅的圖片:
可以看出,隨著隱含狀態(tài)越大,得到的預(yù)測結(jié)果圖和原始序列圖的相似度越大,表明HMM模型越準(zhǔn)確。
########################小**********結(jié)###############################
1,HMM模型的構(gòu)建和訓(xùn)練很簡單,直接使用hmmlearn模塊中的GuassianHMM函數(shù)即可,其訓(xùn)練時只需要時序數(shù)據(jù)即可。
2,比較難的是理解HMM模型,主要理解隱馬爾科夫鏈,兩種序列,三種概率,就能有個大概了解。
3,HMM模型中GuassianHMM函數(shù)的參數(shù)優(yōu)化空間不大,只是優(yōu)化隱含狀態(tài)數(shù)即可,從圖中看出,即使隱含狀態(tài)數(shù)比較大得到的結(jié)果也不是很理想,此時需要用深度學(xué)習(xí)里面的RNN或LSTM來得到準(zhǔn)確率更高的模型。
#################################################################
注:本部分代碼已經(jīng)全部上傳到(我的github)上,歡迎下載。
參考資料:
1, Python機器學(xué)習(xí)經(jīng)典實例,Prateek Joshi著,陶俊杰,陳小莉譯
總結(jié)
以上是生活随笔為你收集整理的【火炉炼AI】机器学习044-创建隐马尔科夫模型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “互联网+教育”促进优质资源共享
- 下一篇: 超级AI大脑:全能型学习助理