让你真正理解HMM(Hidden Markov Model)的算法演示程序

来源:互联网 发布:不死者之王 知乎 编辑:程序博客网 时间:2024/05/21 07:05

HMM, 隐Markov模型, 在人脸, 步态, 语音识别等领域有着广泛的用途.

通过以Javascript语言演示其使用方法, 读者可方便地理解其计算过程(其实,并不难).

理论就不讲解了,直接看计算过程:

<html><head><meta charset="UTF-8"/><meta author="alaclp@qq.com"/><meta published="2014-11-28"/><meta licence="public"/><meta about="Hidden markov model"/><title>让你真正理解隐Markov模型的计算示例</title></head><body><h1>HMM Demo</h1><hr/><div id="info"><h2>[0] HMM模型参数</h2><b>状态S:{H,L}</b><br/><b>初始状态I:{0.5, 0.5}</b><br/><b>状态转移矩阵A:</b><br/><table border="1px"><tr>  <td>a_ij</td><td>H</td><td>L</td></tr><tr>  <td>H</td><td>0.5</td><td>0.5</td></tr><tr>  <td>L</td><td>0.4</td><td>0.6</td></tr></table><b>混淆矩阵B:</b><br/><table border="1px"><tr>  <td>b_ik</td><td>A</td><td>C</td><td>T</td><td>G</td></tr><tr>  <td>H</td><td>0.2</td><td>0.3</td><td>0.3</td><td>0.2</td></tr><tr>  <td>L</td><td>0.3</td><td>0.2</td><td>0.2</td><td>0.3</td></tr></table><br/><h2>[1] 评估问题:使用上述模型,采用<font color='red'>Forward算法</font>计算发生GGCA观测结果的概率</h2><h3>结果矩阵:</h3><table border="1px"><tr>  <td>概率</td><td>初始</td>  <td><div id="O1">G</div></td>  <td><div id="O2">G</div></td>  <td><div id="O3">C</div></td>  <td><div id="O4">A</div></td></tr><tr><td><div id="S0">H</div></td><td>0.5</td><td><div id="11"></div></td><td><div id="12"></div></td><td><div id="13"></div></td><td><div id="14"></div></td></tr><tr><td><div id="S1">L</div></td><td>0.5</td><td><div id="21"></div></td><td><div id="22"></div></td><td><div id="23"></div></td><td><div id="24"></div></td></tr></table><div id="prob"></div><br/><div id="output"><b>计算过程:</b><br/></div><hr/><h2>[2] 解码问题: 给定观测序列GGCACTGAA,问产生该序列概率最大的状态路径是什么?</h2><b>把HMM模型换算为以2为底的对数值,则有</b><br/><b>状态S:{H,L}</b><br/><b>初始状态I:{-1, -1}</b><br/><b>状态转移矩阵A:</b><br/><table border="1px"><tr>  <td>a_ij</td><td>H</td><td>L</td></tr><tr>  <td>H</td><td>-1</td><td>-1</td></tr><tr>  <td>L</td><td>-1.322</td><td>-0.737</td></tr></table><b>混淆矩阵B:</b><br/><table border="1px"><tr>  <td>b_ik</td><td>A</td><td>C</td><td>T</td><td>G</td></tr><tr>  <td>H</td><td>-2.322</td><td>-1.737</td><td>-1.737</td><td>-2.322</td></tr><tr>  <td>L</td><td>-1.737</td><td>-2.322</td><td>-2.322</td><td>-1.737</td></tr></table><h3>结果矩阵:</h3><table border="1px"><tr>  <td>概率</td><td>初始</td>  <td><div id="D1">G</div></td>  <td><div id="D2">G</div></td>  <td><div id="D3">C</div></td>  <td><div id="D4">A</div></td>  <td><div id="D5">C</div></td>  <td><div id="D6">T</div></td>  <td><div id="D7">G</div></td>  <td><div id="D8">A</div></td>  <td><div id="D9">A</div></td></tr><tr><td><div id="S0">H</div></td><td>-1.0</td><td><div id="V11"></div></td><td><div id="V12"></div></td><td><div id="V13"></div></td><td><div id="V14"></div></td><td><div id="V15"></div></td><td><div id="V16"></div></td><td><div id="V17"></div></td><td><div id="V18"></div></td><td><div id="V19"></div></td></tr><tr><td><div id="S1">L</div></td><td>-1.0</td><td><div id="V21"></div></td><td><div id="V22"></div></td><td><div id="V23"></div></td><td><div id="V24"></div></td><td><div id="V25"></div></td><td><div id="V26"></div></td><td><div id="V27"></div></td><td><div id="V28"></div></td><td><div id="V29"></div></td></tr></table><div id="result1"></div>计算过程:<br/><div id="output1"><div><script type="text/javascript">//状态集合var S = ['H', 'L'];//观测集合var O = ['A', 'C', 'T', 'G'];//初始状态发生H和L的概率矩阵var imat = [0.5, 0.5];//不同状态间转换的概率矩阵---状态转换矩阵var amat = {'HH': 0.5, 'HL':0.5, 'LH':0.4, 'LL': 0.6};//由状态产生特定观测的概率矩阵---混淆矩阵var bmat = {'HA': 0.2, 'HC': 0.3, 'HG': 0.3, 'HT': 0.2,             'LA': 0.3, 'LC': 0.2, 'LG': 0.2, 'LT': 0.3};//测试用的观测结果var dest = 'GGCA';//设置概率计算矩阵var pmat = new Array(S.length);for(var i = 0; i < S.length; i++) {pmat[i] = new Array();for(var j = 0; j < dest.length; j++)pmat[i].push(0);}var out = document.getElementById("output");var tmp;//计算评估问题算法---前向算法//分为两个部分计算//计算结果矩阵pmat第1列---由初始状态矩阵及混淆矩阵所决定for(var i = 0; i < S.length; i++) {pmat[i][0] = imat[i] * bmat[S[i] + dest[0]];document.getElementById(String(i + 1) + "1").innerHTML = pmat[i][0];}//计算后续列的概率---由前一状态概率 * 状态间转换概率amat * 状态到观测概率矩阵bmat所决定for(var i = 1; i < dest.length; i++) {for(var rowA = 0; rowA < S.length; rowA++) {//输出out.innerHTML += "<b>" + String(rowA + 1) + "行" + String(i + 1) + "列</b><br/>";for(var rowB = 0; rowB < S.length; rowB++) {if (rowA == rowB) {tmp = pmat[rowA][i-1] * amat[S[rowA] + S[rowA]] * bmat[S[rowA] + dest[i]];pmat[rowA][i] += tmp;//输出out.innerHTML += S[rowA] + S[rowB] + dest[i] + ": " + String(pmat[rowA][i-1]) + "*" + String(amat[S[rowA] + S[rowA]]) + "*" + String(bmat[S[rowA] + dest[i]]) + "=" + String(tmp) + "<br/>";}else {tmp = pmat[rowB][i-1] * amat[S[rowB] + S[rowA]] * bmat[S[rowA] + dest[i]];pmat[rowA][i] += tmp;//输出out.innerHTML += S[rowB] + S[rowA] + dest[i] + ": " + String(pmat[rowB][i-1]) + "*" + String(amat[S[rowB] + S[rowA]]) + "*" + String(bmat[S[rowB] + dest[i]]) + "=" + String(tmp) + "<br/>";}}//输出out.innerHTML += "和为: <b>" + String(pmat[rowA][i]) + "</b><br/>";document.getElementById(String(rowA + 1) + String(i + 1)).innerHTML = pmat[rowA][i];}}//输出状态S产生观测序列的概率var sm = 0;for(var i = 0; i < S.length; i++)  sm += pmat[i][dest.length-1];document.getElementById("prob").innerHTML = "评估结果: HMM(S(H, L), O(A, T, C, G), imat, amat, bmat)产生观测结果" + dest + "的概率为: <font color='red'>" + String(sm) + "</font><br/>";//------------------------//取得最佳路径问题---解码问题//测试用的观测结果var dest = 'GGCACTGAA';//把数值矩阵转换为对数for(var i = 0; i < S.length; i++)  imat[i] = Math.log(imat[i]) / Math.LN2;for(var i = 0; i < S.length; i++)for(var j = 0; j < S.length; j++) {  amat[S[i] + S[j]] = Math.log(amat[S[i] + S[j]]) / Math.LN2;}for(var i = 0; i < S.length; i++)for(var j = 0; j < O.length; j++) {  bmat[S[i] + O[j]] = Math.log(bmat[S[i] + O[j]]) / Math.LN2;  console.log( S[i] + "->" + O[j] + "=" + bmat[S[i] + O[j]] );  }  //初始化概率计算矩阵pmatvar pmat = new Array(S.length);for(var i = 0; i < S.length; i++) {pmat[i] = new Array();for(var j = 0; j < dest.length; j++)pmat[i].push(0);}var out = document.getElementById("output1");//计算解码问题算法---Viterbi算法//分为两个部分计算//计算结果矩阵pmat第1列---由初始状态矩阵及混淆矩阵所决定var link = new Array();var maxval = -1e15, maxid = -1;for(var i = 0; i < S.length; i++) {pmat[i][0] = imat[i] + bmat[S[i] + dest[0]];if (pmat[i][0] > maxval) {maxval = pmat[i][0];maxid = i;}document.getElementById("V" + String(i + 1) + "1").innerHTML = pmat[i][0];}//存储第1个最大概率点link.push(S[maxid]);//计算后续列的概率---由前一状态最大概率 * 前一状态到其他状态的转换概率amat * 当前状态对观测值的发生概率//记录当前可能产生观测结果的最大概率for(var i = 1; i < dest.length; i++) {var thisO = dest[i];    //计算由上次状态lastS出发,发生状态转换到S[rowA]产生观测值dest[i]的最大概率for(var rowA = 0; rowA < S.length; rowA++) {var thisS = S[rowA];var maxval = -1e15;//由thisS产生thisO的概率var pp = bmat[thisS + thisO]; for(var rowB = 0; rowB < S.length; rowB++) {var lastS = S[rowB];//由lastS到thisS的转移概率var tp = amat[lastS + thisS];//上次的历史概率var lp = pmat[rowB][i-1];//总概率var totalP = pp + tp + lp;if (totalP > maxval) {maxval = totalP;document.getElementById("V" + String(rowA + 1) + String(i + 1)).innerHTML = String(totalP);}out.innerHTML += "O" + String(i + 1) + ": " + lastS + "->" + thisS + "= " + String(pp) + "(" + thisS + "->" + thisO + ") +" + String(tp) + "(T: " + lastS + thisS + ") +" + String(lp) + "(" + lastS + ", " + String(i-1)  + ") ==>" + String(totalP) + "<br/>";}pmat[rowA][i] = maxval;}if (pmat[0][i] > pmat[1][i])link.push(S[0]);elselink.push(S[1]);out.innerHTML += "最佳: " + link[link.length - 1] + "<br/>";}var out = document.getElementById("result1");out.innerHTML = "最佳状态序列:";for(var i = 0; i < link.length; i++)out.innerHTML += link[i];</script></body></html>

