描述:隐马尔科夫模型的三个基本问题之一:概率计算问题。给定模型λ=(A,B,π)和观测序列O=(o1,o2,...,oT),计算在模型λ下观测序列O出现的概率P(O|λ)
概率计算问题有三种求解方法:
直接计算法(时间复杂度为O(TN^T),计算量非常大,不易实现)
前向算法:A:状态转移概率矩阵;B:观测概率矩阵;Pi:初始状态概率向量;O:观测序列
1 def forward(A, B, Pi, O):
2 """计算前向概率"""
3 m = np.shape(A)[0]
4 n = np.shape(O)[0]
5 alpha = np.zeros((n, m))
6
7 for i in range(m):
8 alpha[0][i] = Pi[0][i]*B[i][0]
9
10 for t in range(1, n):
11 for i in range(m):
12 sum = 0
13 for j in range(m):
14 sum += alpha[t-1][j]*A[j][i]
15 alpha[t][i] = sum * B[i][O[t]-1]
16
17 return alpha
18
19 def calc_forward(alpha):
20 """前向算法计算观测序列O出现的概率"""
21 p = 0
22 m = np.shape(alpha)[0]
23 for i in range(m):
24 p += alpha[-1][i]
25
26 return p
后向算法:A:状态转移概率矩阵;B:观测概率矩阵;Pi:初始状态概率向量;O:观测序列
1 # 方法一
2 def backward1(A, B, Pi, O):
3 """计算后向概率"""
4 m = np.shape(A)[0]
5 n = np.shape(O)[0]
6 beta = np.zeros((n, m))
7 sum_beta = np.zeros((m, m))
8
9 for i in range(m):
10 beta[n-1][i] = 1
11
12 for t in range(n-1, 0, -1):
13 for i in range(m):
14 for j in range(m):
15 sum_beta[i, j] = A[i, j]*B[j, O[t]-1]*beta[t, j]
16 beta[t-1][:] = sum_beta.sum(1)
17
18 return beta
19
20 # 方法二
21 def backward(A, B, Pi, O):
22 """计算后向概率"""
23 m = np.shape(A)[0]
24 n = np.shape(O)[0]
25 beta = np.zeros((n, m))
26 sum_beta = np.zeros((m, m))
27
28 for i in range(m):
29 beta[n-1][i] = 1
30
31 for t in range(n-1, 0, -1):
32 for i in range(m):
33 sum_beta[i, :] = A[i, :]*B[:, O[t]-1]*beta[t, :]
34 beta[t-1][:] = sum_beta.sum(1)
35
36 return beta
37
38 def calc_backward(beta, Pi, B):
39 """后向算法计算观测概率O出现的概率"""
40 r = Pi[0]*B[:, 0]*beta[0, :]
41 p = r.sum()
42
43 return p