前向算法
算法目标:计算给定隐马尔可夫模型和观测序列的概率 。
算法步骤:通过递归计算前向概率来实现,其中表示在时刻状态为并且观测到部分序列的概率。
- 初始化
在初始时刻,计算所有状态的初始前向概率:,
其中,是初始状态概率,是状态生成观测的概率。- 递归计算
对于和所有状态,递归地计算前向概率:,
其中,是从状态转移到状态的概率,是状态生成观测的概率- 终止
在时刻结束时,观测序列出现的概率为所有状态的前向概率之和:
球盒模型
import numpy as np
class HiddenMarkovModel:
def __init__(self, num_states, num_observations, initial_probs=None, transition_probs=None, emission_probs=None):
"""
初始化隐马尔可夫模型 (HMM) 参数。
:param num_states: 状态数量
:param num_observations: 观测值数量
:param initial_probs: 初始状态概率向量 (长度为 num_states)
:param transition_probs: 状态转移概率矩阵 (大小为 num_states x num_states)
:param emission_probs: 观测概率矩阵 (大小为 num_states x num_observations)
"""
self.num_states = num_states
self.num_observations = num_observations
self.initial_probs = initial_probs
self.transition_probs = transition_probs
self.emission_probs = emission_probs
@staticmethod
def sample_from_distribution(distribution):
"""
根据给定的概率分布,从中抽取一个样本。
:param distribution: 概率分布向量
:return: 抽取样本的索引
"""
return np.random.choice(np.arange(len(distribution)), p=distribution)
def generate_observations(self, sequence_length):
"""
根据模型参数生成观测序列。
:param sequence_length: 要生成的观测序列的长度
:return: 生成的观测序列
"""
# 从初始状态概率分布中采样初始状态
current_state = self.sample_from_distribution(self.initial_probs)
# 从当前状态的观测概率分布中采样观测值
current_observation = self.sample_from_distribution(self.emission_probs[current_state])
observations = [current_observation]
for _ in range(sequence_length - 1):
# 根据状态转移概率分布采样下一个状态
next_state = self.sample_from_distribution(self.transition_probs[current_state])
# 从新状态的观测概率分布中采样观测值
next_observation = self.sample_from_distribution(self.emission_probs[next_state])
observations.append(next_observation)
current_state = next_state # 更新当前状态
return observations
def forward_algorithm(self, observations):
"""
使用前向算法计算给定观测序列的概率。
:param observations: 观测序列
:return: 观测序列的概率
"""
# 初始化前向概率矩阵
alpha = self.initial_probs * self.emission_probs[:, observations[0]]
# 递归计算前向概率
for observation in observations[1:]:
alpha = np.dot(alpha, self.transition_probs) * self.emission_probs[:, observation]
# 返回观测序列的概率
return np.sum(alpha)
if __name__ == '__main__':
# 初始化 HMM 模型参数
# 初始状态概率, 即选择第一个盒子的概率
initial_probs = np.array([0.3, 0.2, 0.2, 0.3])
# 状态转移概率矩阵
transition_probs = np.array([
[0.1, 0.6, 0.2, 0.1], # 从第1个盒子转移到其他盒子的概率
[0.3, 0.1, 0.4, 0.2], # 从第2个盒子转移到其他盒子的概率
[0.2, 0.3, 0.1, 0.4], # 从第3个盒子转移到其他盒子的概率
[0.5, 0.2, 0.2, 0.1] # 从第4个盒子转移到其他盒子的概率
])
# 观测概率矩阵,也称发射概率矩阵
emission_probs = np.array([
[0.4, 0.6], # 第1个盒子中抽到红色和白色球的概率
[0.7, 0.3], # 第2个盒子中抽到红色和白色球的概率
[0.5, 0.5], # 第3个盒子中抽到红色和白色球的概率
[0.6, 0.4] # 第4个盒子中抽到红色和白色球的概率
])
# 观测值到颜色的映射
observation_to_color = {0: '红色', 1: '白色'}
# 确保参数的维度一致
assert len(transition_probs) == len(initial_probs)
assert len(transition_probs) == len(emission_probs)
# 创建 HMM 对象
hmm = HiddenMarkovModel(
num_states=emission_probs.shape[0],
num_observations=emission_probs.shape[1],
initial_probs=initial_probs,
transition_probs=transition_probs,
emission_probs=emission_probs
)
# 生成一个长度为 5 的观测序列
observation_sequence = hmm.generate_observations(5)
print("生成的观测序列:", observation_sequence)
print("生成的观测序列对应的颜色:", [observation_to_color[o] for o in observation_sequence])
# 使用前向算法计算观测序列的概率
observation_probability = hmm.forward_algorithm(observation_sequence)
print("观测序列的概率:", observation_probability)
生成的观测序列: [1, 1, 1, 0, 0]
生成的观测序列对应的颜色: ['白色', '白色', '白色', '红色', '红色']
观测序列的概率: 0.02654901
标签:概率,self,probs,观测,马尔可夫,num,observations,模型 From: https://blog.csdn.net/weixin_74254879/article/details/140508702