计算结果如下,方便大家检验:

HMM Demo


[0] HMM模型参数

状态S: {H, L}
初始状态I: {0.5, 0.5}
状态转移矩阵A:

a_ijHLH0.50.5L0.40.6混淆矩阵B:
b_ikACTGH0.20.30.30.2L0.30.20.20.3

[1] 评估问题:使用上述模型,采用Forward算法计算发生GGCA观测结果的概率

结果矩阵:

概率初始
G
G
C
A
H
0.5
0.15
0.0345
0.008415
0.0013767000000000002
L
0.5
0.1
0.027
0.00669
0.00246645
评估结果: HMM(S(H, L), O(A, T, C, G), imat, amat, bmat)产生观测结果GGCA的概率为:0.00384315

计算过程:
1行2列

HHG: 0.15*0.5*0.3=0.0225
LHG: 0.1*0.4*0.2=0.012000000000000002
和为: 0.0345
2行2列

HLG: 0.15*0.5*0.3=0.015
LLG: 0.1*0.6*0.2=0.012
和为: 0.027
1行3列

HHC: 0.0345*0.5*0.3=0.005175
LHC: 0.027*0.4*0.2=0.0032400000000000003
和为: 0.008415
2行3列

HLC: 0.0345*0.5*0.3=0.0034500000000000004
LLC: 0.027*0.6*0.2=0.00324
和为: 0.00669
1行4列

