热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

隐马尔可夫模型(HMM)-笔记

最近在看到CNV的时候,发现一些检测CNV的分析方法都是基于隐马尔可夫模型(HMM),而HMM在生物

最近在看到CNV的时候,发现一些检测CNV的分析方法都是基于隐马尔可夫模型(HMM),而HMM在生物信息学中也应用广泛。如早期的DNA序列分析(对一家族序列建立HMM模型),还有预测DNA编码区域(对已知或者指定序列进行训练从而构建HMM模型),以及CNV分析(在Segmentation中利用HMM模型预估CNV数目,确定相应区域的拷贝数)等等

HMM是生物信息学中比较流行的机器学习和模式识别方法,它具有对模型中的一些隐性参数进行识别和优化的能力,使得这种模型具有很强的鲁棒性,并且可以随着训练深入进一步提高识别精度,同时这种自适应的模型能够有效地实现检测过程中的参数优化

因此整理下<<统计学习方法>>的隐马尔可夫模型和一些网上资料

基本概念:

  • 隐马尔可夫模型是一个关于时序的概率模型,可以用于根据一些已知的来推断未知的东西
  • 马尔可夫链是一个随机过程模型,服从马尔可夫性质:无记忆性,某一时刻的状态只受前一个时刻的影响
  • 状态序列是由马尔可夫链随机生成的,是隐藏的,不可观测的;每个状态又有其对应的观测结果,这些观测结果根据时序 排序 后即为观测序列;也可以说观测序列长度跟时刻长度是一致的

HMM基本假设:

  • 假设隐藏的马尔可夫链在任意时刻的状态只依赖于前一个时刻(t−1时)的状态,与其他时刻的状态及观测无关,也与时刻t无关
  • 假设任意时刻的观测只依赖于该时刻的马尔可夫链状态,与其它观测及状态无关

因此组成HMM有两个空间(状态空间Q和观测空间V),三组参数(状态转移矩阵A,观测概率矩阵以及状态初始概率分布π),有了这些参数,一个HMM就被确定了

HMM模型的三个基本问题:

  • 评估观测序列的概率,在给定HMM模型λ=(A,B,π)和观测序列O下,计算模型λ下观测序列的出现概率P(O|λ),用到的是前向-后向算法
  • 预测(解码)问题,在给定HMM模型λ=(A,B,π)和观测序列O下,求解观测序列的条件概率最大的条件下,最可能出现的状态序列,用到的是维特比算法
  • 模型参数学习问题,在给定观测序列O下,估计模型λ的参数,使得该模型下观测序列的条件概率P(O|λ)最大,用到的是EM算法的鲍姆-韦尔奇算法

向前/向后算法

根据<<统计学习方法>>中的第10章隐马尔可夫模型的例子,记录下向前/向后算法对于HMM第一个基本问题的实现过程,Python代码如下:

class Hidden_Markov_Model:
    def forward(self, A, B, PI, Q, V, O):
        Q_n = len(Q)
        O_n = len(O)
        alphas = np.zeros((O_n, Q_n))
        for t in range(O_n):
            index = V.index(O[t])
            if t == 0:
                alphas[t] = PI * B[:,index]
            else:
                alphas[t] = np.dot(alphas[t-1], A) * B[:,index]
        P = np.sum(alphas[O_n-1])
        print("P(O|lambda) =", P)
        return alphas

    def backward(self, A, B, PI, Q, V, O):
        Q_n = len(Q)
        O_n = len(O)
        betas = np.ones((O_n, Q_n))
        for t in range(O_n-2,-1,-1):
            index = V.index(O[t+1])
            betas[t] = np.dot(A * B[:,index], betas[t+1])
        P = np.dot(PI * B[:,V.index(O[0])], betas[0])
        print("P(O|lambda) =", P)
        return betas

对于10.1习题例子(主要根据前向和后向算法计算结果):

A = np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B = np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
PI = np.array([0.2,0.4,0.4])
V = ["red","white"]
Q = [1,2,3]
O = ["red","white","red","white"]

HMM = Hidden_Markov_Model()
HMM = Hidden_Markov_Model()
print("P(O|lambda) =", HMM.forward(A,B,PI,Q,V,O))
>>前向 P(O|lambda) =  0.06009079999999999
print("P(O|lambda) =", HMM.backward(A,B,PI,Q,V,O))
>>后向 P(O|lambda) =  0.06009079999999999

