我最近在我的计算生物课上做了一个家庭作业,我不得不申请一个HMM。虽然我认为我理解HMM,但我无法将它们应用到我的代码中。基本上,我必须将Fair Bet Casino problem应用于DNA中的CpG岛 - 使用观察到的结果使用转换矩阵预测隐藏状态。我设法找到了一个正常工作的解决方案......但不幸的是在指数时间。我的解决方案psuedocode看起来像这样:
*注意:trans_matrix既包含从一个状态进入另一个状态的概率,也包含从一个观察到另一个观察的可能性。
HMM(trans_matrix, observations):
movements = {}
for i in range(0,len(observations):
movements[i] = #list of 4 probabilities, all possible state changes
poss_paths = []
for m in movements.keys():
#add two new paths for every path currently in poss_paths
# (state either changes or doesn't)
#store a running probability for each path
correct_path = poss_paths[index_of_highest_probability]
return correct_path
我意识到当我查看所有可能的路径#add two new paths for every path currently in poss_paths
时,我会进入指数时间。不过,我不知道如何在不查看所有路径的情况下找到概率最高的路径。
谢谢!
编辑: 我在做作业时确实找到了很多关于维特比算法的信息,但我对它如何给出最佳答案感到困惑。看起来维特比(我认为我正在特别关注前向算法)查看特定位置,向前移动一个或两个位置,然后仅查看一些后续概率来确定“正确”的下一个路径增量。我可能理解这个错误;这是维特比的工作方式吗?伪代码很有帮助。谢谢!
答案 0 :(得分:2)
隐马尔可夫模型的一个好处是,您通常可以在不考虑所有可能路径的情况下一步一步地完成所需的操作。您尝试做的事情看起来像寻找单个最可能路径的昂贵方式,您可以通过Viterbi算法的名称进行动态编程来实现 - 例如, http://cs.brown.edu/research/ai/dynamics/tutorial/Documents/HiddenMarkovModels.html。在这样的文档中还有其他有趣的东西,这些东西并不完全相同,例如在单个位置或在所有单个位置处计算隐藏状态的概率。这通常涉及一些叫做alpha和beta传递的东西,这是一个很好的搜索词,还有隐马尔可夫模型。
在http://en.wikipedia.org/wiki/Viterbi_algorithm有一个大型描述,带有数学伪代码,我认为也是python。像大多数这些算法一样,它使用马尔可夫属性,一旦你知道隐藏状态,你知道你需要回答关于那个时间点的问题的所有内容 - 你不需要知道过去的历史。在动态编程中,您沿着数据从左到右工作,使用为输出k-1计算的答案来计算输出k的答案。对于每个状态j,您想要在点k处计算的是观察到的数据直到并包括该点的概率,沿着最可能的路径在点k处的状态j结束。该概率是在k给定状态j下观测数据的概率乘以从时间k-1处的某个先前状态到所有观察到的数据直到并包括点k的概率的j倍的概率的乘积。 -1假设你在时间k-1结束了之前的状态 - 这最后一位是你刚刚为时间k-1计算的。您可以考虑所有可能的先前状态,并选择能够提供最高组合概率的状态。这样可以在时间k给出状态j的答案,并保存前一个给出最佳答案的状态。这可能看起来像你正在摆弄k和k-1的输出,但你现在有一个时间k的答案,它反映了所有数据,包括时间k。您可以执行此操作,直到k是数据中的最后一个点,此时您可以获得给定所有数据的每个最终状态的概率的答案。选择此时的状态,为您提供最高概率,然后使用您保存的信息一直追溯到您之前用于计算数据概率的时间k-1,以及时间状态j的状态j ķ。