HHA: 0.008415*0.5*0.2=0.0008415000000000001
LHA: 0.00669*0.4*0.3=0.0005352
和为: 0.0013767000000000002
2行4列

HLA: 0.008415*0.5*0.2=0.0012622500000000001
LLA: 0.00669*0.6*0.3=0.0012041999999999997
和为: 0.00246645

[2] 解码问题: 给定观测序列GGCACTGAA,问产生该序列概率最大的状态路径是什么?

把HMM模型换算为以2为底的对数值,则有
状态S: {H, L}
初始状态I: {-1, -1}
状态转移矩阵A:

a_ijHLH-1-1L-1.322-0.737混淆矩阵B:
b_ikACTGH-2.322-1.737-1.737-2.322L-1.737-2.322-2.322-1.737

结果矩阵:

概率初始
G
G
C
A
C
T
G
A
A
H
-1.0
-2.7369655941662066
-5.473931188332413
-8.210896782498619
-11.53282487738598
-14.006756065718395
-17.328684160605757
-19.539580943104376
-22.861509037991738
-25.65736832121151
L
-1.0
-3.321928094887362
-6.058893689053569
-8.795859283219775
-10.947862376664826
-14.006756065718395
-16.480687254050807
-19.539580943104376
-22.013512131436787
-24.4874433197692
最佳状态序列:HHHLLLLLL
计算过程:
O2: H->H= -1.7369655941662063(H->G) +-1(T: HH) +-2.7369655941662066(H, 0) ==>-5.473931188332413
O2: L->H= -1.7369655941662063(H->G) +-1.3219280948873622(T: LH) +-3.321928094887362(L, 0) ==>-6.380821783940931
O2: H->L= -2.321928094887362(L->G) +-1(T: HL) +-2.7369655941662066(H, 0) ==>-6.058893689053569
O2: L->L= -2.321928094887362(L->G) +-0.7369655941662062(T: LL) +-3.321928094887362(L, 0) ==>-6.380821783940931
最佳: H
O3: H->H= -1.7369655941662063(H->C) +-1(T: HH) +-5.473931188332413(H, 1) ==>-8.210896782498619
O3: L->H= -1.7369655941662063(H->C) +-1.3219280948873622(T: LH) +-6.058893689053569(L, 1) ==>-9.117787378107138
O3: H->L= -2.321928094887362(L->C) +-1(T: HL) +-5.473931188332413(H, 1) ==>-8.795859283219775
O3: L->L= -2.321928094887362(L->C) +-0.7369655941662062(T: LL) +-6.058893689053569(L, 1) ==>-9.117787378107138
最佳: H
O4: H->H= -2.321928094887362(H->A) +-1(T: HH) +-8.210896782498619(H, 2) ==>-11.53282487738598
O4: L->H= -2.321928094887362(H->A) +-1.3219280948873622(T: LH) +-8.795859283219775(L, 2) ==>-12.4397154729945
O4: H->L= -1.7369655941662063(L->A) +-1(T: HL) +-8.210896782498619(H, 2) ==>-10.947862376664826
O4: L->L= -1.7369655941662063(L->A) +-0.7369655941662062(T: LL) +-8.795859283219775(L, 2) ==>-11.269790471552188
最佳: L
O5: H->H= -1.7369655941662063(H->C) +-1(T: HH) +-11.53282487738598(H, 3) ==>-14.269790471552188
O5: L->H= -1.7369655941662063(H->C) +-1.3219280948873622(T: LH) +-10.947862376664826(L, 3) ==>-14.006756065718395
O5: H->L= -2.321928094887362(L->C) +-1(T: HL) +-11.53282487738598(H, 3) ==>-14.854752972273342
O5: L->L= -2.321928094887362(L->C) +-0.7369655941662062(T: LL) +-10.947862376664826(L, 3) ==>-14.006756065718395
最佳: L
O6: H->H= -2.321928094887362(H->T) +-1(T: HH) +-14.006756065718395(H, 4) ==>-17.328684160605757
O6: L->H= -2.321928094887362(H->T) +-1.3219280948873622(T: LH) +-14.006756065718395(L, 4) ==>-17.65061225549312
O6: H->L= -1.7369655941662063(L->T) +-1(T: HL) +-14.006756065718395(H, 4) ==>-16.743721659884603
O6: L->L= -1.7369655941662063(L->T) +-0.7369655941662062(T: LL) +-14.006756065718395(L, 4) ==>-16.480687254050807
最佳: L
O7: H->H= -1.7369655941662063(H->G) +-1(T: HH) +-17.328684160605757(H, 5) ==>-20.065649754771965
O7: L->H= -1.7369655941662063(H->G) +-1.3219280948873622(T: LH) +-16.480687254050807(L, 5) ==>-19.539580943104376
O7: H->L= -2.321928094887362(L->G) +-1(T: HL) +-17.328684160605757(H, 5) ==>-20.65061225549312
O7: L->L= -2.321928094887362(L->G) +-0.7369655941662062(T: LL) +-16.480687254050807(L, 5) ==>-19.539580943104376
最佳: L
O8: H->H= -2.321928094887362(H->A) +-1(T: HH) +-19.539580943104376(H, 6) ==>-22.861509037991738
O8: L->H= -2.321928094887362(H->A) +-1.3219280948873622(T: LH) +-19.539580943104376(L, 6) ==>-23.1834371328791
O8: H->L= -1.7369655941662063(L->A) +-1(T: HL) +-19.539580943104376(H, 6) ==>-22.276546537270583
O8: L->L= -1.7369655941662063(L->A) +-0.7369655941662062(T: LL) +-19.539580943104376(L, 6) ==>-22.013512131436787
最佳: L
O9: H->H= -2.321928094887362(H->A) +-1(T: HH) +-22.861509037991738(H, 7) ==>-26.1834371328791
O9: L->H= -2.321928094887362(H->A) +-1.3219280948873622(T: LH) +-22.013512131436787(L, 7) ==>-25.65736832121151
O9: H->L= -1.7369655941662063(L->A) +-1(T: HL) +-22.861509037991738(H, 7) ==>-25.598474632157945
O9: L->L= -1.7369655941662063(L->A) +-0.7369655941662062(T: LL) +-22.013512131436787(L, 7) ==>-24.4874433197692
最佳: L

0 0
原创粉丝点击