对于10.2习题例子(根据公式10.24公式,加上前向和后向概率矩阵,从而计算结果):

A = np.array([[0.5,0.1,0.4],[0.3,0.5,0.2],[0.2,0.2,0.6]])
B = np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
PI = np.array([0.2,0.3,0.5])
V = ["red","white"]
Q = [1,2,3]
O = ["red","white","red","red","white","red","white","white"]

HMM = Hidden_Markov_Model()
alpha = HMM.forward(A,B,PI,Q,V,O)
beta = HMM.backward(A,B,PI,Q,V,O)
p = alpha[3,2]*beta[3,2]/sum(alpha[3] * beta[3])
print("P(i4=q3|O,lambda) = ", p)
>>P(i4=q3|O,lambda) =  0.5369518160647323

维特比算法

对于这个HMM预测问题,最容易想到的是枚举法,如果有3个状态和3个观测序列,那么枚举27次,计算其概率,找出概率最大的那个状态序列即可,但是这种方法运算过大(复杂度是指数增长),所以才有了维特比(Viterbi)算法

维特比算法实际上是用动态规划思路来解决隐马尔可夫的预测问题,相当于是寻找最优路径(概率最大的路径),这路径则对应一个时序状态序列;根据马尔可夫性质,当前状态的概率只跟前一次有关(第t+1时刻的状态概率仅由第t时刻的状态决定),因此依靠前向迭代获取达到每个状态的所有路径的最大概率,然后再反向搜索获取最优路径

因此其还是用前向算法计算了每个观测序列下每个状态的概率,而不是每步只取最好的(A*算法),比如在观测2下状态2是最大概率,那么在计算观测3下哪个状态的概率最大时,不是仅仅考虑之前观测序列的状态2,而是将状态1和3也加入考虑的,代码如下:

class Hidden_Markov_Model:
    def vertibi(self, A, B, PI, Q, V, O):
        Q_n = len(Q)
        O_n = len(O)
        deltas = np.zeros((O_n, Q_n))
        psis = np.zeros((O_n, Q_n))
        I = np.zeros(O_n)
        for t in range(O_n):
            index = V.index(O[t])
            for i in range(Q_n):
                if t == 0:
                    deltas[t,i] = PI[i] * B[i,index]
                    psis[t,i] = 0
                else:
                    deltas[t,i] = np.max(A[:,i] * deltas[t-1,:]) * B[i,index]
                    psis[t,i] = np.argmax(A[:,i] * deltas[t-1,:]) + 1
        I[O_n-1] = np.argmax(deltas[O_n-1,:]) + 1
        for t in range(O_n-2,-1,-1):
            I[t] = psis[t+1,int(I[t+1])-1]
        print("I =", I)
        return

以习题10-3为例:

A = np.array([[0.5,0.2,0.3],[0.3,0.5,0.2],[0.2,0.3,0.5]])
B = np.array([[0.5,0.5],[0.4,0.6],[0.7,0.3]])
PI = np.array([0.2,0.4,0.4])
V = ["red","white"]
Q = [1,2,3]
O = ["red","white","red","white"]

HMM = Hidden_Markov_Model()
HMM.vertibi(A,B,PI,Q,V,O)
>>I = [3. 2. 2. 2.]

除了上述两个HMM问题外,还有一个HMM训练(学习)问题;如果训练数据集既有观测序列又有对应的状态序列,那么则用监督学习,不然如果只有观测序列,那么则是非监督学习;监督学习比较简单,相当于以频数估计状态转移概率和观测概率以及初始状态概率;而非监督学习则是用Baum-Welch(鲍姆-韦尔奇)算法,等看完EM再来看看这个算法的实现过程

参考资料:

HMM隐马尔可夫模型

统计学习方法:习题笔记

第10章 隐马尔可夫模型(HMM)

隐马尔科夫模型HMM(一)HMM模型

隐马尔可夫模型HMM

本文出自于 http://www.bioinfo-scrounger.com 转载请注明出处


以上所述就是小编给大家介绍的《隐马尔可夫模型(HMM)-笔记》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 我们 的支持!


推荐阅读
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了在Python张量流中使用make_merged_spec()方法合并设备规格对象的方法和语法,以及参数和返回值的说明,并提供了一个示例代码。 ... [详细]
author-avatar
微笑5885
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有