隐马尔可夫模型30x30网格场景下900维稀疏转移矩阵初始化方法
实现核心逻辑
首先需要完成二维网格到一维隐藏状态的映射,再逐行遍历每个单元格的合法相邻移动方向,最后以稀疏格式存储转移概率,避免存储大量零值造成的内存浪费。相比900x900的稠密矩阵,稀疏存储的内存占用仅为其1%不到,完全匹配该转移矩阵每行最多4个非零值的稀疏结构特征。
分步实现指引
- 状态编码规则:将30x30网格中的每个单元格用
(row, col)二维坐标表示,row、col取值范围为0-29,对应的一维隐藏状态ID为state_id = row * 30 + col,从0到899连续编号,刚好对应转移矩阵的行、列索引。 - 方向参数映射:提前定义四个移动方向的坐标偏移量与对应概率,固定为:
- 向上:行偏移-1、列偏移0,对应概率0.4
- 向下:行偏移+1、列偏移0,对应概率0.1
- 向左:行偏移0、列偏移-1,对应概率0.2
- 向右:行偏移0、列偏移+1,对应概率0.3
- 边界合法判断:逐单元格检查每个方向的移动是否会超出网格范围,仅为落在网格内的相邻单元格赋值转移概率。由于边界单元格的部分移动方向会出界,需要补充规则保证每行概率和为1:常见实现是将出界方向对应的剩余概率,全部累计为当前单元格的原地不动转移概率;也可根据业务需求,将剩余概率按比例重新分配给所有合法移动方向。
- 稀疏矩阵构建:先收集所有非零转移项的
(行索引, 列索引, 概率值)三元组,再通过坐标格式(COO)构建矩阵,最后转换为CSR格式(适合后续HMM推理中的矩阵乘法操作)。
可直接运行的参考代码
import numpy as np from scipy.sparse import coo_matrix, csr_matrix # 基础参数配置 grid_size = 30 total_states = grid_size * grid_size # 方向列表:(行偏移, 列偏移, 移动概率) direction_config = [ (-1, 0, 0.4), (1, 0, 0.1), (0, -1, 0.2), (0, 1, 0.3) ] # 存储所有非零元素的索引和取值 row_list = [] col_list = [] prob_list = [] # 遍历所有网格单元(每个单元对应转移矩阵的一行) for row in range(grid_size): for col in range(grid_size): current_state = row * grid_size + col valid_prob_total = 0.0 for dr, dc, prob in direction_config: next_row = row + dr next_col = col + dc # 检查移动后是否在网格边界内 if 0 <= next_row < grid_size and 0 <= next_col < grid_size: next_state = next_row * grid_size + next_col row_list.append(current_state) col_list.append(next_state) prob_list.append(prob) valid_prob_total += prob # 边界概率归一化:将出界方向的剩余概率分配为原地不动的转移概率 gap_prob = 1.0 - valid_prob_total if gap_prob > 1e-8: row_list.append(current_state) col_list.append(current_state) prob_list.append(gap_prob) # 构建CSR格式稀疏转移矩阵 transition_matrix = coo_matrix( (prob_list, (row_list, col_list)), shape=(total_states, total_states) ).tocsr()
校验与调整说明
- 可通过
transition_matrix.sum(axis=1)逐行检查概率和,确保每一行的转移概率总和为1,符合转移矩阵的数学要求。 - 若业务场景中不允许原地移动,可将边界处理逻辑替换为概率归一化:即对当前单元格的所有合法方向概率,除以
valid_prob_total后再赋值,保证行和为1,无需添加原地不动的转移项。 - 可随机抽查边界单元格(如网格最上方row=0的单元格)的转移项数量,确认向上方向的概率已被正确处理。
内容的提问来源于stack exchange,提问作者Anurag Singla
相关产品推荐
相关产品推荐

