一、HMM模型的学习问题(Baum-Welch算法)
(1) Baum-Welch算法介绍
HMM的学习算法Baum-Welch(也称为EM算法)是一种无监督学习算法,用于从观测序列中估计HMM模型的参数,包括初始概率向量、状态转移概率矩阵和观测概率矩阵。
Baum-Welch算法的主要步骤如下:
【1】初始化:随机初始化HMM模型的参数,包括初始概率向量、状态转移概率矩阵和发射概率矩阵(即观测矩阵B)。
【2】E步骤(Expectation):对于每个观测序列,使用前向-后向算法计算前向概率矩阵alpha和后向概率矩阵beta。
【3】M步骤(Maximization):利用E步骤中计算得到的前向概率矩阵alpha、后向概率矩阵beta以及观测序列,更新HMM模型的参数。
– 更新初始概率向量pi:根据alpha和beta计算得到的gamma矩阵。
– 更新状态转移概率矩阵A:根据alpha、beta和观测序列计算得到的xi矩阵。
– 更新发射概率矩阵B:根据alpha、beta和观测序列计算得到的gamma矩阵。
【4】重复步骤2和3,直到收敛或达到最大迭代次数。
在E步骤中,利用前向-后向算法计算前向概率矩阵alpha和后向概率矩阵beta。前向概率alpha表示在给定模型参数和观测序列的条件下,到达每个时间步和隐藏状态的路径的概率。后向概率beta表示在给定模型参数和观测序列的条件下,从每个时间步和隐藏状态出发,到达观测序列结束的路径的概率。
在M步骤中,根据E步骤中计算得到的前向概率矩阵alpha、后向概率矩阵beta以及观测序列,利用各种计算公式更新HMM模型的参数。通过不断迭代E步骤和M步骤,逐渐优化模型参数,使得模型能够更好地解释观测序列。
Baum-Welch算法是一种经典的HMM学习算法,它利用了观测序列中的信息来估计模型参数,从而提高了HMM模型的拟合能力。然而,Baum-Welch算法可能会陷入局部最优解,并且对于有多个局部最优解的情况,无法保证找到全局最优解。因此,在实际应用中,可能需要多次运行Baum-Welch算法以选择最优的模型参数。
(2) Baum-Welch算法推导过程介绍
为了让有基础的读者进一步了解Baum-Welch算法,为了他们的学术研究乃至创新需要,笔者给大家查找了该算法推导过程的资料,以方便读者参考。
输入:给定训练数据只包含观测序列,而没有对应的状态序列
输出:学习HMM模型λ = (π, A, B)的参数
学习方法:参数的学习可以由EM算法来实现
步骤-1:确定对数似然函数
步骤-2:EM算法的E步
步骤-3:EM算法的M步
步骤4:求初始概率向量π
步骤-5:求状态转移矩阵A
步骤-6:求观测概率分布矩阵B
(3) Baum-Welch算法案例-天气预测
我们以天气预报案例为例,假设有三种天气状态:晴天(Sunny)、多云(Cloudy)和雨天(Rainy),以及两种观测结果:干燥(Dry)和湿润(Wet)。我们收集了7天的天气数据,如下所示:
天气状态:Sunny, Sunny, Cloudy, Rainy, Rainy, Cloudy, Sunny
观测结果:Dry, Wet, Wet, Dry, Wet, Wet, Dry
注释:S表示晴天,C表示多云,R表示雨天;D表示干燥,W表示湿润。
代码实现:
import numpy as np
def baum_welch(obs, n_states, n_obs):
# 初始化参数
start_prob = np.ones(n_states) / n_states # 初始状态概率
trans_prob = np.ones((n_states, n_states)) / n_states # 状态转移概率
obs_prob = np.ones((n_states, n_obs)) / n_obs # 观测概率
# 迭代次数
n_iter = 100
# 迭代更新模型参数
for _ in range(n_iter):
# E步:计算前向概率和后向概率
alpha = np.zeros((len(obs), n_states)) # 前向概率
beta = np.zeros((len(obs), n_states)) # 后向概率
# 计算前向概率
alpha[0] = start_prob * obs_prob[:, obs[0]]
for t in range(1, len(obs)):
alpha[t] = np.dot(alpha[t-1], trans_prob) * obs_prob[:, obs[t]]
# 计算后向概率
beta[-1] = 1
for t in reversed(range(len(obs)-1)):
beta[t] = np.dot(trans_prob, obs_prob[:, obs[t+1]] * beta[t+1])
# M步:更新模型参数
# 更新初始状态概率
start_prob = alpha[0] * beta[0] / np.sum(alpha[0] * beta[0])
# 更新状态转移概率
for i in range(n_states):
for j in range(n_states):
numer = np.sum(alpha[t, i] * trans_prob[i, j] * obs_prob[j, obs[t+1]] * beta[t+1, j] for t in range(len(obs)-1))
denom = np.sum(alpha[t, i] * beta[t, i] for t in range(len(obs)-1))
trans_prob[i, j] = numer / denom
# 更新观测概率矩阵
for j in range(n_states):
for k in range(n_obs):
numer = np.sum(alpha[t, j] * beta[t, j] for t in range(len(obs)) if obs[t] == k)
denom = np.sum(alpha[t, j] * beta[t, j] for t in range(len(obs)))
obs_prob[j, k] = numer / denom
return start_prob, trans_prob, obs_prob
# 定义天气状态和观测结果的编码
state2idx = {'S': 0, 'C': 1, 'R': 2}
obs2idx = {'D': 0, 'W': 1}
# 定义观测数据
obs = [state2idx[s] for s in ['S', 'S', 'C', 'R', 'R', 'C', 'S']]
obs = [obs2idx[o] for o in ['D', 'W', 'W', 'D', 'W', 'W', 'D']]
# 学习HMM模型参数
start_prob, trans_prob, obs_prob = baum_welch(obs, 3, 2)
# 打印结果
print(“初始状态概率:”, start_prob)
print(“状态转移概率:”, trans_prob)
print(“观测概率矩阵:”, obs_prob)
结果:
初始状态概率: [1.72987913e-08 2.86102186e-15 9.99999983e-01]
状态转移概率: [[5.49789253e-05 1.08844210e-09 9.99945021e-01]
[4.99999985e-01 5.00000001e-01 4.99999985e-01]
[4.99999985e-01 4.99999983e-01 5.00000002e-01]]
观测概率矩阵: [[1. 0.]
[0. 1.]
[0. 1.]]
初始状态概率表示开始天气状态的概率分布,状态转移概率表示天气状态之间的转移概率,观测概率矩阵表示观测结果在每个天气状态下的概率分布。根据结果可以看出,模型学习到的参数能够较好地描述观测数据的分布。
(4) Baum-Welch算法的应用场景
Baum-Welch算法是隐马尔可夫模型(HMM)参数估计的经典算法,属于无监督学习的一种方法,主要应用于需要从观测序列中学习模型参数的场景。
算法特点与适用条件:
【1】无监督学习:仅需观测序列,无需标注隐藏状态。
【2】局部最优:结果依赖初始参数,可能需多次随机初始化。
【3】时序数据:适合具有时间依赖性的序列数据。
对比其他方法:
【1】与Viterbi算法区别:Viterbi用于解码最可能的状态序列,而Baum-Welch用于参数学习。
【2】与监督学习对比:若数据已标注,可直接用最大似然估计,无需Baum-Welch。
Baum-Welch算法在数据标注成本高或隐藏状态难以直接观测的场景中尤为重要,是时序数据分析的核心工具之一。以下是其典型应用领域:
【1】语音识别
应用:训练HMM模型以识别语音信号中的音素或单词。
场景:从大量未标注的语音数据中自动学习声学模型的参数(如状态转移概率、观测概率)。
示例:将语音信号分段建模为HMM的状态(如“开始-中间-结束”),通过Baum-Welch算法优化模型。
【2】 生物信息学
DNA/RNA序列分析:预测基因编码区(如CpG岛检测);建模蛋白质二级结构或序列比对。
示例:将DNA碱基序列作为观测值,隐藏状态可能代表不同的功能区域(如外显子、内含子)。
【3】自然语言处理(NLP)
词性标注:将隐藏状态映射到词性标签(如名词、动词),通过观测单词序列学习状态转移规律。
命名实体识别:识别文本中的人名、地名等实体。
【4】金融时间序列分析
股票价格建模:将市场隐藏状态(如“牛市”“熊市”)与观测价格关联,预测趋势。
风险检测:通过异常观测序列识别潜在金融风险。
【5】手势识别与运动分析
动作捕捉:从传感器数据中识别人体动作(如 walking、running)。
示例:将传感器信号作为观测值,隐藏状态对应不同动作阶段。
【6】故障诊断与预测性维护
工业设备监测:通过振动、温度等观测数据学习设备的隐藏状态(如“正常”“故障”)。
示例:HMM模型可预警潜在故障。
【7】气象预测
天气模式建模:隐藏状态表示真实天气(如晴、雨),观测值可能是传感器数据或历史记录。
二、HMM模型的预测问题
(1) Viterbi算法简介
HMM主要用来预测每个时刻t在该时刻最有可能出现的状态,从而得到一个状态序列{i1,i2,…in},将它作为预测结果。下面主要介绍下维特比算法(Viterbi Algorithm)。
维特比算法(Viterbi Algorithm)是一种常用的动态规划算法,用于解决HMM模型中的状态序列问题,即根据观测序列推断出最可能的隐藏状态序列。
维特比算法的步骤如下:
【1】初始化:设置初始概率为起始状态的概率,将路径概率初始化为1。
【2】递推:从第一个时间步开始,对于每个时间步和每个可能的隐藏状态,计算当前状态的最大路径概率和对应路径,以及当前状态的概率。
【3】回溯:找到最后一个时间步中具有最大路径概率的状态,然后根据每个时间步的最优路径回溯,得到最可能的隐藏状态序列。
维特比算法的优点是在时间复杂度上有很好的优化,因为它避免了对所有可能的状态序列进行遍历。它的计算复杂度为O(T * N^2),其中T是时间步数,N是状态数。因此,它在实际问题中可以高效地求解HMM模型的状态序列问题。
(2) Viterbi算法的主要推导步骤
下面介绍下维特比算法的主要推导过程。
输入:模型λ = (π, A, B)和观测O = {O1,O2…OT}
输出:最优路径I = { i1,i2 … iT }
(3) 使用Viterbi进行天气预测
示例:
考虑天气预报模型 λ=(π,A,B);假设每天天气受气压的因素影响,状态集合Q = {1,2,3}其中1代表高气压,2代表中气压,3代表低气压;观测集合V ={晴天,雨天},
初始状态矩阵 π = {0.5,0.3,0.2},
状态转移矩阵 A = [[0.2,0.3,0.5] ,
[0.3,0.5,0.2] ,
[0.1,0.3,0.6] ]
观测矩阵B = [ [0.3,0.7],
[0.2,0.8] ,
[0.5,0.5]]
已知观测序列 O =(晴天,雨天,晴天),试使用维特比算法(Viterbi Algorithm)求最优状体序列,即最优路径I =(i1,i2,i3)。
解:
步骤-1:t1时刻
初始化过程。在t = 1时,对于每个状态i,i=1、2、3,求状态i观测O[1]=“晴天”的概率,计算过程如下所示。
由 P1[ i ] = π[i] * b[i][o1] ,i = 1、2、3 可得:
P1[1] = π[1] * b[1][o1] = 0.5 X 0.3 = 0.15
P1[2] = π[2] * b[2][o1] = 0.3 X 0.2 = 0.06
P1[3 ] = π[3] * b[3][o1] = 0.2 X 0.5 = 0.10
t1时刻对应的每种路径表示为 path1[i] ,i = 1、2、3 ,则有:
path1[1] = path1[2] = path1[3] = 0
步骤-2:t2时刻
在t = 2时,对于每个状态i,i=1、2、3,求 {在t=1状态j观测O[1]=“晴天” && t=2状态i观测O[2]=“雨天”} 的路径的最大概率,计算过程如下所示。
P2[ i ] = MAX { P1[ j ] * a[ j ][ i ] } * b[i][o2] , 其中 j >=1 && j<=3
【1】当为状态为1时
P2[1] = MAX { P1[1 ] * a[ 1 ][1 ] , P1[2 ] * a[ 2 ][1 ] , P1[3]*a[3][1] } * b[1][o2]
= MAX { 0.15* 0.2 , 0.06 *0.3, 0.10*0.1 } * 0.7
= MAX {0.03 , 0.018, 0.01 } * 0.7
= 0.03 * 0.7
= 0.021
因为P1[1 ] * a[ 1 ][1 ]最大,所以 从t2时刻往t1时刻看,t2时刻的状态1àt1时刻的状态1之间最大记作:
Path2[1] = 1
画出这条路径,如下所示:
【2】当为状态 为2时
P2[2] = MAX { P1[1 ] * a[ 1 ][2 ] , P1[2 ] * a[ 2 ][2 ] , P1[3]*a[3][2] } * b[2][o2]
= MAX { 0.15* 0.3 , 0.06 *0.5, 0.10*0.3 } * 0.8
= MAX {0.045 , 0.03, 0.03 } * 0.8
= 0.045 * 0.8
= 0.036
因为PP1[1 ] * a[ 1 ][2 ]最大,,所以 从t2时刻往t1时刻看,t2时刻的状态2àt1时刻的状态1之间最大记作:
Path2[2] = 1
画出这条路径,如下所示:
【3】当为状态 为3时
P2[3] = MAX { P1[1 ] * a[ 1 ][3 ] ,P1[2 ] * a[ 2 ][3 ] ,P1[3]*a[3][3] } * b[3][o2]
= MAX { 0.15* 0.5 , 0.06 *0.2, 0.10*0.6 } * 0.5
= MAX {0.075 , 0.012, 0.06 } * 0.5
= 0.075 * 0.5
= 0.0375
因为P1[1 ] * a[ 1 ][3 ]最大,所以 从t2时刻往t1时刻看,t2时刻的状态3àt1时刻的状态1之间最大记作:
Path2[3] =1
画出这条路径,如下所示:
步骤-3:t3时刻
类似t2时刻,t3时刻计算如下:
【1】当为状态为1时
P3[1] = MAX { P2[1 ] * a[ 1 ][1 ] , P2[2 ] * a[ 2 ][1 ] , P2[3]*a[3][1] } * b[1][o1]
= MAX { 0.021* 0.2 , 0.036 *0.3, 0.0375*0.1 } * 0.3
= MAX {0.0042 , 0.0108, 0.00375 } * 0.3
= 0.0108 * 0.3
= 0.00324
因为P2[2 ] * a[ 2 ][1 ]最大,所以 从t3时刻往t2时刻看,t3时刻的状态1àt2时刻的状态2之间最大记作:
Path3[1] = 2
画出这条路径,如下所示:
【2】当为状态 为2时
P2[2] = MAX { P2[1 ] * a[ 1 ][2 ] , P2[2 ] * a[ 2 ][2 ] , P2[3]*a[3][2] } * b[2][o1]
= MAX { 0.021* 0.3 , 0.036 *0.5, 0.0375*0.3 } * 0.2
= MAX {0.0063 , 0.018, 0.01125 } * 0.2
= 0.018 * 0.2
= 0.0036
因为P2[2 ] * a[ 2 ][2 ]最大,所以 从t3时刻往t2时刻看,t3时刻的状态2àt2时刻的状态2之间最大记作:
Path3[2] = 2
【3】当为状态 为3时
P3[3] = MAX { P2[1 ] * a[ 1 ][3 ] ,P2[2 ] * a[ 2 ][3 ] ,P2[3]*a[3][3] } * b[3][o1]
= MAX { 0.021* 0.5 , 0.036 *0.2, 0.0375*0.6 } * 0.5
= MAX {0.0105 , 0.0072, 0.0225 } * 0.5
= 0.0225* 0.5
= 0.01125
因为P2[2 ] * a[ 2 ][2 ]最大,所以 从t3时刻往t2时刻看,t3时刻的状态3àt2时刻的状态3之间最大记作:
Path3[3] = 3
最优路径为【1,3,3】
(4) Viterbi算法的应用场景
Viterbi算法是隐马尔可夫模型(HMM)中最经典的解码算法,用于在给定观测序列和模型参数的情况下,找到最可能的隐藏状态序列。其核心思想是动态规划,通过递推高效地求解全局最优路径(即最大后验概率路径)。
Viterbi算法的核心优势:
【1】全局最优解:保证找到概率最大的状态路径,而非贪心算法的局部最优。
【2】高效性:通过动态规划避免穷举,时间复杂度为 O(N⋅T)O(N⋅T)(NN为状态数,TT为序列长度)。
【3】时序建模:适合处理具有时间依赖性的序列数据。
对比Baum-Welch算法:
【1】Baum-Welch:用于无监督学习,从观测数据中估计HMM参数(训练阶段)。
【2】Viterbi:用于推断,在已知模型下解码最优状态序列(预测阶段)。
Viterbi算法是任何需要从观测序列反推隐藏状态序列的场景的首选工具,尤其在语音、文本、生物序列和通信领域不可或缺。其高效性和数学严谨性使其成为时序数据分析的基石算法之一。以下是其典型应用场景:
【1】语音识别
任务:将语音信号(观测序列)转换为对应的文本或音素序列(隐藏状态序列)。
应用:识别单词或音素(如HMM状态对应音素,观测值为MFCC特征); 结合语言模型提升识别准确率。
示例:在“你好”的语音信号中,Viterbi算法解码出最可能的音素序列 /n/ /i/ /h/ /a/ /o/。
【2】自然语言处理(NLP)
词性标注(POS Tagging):
观测序列:句子中的单词序列(如“I love NLP”);
隐藏状态:词性标签(如代词、动词、名词);
输出:最可能的词性序列 [Pronoun, Verb, Noun]。
命名实体识别(NER):识别文本中的人名、地名等实体。
【3】生物信息学
基因序列分析:
预测DNA中的编码区(如外显子/内含子)。
隐藏状态:基因功能区域;观测值:碱基(A/T/C/G)。
蛋白质结构预测:从氨基酸序列推断二级结构(α螺旋、β折叠等)。
【4】通信与错误校正
卷积码解码:
在数字通信中,Viterbi算法用于解码信道编码(如卷积码)的传输序列。
观测序列:接收到的含噪声信号。
隐藏状态:编码器的可能状态。
示例:卫星通信、Wi-Fi信号解码。
【5】金融时间序列分析
市场状态识别:
隐藏状态:市场 regime(如“牛市”“熊市”“震荡”)。
观测序列:股价或收益率数据。
输出:推断历史市场状态的切换路径。
【6】计算机视觉与手势识别
动作识别:
从视频帧序列(观测值)推断人体动作(如“挥手”“走路”)。
手写识别:将笔画轨迹转换为字符序列。
【7】故障诊断
工业设备监测:
观测序列:传感器数据(振动、温度等)。
隐藏状态:设备健康状态(正常、磨损、故障)。
输出:故障发生的可能时间点。
【8】气象预测
天气状态推断:
隐藏状态:实际天气(晴、雨、雪)。
观测序列:气象站数据或卫星云图。
示例:根据历史数据推测过去一周的真实天气序列。
暂无评论内容