机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现
生活随笔
收集整理的這篇文章主要介紹了
机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1、隱馬爾可夫模型HMM
? ?學(xué)習(xí)算法,看中文不如看英文,中文喜歡描述的很高深。
? ?http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
? ?里面有HMM定義、前向算法、維特比算法、后向算法。
2、Viterbi是隱馬爾科夫模型中用于確定(搜索)已知觀察序列在HMM下最可能的隱藏序列。
? ?Viterb采用了動態(tài)規(guī)劃的思想,利用后向指針遞歸地計算到達當前狀態(tài)路徑中的最可能(局部最優(yōu))路徑。
? ?要理解,看wiki的一個動態(tài)圖。
? ?https://en.wikipedia.org/wiki/File:Viterbi_animated_demo.gif
? ?求解最可能的隱狀態(tài)序列是HMM的三個典型問題之一,通常用維特比算法解決。
? ?維特比算法就是求解HMM上的最短路徑(-log(prob),也即是最大概率)的算法。
3、HMM五元組
? ?1)obs:觀測序列,m個;
? ?2)states:隱狀態(tài),n個;
? ?3)start_p:初始概率(隱狀態(tài))
? ?4)trans_p:轉(zhuǎn)移概率(隱狀態(tài)),n*n矩陣,描述時間序列上的隱狀態(tài)概率;
? ?5)emit_p: 發(fā)射概率 (隱狀態(tài)表現(xiàn)為顯狀態(tài)的概率),n*m矩陣;
? ?要理解HMM模型的基本定義和三個基本問題。
4、Viterbi算法簡單實現(xiàn):
? ?https://github.com/hankcs/Viterbi/tree/master/src/com/hankcs/algorithm
? ?天氣見這里面的例子:http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
? ?學(xué)習(xí)算法,看中文不如看英文,中文喜歡描述的很高深。
? ?http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
? ?里面有HMM定義、前向算法、維特比算法、后向算法。
2、Viterbi是隱馬爾科夫模型中用于確定(搜索)已知觀察序列在HMM下最可能的隱藏序列。
? ?Viterb采用了動態(tài)規(guī)劃的思想,利用后向指針遞歸地計算到達當前狀態(tài)路徑中的最可能(局部最優(yōu))路徑。
? ?要理解,看wiki的一個動態(tài)圖。
? ?https://en.wikipedia.org/wiki/File:Viterbi_animated_demo.gif
? ?求解最可能的隱狀態(tài)序列是HMM的三個典型問題之一,通常用維特比算法解決。
? ?維特比算法就是求解HMM上的最短路徑(-log(prob),也即是最大概率)的算法。
3、HMM五元組
? ?1)obs:觀測序列,m個;
? ?2)states:隱狀態(tài),n個;
? ?3)start_p:初始概率(隱狀態(tài))
? ?4)trans_p:轉(zhuǎn)移概率(隱狀態(tài)),n*n矩陣,描述時間序列上的隱狀態(tài)概率;
? ?5)emit_p: 發(fā)射概率 (隱狀態(tài)表現(xiàn)為顯狀態(tài)的概率),n*m矩陣;
? ?要理解HMM模型的基本定義和三個基本問題。
4、Viterbi算法簡單實現(xiàn):
? ?https://github.com/hankcs/Viterbi/tree/master/src/com/hankcs/algorithm
? ?算法本身理解是一回事,著手代碼又是一回事,所以對于能夠代碼動手實現(xiàn)的,是很值得學(xué)習(xí)的,至少表明其深入理解了。
??算法中的思路是從觀測的序列得到最大概率的隱狀態(tài),關(guān)鍵就是這一時刻的隱狀態(tài)能得出下一個時刻隱狀態(tài)的概率以及這一時刻顯狀態(tài)的概率。
??
package sk.ml;/*** 維特比算法*/ public class Viterbi {/*** 求解HMM模型* @param obs 觀測序列* @param states 隱狀態(tài)* @param start_p 初始概率(隱狀態(tài))* @param trans_p 轉(zhuǎn)移概率(隱狀態(tài))* @param emit_p 發(fā)射概率 (隱狀態(tài)表現(xiàn)為顯狀態(tài)的概率)* @return 最可能的序列*/public static int[] compute(int[] obs, int[] states, double[] start_p, double[][] trans_p, double[][] emit_p){double[][] V = new double[obs.length][states.length];int[][] path = new int[states.length][obs.length];for (int y : states){V[0][y] = start_p[y] * emit_p[y][obs[0]];path[y][0] = y;}for (int t = 1; t < obs.length; ++t){int[][] newpath = new int[states.length][obs.length];for (int y : states){double prob = -1;int state;for (int y0 : states){double nprob = V[t - 1][y0] * trans_p[y0][y] * emit_p[y][obs[t]];if (nprob > prob){prob = nprob;state = y0;// 記錄最大概率V[t][y] = prob;// 記錄路徑System.arraycopy(path[state], 0, newpath[y], 0, t);newpath[y][t] = y;}}}path = newpath;}double prob = -1;int state = 0;for (int y : states){if (V[obs.length - 1][y] > prob){prob = V[obs.length - 1][y];state = y;}}return path[state];} }5、網(wǎng)絡(luò)上對HMM有兩個比較經(jīng)典的案例,一個是天氣,一個是診斷。
? ?診斷見知乎上文章:https://www.zhihu.com/question/20136144
? ?
package sk.ml;import static sk.ml.DoctorExample.Status.*; import static sk.ml.DoctorExample.Feel.*;public class DoctorExample {enum Status{Healthy,//健康Fever,//感冒}enum Feel{normal,//舒服cold,//冷dizzy,//頭暈}static int[] states = new int[]{Healthy.ordinal(), Fever.ordinal()};static int[] observations = new int[]{normal.ordinal(), cold.ordinal(), dizzy.ordinal()};static double[] start_probability = new double[]{0.6, 0.4};static double[][] transititon_probability = new double[][]{{0.7, 0.3},{0.4, 0.6},};static double[][] emission_probability = new double[][]{{0.5, 0.4, 0.1},{0.1, 0.3, 0.6},};public static void main(String[] args){int[] result = Viterbi.compute(observations, states, start_probability, transititon_probability, emission_probability);for (int r : result){System.out.print(Status.values()[r] + " ");}System.out.println();} } 執(zhí)行結(jié)果: Healthy Healthy Fever? ?天氣見這里面的例子:http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
??
package sk.ml;import static sk.ml.WeatherExample.Weather.*; import static sk.ml.WeatherExample.Activity.*; public class WeatherExample {enum Weather//隱狀態(tài){Rainy,//下雨Sunny,//天晴}enum Activity //顯狀態(tài){walk,//散步shop,//購物clean,//清潔}static int[] states = new int[]{Rainy.ordinal(), Sunny.ordinal()};static int[] observations = new int[]{walk.ordinal(), shop.ordinal(), clean.ordinal()};static double[] start_probability = new double[]{0.6, 0.4};//初始狀態(tài)static double[][] transititon_probability = new double[][]{//轉(zhuǎn)移矩陣{0.7, 0.3},{0.4, 0.6},};static double[][] emission_probability = new double[][]{//觀測矩陣{0.1, 0.4, 0.5},{0.6, 0.3, 0.1},};public static void main(String[] args){int[] result = Viterbi.compute(observations, states, start_probability, transititon_probability, emission_probability);for (int r : result){System.out.print(Weather.values()[r] + " ");}System.out.println();} } 執(zhí)行結(jié)果: Sunny Rainy Rainy理解算法最好的就是代碼和數(shù)學(xué)公式兩邊對應(yīng)。
總結(jié)
以上是生活随笔為你收集整理的机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Apache Sentry 初识
- 下一篇: 机器学习知识点(二十五)Java实现隐马