日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现

發(fā)布時(shí)間:2025/4/16 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1、隱馬爾可夫模型HMM
? ?學(xué)習(xí)算法,看中文不如看英文,中文喜歡描述的很高深。
? ?http://www.comp.leeds.ac.uk/roger/HiddenMarkovModels/html_dev/main.html
? ?里面有HMM定義、前向算法、維特比算法、后向算法。


2、Viterbi是隱馬爾科夫模型中用于確定(搜索)已知觀察序列在HMM下最可能的隱藏序列。
? ?Viterb采用了動(dòng)態(tài)規(guī)劃的思想,利用后向指針遞歸地計(jì)算到達(dá)當(dāng)前狀態(tài)路徑中的最可能(局部最優(yōu))路徑。
? ?要理解,看wiki的一個(gè)動(dòng)態(tài)圖。
? ?https://en.wikipedia.org/wiki/File:Viterbi_animated_demo.gif
? ?求解最可能的隱狀態(tài)序列是HMM的三個(gè)典型問題之一,通常用維特比算法解決。
? ?維特比算法就是求解HMM上的最短路徑(-log(prob),也即是最大概率)的算法。


3、HMM五元組
? ?1)obs:觀測序列,m個(gè);
? ?2)states:隱狀態(tài),n個(gè);
? ?3)start_p:初始概率(隱狀態(tài))
? ?4)trans_p:轉(zhuǎn)移概率(隱狀態(tài)),n*n矩陣,描述時(shí)間序列上的隱狀態(tài)概率;
? ?5)emit_p: 發(fā)射概率 (隱狀態(tài)表現(xiàn)為顯狀態(tài)的概率),n*m矩陣;
? ?要理解HMM模型的基本定義和三個(gè)基本問題。




4、Viterbi算法簡單實(shí)現(xiàn):
? ?https://github.com/hankcs/Viterbi/tree/master/src/com/hankcs/algorithm

? ?算法本身理解是一回事,著手代碼又是一回事,所以對(duì)于能夠代碼動(dòng)手實(shí)現(xiàn)的,是很值得學(xué)習(xí)的,至少表明其深入理解了。

??算法中的思路是從觀測的序列得到最大概率的隱狀態(tài),關(guān)鍵就是這一時(shí)刻的隱狀態(tài)能得出下一個(gè)時(shí)刻隱狀態(tài)的概率以及這一時(shí)刻顯狀態(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ò)上對(duì)HMM有兩個(gè)比較經(jīng)典的案例,一個(gè)是天氣,一個(gè)是診斷。


? ?診斷見知乎上文章: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é)公式兩邊對(duì)應(yīng)。

總結(jié)

以上是生活随笔為你收集整理的机器学习知识点(二十四)隐马尔可夫模型HMM维特比Viterbi算法Java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。