【自然语言处理】— 隐马尔可夫模型详解、例解

本文详细介绍了自然语言处理中的隐马尔可夫模型(HMM),包括其基本概念、关键要素(隐含状态、可见状态、状态转移概率和观测概率)、数学表示以及在掷骰子示例中的应用。模型由状态转移矩阵、观测概率矩阵和初始状态概率向量共同决定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【自然语言处理】— 隐马尔可夫模型

引例

假设有三种不同的骰子,分别是立方体,正四面体,正八面体,分别有1-6,1-4,1-8,分别记作D6、D4、D8。每个面出现的概率分别是1/6,1/4,1/8。
在这里插入图片描述

在不观察的情况下,从三个骰子中随机选一个,进行抛掷,结果可能是1-8中的任意数字。依照这种方式,随机选择骰子,重复抛掷,可以得到一串数字,这串数字对我们是可见的,并且直接记录下来了,因此将这串数字记作可见状态链
在这里插入图片描述
在抛掷的过程中,被我们随机选择的骰子编号也组成了一串序列,因为我们是随机选择的骰子,因此将这串序列称为隐含状态链
在这里插入图片描述
实验过程中产生了两个数据链,隐含状态链和可见状态链,隐马尔可夫模型=隐含状态链➕可见状态链
在这里插入图片描述

隐马尔可夫模型概念

隐马尔可夫模型(Hidden Markov Model),简称HMM,它是关于时序的概率模型,该模型包含随机生成的不可观测序列,该序列被称为状态序列,使用S表示,每个不可观测状态都会产生一个可观测的结果,这样会得到一个观测序列,使用O表示。

在这里插入图片描述

每个状态和时刻都会与一个时刻进行对应,如果有t个时刻,就产生了 s 1 → s t , o 1 → o t s_1→s_t,o_1→o_t s1sto1ot,相当于一次一次掷骰子,t就代表第几次掷骰子
在这里插入图片描述

在HMM中,状态序列是隐藏的,无法被观测到,因此状态变量是一个隐变量,隐藏的状态序列是由一个马尔可夫链,随机生成的

隐马尔可夫模型的关键

在隐马尔可夫模型中, 包含了四个关键因素,分别是:

  1. 隐含状态
  2. 可见状态
  3. 隐含状态转换
  4. 可见状态输出

在这里插入图片描述

各个隐含状态之间会进行转换,存在着对应的转换概率

隐含状态会输出可见状态,隐含状态和可见状态之间有一个输出概率,不同隐含状态到可见状态的输出概率可能不同

例如,隐含状态D6输出可见状态1到6概率是 1 6 \cfrac{1}{6} 61,隐含状态D4输出可见状态1到4概率是 1 4 \cfrac{1}{4} 41

在这里插入图片描述

隐马尔可夫模型的数学表示

为了进一步讨论隐马尔可夫模型,需要使用数学符号来表示HMM,其中包括隐含状态 Q Q Q和观测结果 V V V两个集合,状态转移概率矩阵 A A A,观测概率矩阵 B B B,初始状态概率向量 π \pi π,三个概率矩阵。

隐含状态与观测结果

例如,隐含状态集合 Q = { q 1 , q 2 , . . . , q n } Q = \{q_1,q_2,...,q_n\} Q={q1,q2,...,qn}包括 q 1 到 q n n q_1到q_n n q1qnn种状态
观测结果集合 V = { v 1 , v 2 , . . . , v m } V=\{v_1,v_2,...,v_m\} V={v1,v2,...,vm}包括 v 1 到 v m m v_1到v_m m v1vmm种可能的结果

在掷骰子的案例中, n = 3     q 1 , q 2 , q 3 对应 D 6 , D 4 , D 8 n=3\ \ \ q_1,q_2,q_3对应D_6,D_4,D_8 n=3   q1,q2,q3对应D6,D4,D8
m = 8     v 1 到 v 8 对应数字 1 到 8 m=8 \ \ \ v_1到v_8对应数字1到8 m=8   v1v8对应数字18

在这里插入图片描述

状态转移矩阵

状态转移的概率矩阵 A A A是一个是一个 N ∗ N N*N NN的矩阵
在这里插入图片描述

其中 a i j a_{ij} aij代表了状态 q i q_i qi转移到状态 q j q_j qj的概率
在这里插入图片描述
具体地, a i j 等于在 s t = q i 的条件下, s t + 1 = q j 的概率 a_{ij}等于在s_t = q_i的条件下,s_{t+1}=q_j的概率 aij等于在st=qi的条件下,st+1=qj的概率

在这里插入图片描述
例如,3个骰子,选择任意骰子的概率都是 1 3 \cfrac{1}{3} 31,那么就得到了 3 ∗ 3 3*3 33的状态转移概率矩阵,其中的每个元素都是 0.33 0.33 0.33

在这里插入图片描述

观测概率矩阵

观测概率矩阵为 B B B,由于每一个状态 q q q都可以输出一个观测结果 v v v,因此B是一个 N ∗ M N*M NM的矩阵

在这里插入图片描述
其中 b i j b_ij bij代表了在时刻 t t t,状态 q i q_i qi输出观测结果 v j v_j vj的概率。

例如,在掷骰子时,根据三种骰子的输出,可以得到一个 3 ∗ 8 3*8 38的概率矩阵,第一行对应六面骰子,输出1到6的概率是1/6,输出7和8的概率是0,而第二行和第三行,分别代表投掷四面骰子和八面骰子的输出1到8的概率

