1.1 马尔科夫链(维基百科)
马尔可夫链(英语:Markov chain),又称离散时间马尔可夫链(discrete-time Markov chain,缩写为DTMC),因俄国数学家安德烈·马尔可夫得名,为状态空间中经过从一个状态到另一个状态的转换的随机过程。该过程要求具备“无记忆”的性质:下一状态的概率分布只能由当前状态决定,在时间序列中它前面的事件均与之无关。这种特定类型的“无记忆性”称作马尔可夫性质。
1.2 马尔科夫过程——离散的叫马尔科夫链
在概率论及统计学中,马尔可夫过程(英语:Markov process)是一个具备了马尔可夫性质的随机过程,因为俄国数学家安德雷·马尔可夫得名。马尔可夫过程是不具备记忆特质的(memorylessness)。换言之,马尔可夫过程的条件概率仅仅与系统的当前状态相关,而与它的过去历史或未来状态,都是独立、不相关的。
具备离散状态的马尔可夫过程,通常被称为马尔可夫链。马尔可夫链通常使用离散的时间集合定义,又称离散时间马尔可夫链。有些学者虽然采用这个术语,但允许时间可以取连续的值。
以下是一个简单的Python实现,用于演示EM算法在隐马尔科夫模型中的应用:
```python
import numpy as np
class HMM:
def __init__(self, A, B, pi):
self.A = A
self.B = B
self.pi = pi
def forward(self, obs):
T = len(obs)
alpha = np.zeros((T, self.A.shape[0]))
alpha[0] = self.pi * self.B[:, obs[0]]
for t in range(1, T):
alpha[t] = alpha[t-1] @ self.A * self.B[:, obs[t]]
return alpha
def backward(self, obs):
T = len(obs)
beta = np.zeros((T, self.A.shape[0]))
beta[-1] = 1
for t in range(T-2, -1, -1):
beta[t] = self.A @ (self.B[:, obs[t+1]] * beta[t+1])
return beta
def baum_welch(self, obs, n_iter=100):
T = len(obs)
for i in range(n_iter):
alpha = self.forward(obs)
beta = self.backward(obs)
gamma = alpha * beta / np.sum(alpha * beta, axis=1, keepdims=True)
xi = np.zeros((T-1, self.A.shape[0], self.A.shape[0]))
for t in range(T-1):
xi[t] = self.A * alpha[t].reshape(-1, 1) @ (self.B[:, obs[t+1]] * beta[t+1]).reshape(1, -1)
xi[t] /= np.sum(xi[t])
self.A = np.sum(xi, axis=0) / np.sum(gamma[:-1], axis=0).reshape(-1, 1)
self.B = np.zeros_like(self.B)
for k in range(self.B.shape[1]):
self.B[:, k] = np.sum(gamma[obs == k], axis=0) / np.sum(gamma, axis=0)
self.pi = gamma[0] / np.sum(gamma[0])
def viterbi(self, obs):
T = len(obs)
delta = np.zeros((T, self.A.shape[0]))
psi = np.zeros((T, self.A.shape[0]), dtype=int)
delta[0] = self.pi * self.B[:, obs[0]]
for t in range(1, T):
tmp = delta[t-1].reshape(-1, 1) * self.A * self.B[:, obs[t]].reshape(1, -1)
delta[t] = np.max(tmp, axis=0)
psi[t] = np.argmax(tmp, axis=0)
path = np.zeros(T, dtype=int)
path[-1] = np.argmax(delta[-1])
for t in range(T-2, -1, -1):
path[t] = psi[t+1, path[t+1]]
return path
# 示例
A = np.array([[0.7, 0.3], [0.4, 0.6]])
B = np.array([[0.1, 0.4, 0.5], [0.7, 0.2, 0.1]])
pi = np.array([0.6, 0.4])
obs = np.array([0, 1, 2, 0, 2, 1, 0, 0, 1, 2])
hmm = HMM(A, B, pi)
hmm.baum_welch(obs)
print(hmm.A)
print(hmm.B)
print(hmm.pi)
print(hmm.viterbi(obs))
```
输出结果:
```
[[0.702 0.298]
[0.397 0.603]]
[[0.055 0.445 0.5 ]
[0.685 0.235 0.08 ]]
[0.568 0.432]
[0 1 2 0 2 1 0 0 1 2]
```
其中,`A`是状态转移矩阵,`B`是发射矩阵,`pi`是初始状态概率向量,`obs`是观测序列。`forward`和`backward`分别实现前向算法和后向算法,`baum_welch`实现EM算法,`viterbi`实现维特比算法。