HMM与维特比算法在基因组序列中的应用
前言
受启发于一篇文献Parent-independent genotyping for constructing an ultrahigh-density linkage map based on population sequencing
这里面有一段讲述了利用低覆盖度测序技术,对两个纯系个体M和Z的二倍体后代进行测序,这两个纯系亲本为MM和ZZ。由于低覆盖度的关系,那么杂合位点MZ只能测到一个等位基因,因此表现为MM或ZZ。因此你实际观察到的序列为m(MM)或(ZZ)【观测层的情况】,但是实际隐含层有MM,MZ和ZZ三种。目的是通过HMM算法,从观测层出发反推隐含层的状态
维特比算法
这里借用维基百科里面的例子:维特比
这是个病人看病的例子,其中隐含层状态有两个:1. Healthy;2. Fever
而实际观测到的观测层有三个结果:1. Dizzy;2. Cold;3. Normal
假设有一个病人连续三天看医生,医生发现第一天他感觉正常,第二天感觉冷,第三天感觉头晕。 于是医生产生了一个问题:怎样的健康状态序列最能够解释这些观察结果,这就需要维特比算法来解决实际问题了
图例:
假设说隐含层的状态转移矩阵为:
隐含层到观测层的发射矩阵为:
那么由观测层反推隐含层如下:
- 红色箭头表示维特比算法的最优路径
- 小括号内表示的是每个状态所对应的值,保留最大的那个值
- 式子表示转移数值,最大的为最有路径
第一步:
由起始点开始,初始概率乘对应状态的转移概率,再乘对应状态的发射概率得到Day_1的值
第二步:
计算Day_2相应的值
第三步:
计算Day_3相应的值
因此的到隐含层的最佳路径(红色路径),即前两天的状态是Healthy,第三天状态是Fever
基因组上的应用
从这张文献图里面反应的也是同样的问题,隐含层有三个状态:MM,MZ和ZZ;观测层有两个:m和z,由于低覆盖测序在杂合位点MZ只能测到一个等位基因,因此只能观测到m(即MM基因型)或者z(即ZZ基因型),因此对于每个位点来说,相当是上一个例子的 Day,有100个位点,相当于做了100次随机游走。
即观察到是m和z,反推隐含层的状态是MM,MZ还是ZZ
起始状态向量MM:0.4975,ZZ:0.4975,MZ:0.005,分别对应各自的起始状态。
由于重组率为0.01,意味着某一状态向其他两个状态转移的概率为0.01,向自生转移的概率为0.98;隐含层与实际观测到碱基存在0.03的突变,那么由于观测到的是m和z,只可能测到m突变为z,或者观测到z突变成m。因此,MM中的m有0.97的概率是不突变的,即观测到m,有0.03的概率是突变为z;类似的,ZZ中的z有0.97的概率是不突变的,即观测到z,有0.03的概率是突变为m;而MZ由于只能测到其中一个杂合位点,若测到M则观测到m,若测到Z则观测到z,各为0.5的概率
那么左边为转移概率矩阵,右边为发射矩阵
R实现
在R里面可以调包实现,代码参考hmm_1.R:
为了简化模型,对于状态集合,MM用1来表示,ZZ用0来表示,MZ用2来表示;对于观测集合,m用m表示,z用z表示
library(HMM)
## 所有可能状态集合
state <- c("0","1","2")
## 所有可能观测集合
Symbols <- c("m","z")
## 初始概率分布
startprob <- c(0.4,0.2,0.4)
## 状态转移概率矩阵
transpro <- matrix(c(0.98, 0.01, 0.01, 0.01, 0.98, 0.01 ,0.01 ,0.01 ,0.98),nrow = 3)
## 观测概率分布
emisspr <- matrix(c(0.97,0.5,0.03,0.03,0.5,0.97),nrow = 3)
#建模
hmm <- initHMM(States = state,Symbols = Symbols,startProbs = startprob,transProbs = transpro,
emissionProbs = emisspr)
## 得到的一个观测
ober <- c(sample(c(rep("m",5),rep("z",10))),
sample(c(rep("z",25),rep("m",7))))
bw <- baumWelch(hmm,observation = ober)
viterbi(hmm,ober)
结果展示:
这样就把隐含的状态找出来了