在这里插入图片描述

初始状态概率向量

初始状态的概率向量是 π \pi π,它是一个 N ∗ 1 N*1 N1的列向量, π i \pi_i πi代表在时刻 t = 1 t=1 t=1时,状态为 q i q_i qi的概率,例如,掷骰子时,三种骰子的概率都是1/3
在这里插入图片描述

小结

π 和 A \pi和A πA确定了隐藏的马尔可夫链,也就是如何生成不可观测的状态序列 S S S B B B确定了如何从隐藏状态产生观测状态序列 O O O,隐马尔可夫模型由 A 、 B 、 π A、B、\pi ABπ共同决定,使用三元符号 λ = ( A , B , π ) λ=(A,B,\pi) λ=(A,B,π)表示。
在这里插入图片描述

参考视频:什么是HMM隐马尔可夫模型,自然语言处理中的最基础算法之一_哔哩哔哩_bilibili

### 关于自然语言处理中的隐马尔可夫模型实验 #### 实验概述 隐马尔可夫模型(Hidden Markov Model, HMM)是一种强大的工具,在自然语言处理领域被广泛应用于各种任务,如语音识别、中文分词等。对于中文分词而言,HMM可以通过定义四种不同的隐藏状态——‘S’(单字成词),‘B’(词组的开头),‘M’(词组的中间), ‘E’(词组的结尾)—来进行有效的建模[^5]。 #### 示代码及其释 下面是一个简单的Python程序片段,展示了如何基于给定的数据集训练一个用于中文分词的HMM,并使用维特比算法对新的句子进行预测: ```python import numpy as np class HMMSegmentation: def __init__(self): self.start_probabilities = {} # 初始概率分布 self.transition_probabilities = {} # 状态转移矩阵 self.emission_probabilities = {} # 发射概率表 def train(self, training_data): """从已标注数据集中估计HMM参数""" state_counts = {'B': 0, 'M': 0, 'E': 0, 'S': 0} transition_matrix = {state: {'B': 0, 'M': 0, 'E': 0, 'S': 0} for state in ['B', 'M', 'E', 'S']} emission_table = {} prev_state = None total_transitions = 0 for sentence in training_data: words = sentence.split() if not words: continue current_states = [] char_index = 0 while char_index < len(''.join(words)): word_length = len(words[char_index // (len(sentence)-sum(len(w)for w in words[:char_index//len(words)]))]) if word_length == 1: current_states.append('S') char_index += 1 elif char_index % word_length == 0 and char_index != 0: current_states.extend(['B'] + ['M'] * (word_length - 2) + ['E']) char_index += word_length assert len(current_states) == sum([len(word) for word in words]), f"Length mismatch between states ({current_states}) and characters." start_char = True for i, c in enumerate(''.join(words)): s = current_states[i] if start_char: try: self.start_probabilities[s] += 1 except KeyError: self.start_probabilities[s] = 1 start_char = False else: transition_matrix[prev_s][s] += 1 total_transitions += 1 try: emission_table[(c, s)] += 1 except KeyError: emission_table[(c, s)] = 1 prev_s = s transition_matrix['E']['B'] += 1 total_transitions += 1 # 归一化转换概率发射概率 for from_state in transition_matrix.keys(): row_sum = float(sum(list(transition_matrix[from_state].values()))) for to_state in transition_matrix[from_state]: transition_matrix[from_state][to_state] /= max(row_sum, 1e-9) for key in list(emission_table.keys()): count = emission_table[key] character, tag = key if character not in emission_probabilities: emission_probabilities[character] = {} emission_probabilities[character][tag] = count / float(state_counts[tag]) # 更新成员变量 self.transition_probabilities.update(transition_matrix) self.emission_probabilities.update(emission_probabilities) def viterbi(observation_sequence, hmm_model): """应用Viterbi算法寻找最有可能的状态序列""" V = [{}] path = {} # 初始化首列的概率值 for y in ["B", "M", "E", "S"]: obs = observation_sequence[0] if obs in hmm_model.emission_probabilities and \ y in hmm_model.emission_probabilities[obs]: emi_p = hmm_model.emission_probabilities[obs][y] else: emi_p = 1e-9 init_p = hmm_model.start_probabilities.get(y, 1e-9) V[0][y] = init_p * emi_p path[y] = [y] for t in range(1, len(observation_sequence)): V.append({}) new_path = {} last_node = [(k, V[t-1][k]) for k in ("B", "M", "E", "S")] for y in ["B", "M", "E", "S"]: prob, state = max( ((V[t-1][y0]*hmm_model.transition_probabilities[y0].get(y, 1e-9)*emi, y0) for y0, last_max in last_node), default=(None, None)) if prob is None or prob <= 0: prob = 1e-9 state = "S" obs_t = observation_sequence[t] if obs_t in hmm_model.emission_probabilities and \ y in hmm_model.emission_probabilities[obs_t]: emi = hmm_model.emission_probabilities[obs_t][y] else: emi = 1e-9 V[t][y] = prob*emi new_path[y] = path[state]+[y] path = new_path n = len(observation_sequence)-1 final_prob, final_state = max(((V[n][y], y) for y in ('E','S')),default=(None,None)) return path[final_state] if __name__ == "__main__": sentences = [ "我/爱/自/然
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之墨_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值