作业头
| 这个作业属于哪个课程 | 自然语言处理 |
| 这个作业要求在哪里 | 利用HMM实现词性标注作业要求 |
| 我在这个课程的目标 | 更好学习自己目标课程,了解相关知识 |
| 这个作业在哪个具体方面帮助我实现目标 | 熟悉HMM对词性标注的过程 |
| 参考文献 | 1.隐马尔科夫模型 2.基于HMM的词性标注 3.机器学习基础 HMM模型(隐马尔科夫)_落花雨时的博客-CSDN博客 |
作业内容
1.利用“1998人民日报词性标注语料库”进行模型的训练。
2.根据数据估计HMM的模型参数:全部的词性集合Q,全部的词集合V ,初始概率向量PI ,词性到词性的转移矩阵A ,词性到词的转移矩阵B 。 可以采用频率估计概率的方法计算模型参数,但需要进一步采用拉普拉斯平滑处理。
3.在模型预测阶段基于维特比算法进行解码,并给出测试文本:“那个球状闪电呈橘红色,拖着一条不太长的尾迹,在夜空中沿一条变换的曲线飘行着。”的词性标注结果。
二、HMM模型的介绍
隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。然后利用这些参数来作进一步的分析,例如模式识别。
是在被建模的系统被认为是一个马尔可夫过程与未观测到的(隐藏的)的状态的统计马尔可夫模型。
在隐马尔可夫模型中,我们不仅仅有这么一串可见状态链,还有一串隐含状态链。一般来说,HMM中说到的马尔可夫链其实是指隐含状态链,因为隐含状态(球)之间存在转换概率(transition probability)。
我认为对于HMM来说,我们提前了解所有隐含状态之间的转换概率和所有隐含状态到所有可见状态之间的输出概率,做模拟是相当容易的。但是在生活中应用HMM模型时候呢,往往是缺失了一部分信息的,有时候你知道球有几种,每种球的颜色是什么,但是不知道掷出来的球序列;有时候你只是看到了很多次拿球的结果,剩下的什么都不知道。如果应用算法去估计这些缺失的信息,就成了一个很重要的问题。
三、估计HMM的模型参数
给定HMM的参数μμ和观察序列O=O1O2…OTO=O1O2…OT在时间tt位于状态sisi,时间t+1t+1位于状态sjsj的概率:
ξt(i,j)=P(qt=si,qt+1=sj|O;μ)(1≤t≤T,1≤i,j≤N)
ξt(i,j)=P(qt=si,qt+1=sj|O;μ)(1≤t≤T,1≤i,j≤N)
可由下面的公式计算获得:
ξt(i,j)=P(qt=si,qt+1=sj,O;μ)P(O;μ)=at(i)aijbj(Ot+1)βt+1(j)P(O;μ)=at(i)aijbj(Ot+1)βt+1(j)∑Ni=1∑Nj=1at(i)aijbj(Ot+1)βt+1(j)(18−1)
ξt(i,j)=P(qt=si,qt+1=sj,O;μ)P(O;μ)=at(i)aijbj(Ot+1)βt+1(j)P(O;μ)=at(i)aijbj(Ot+1)βt+1(j)∑i=1N∑j=1Nat(i)aijbj(Ot+1)βt+1(j)(18−1)
给定HMM的参数 μμ和观察序列 O=O1O2…OTO=O1O2…OT在时间 tt位于状态sisi的概率 γt(i)γt(i)为:
γt(i)=∑j=1Nξt(i,j)(18−2)
γt(i)=∑j=1Nξt(i,j)(18−2)
由此, μμ的参数可由下式估计:
πi¯=P(q1=si|O;μ)=γ1(i)a¯ij=Q中从状态qi转移到qj的期望次数Q中所有从状态qi转移到另一状态(包含qj)的期望次数=∑T−1t=1ξt(i,j)∑T−1t=1γt(i)b¯j(k)=Q中从状态qj输出符号vk的期望次数Q到达qj的期望次数=∑Tt=1γt(j)δ(Ot,vk)∑Tt=1γt(j)
πi¯=P(q1=si|O;μ)=γ1(i)a¯ij=Q中从状态qi转移到qj的期望次数Q中所有从状态qi转移到另一状态(包含qj)的期望次数=∑t=1T−1ξt(i,j)∑t=1T−1γt(i)b¯j(k)=Q中从状态qj输出符号vk的期望次数Q到达qj的期望次数=∑t=1Tγt(j)δ(Ot,vk)∑t=1Tγt(j)
前向后向算法
根据上述思路,给出前向后向算法:
1. 初始化:随机地给参数πi,aij,bj(k)πi,aij,bj(k)赋值,使得满足如下约束:
∑i=1Nπi=1∑j=1Naij=1,1≤i≤N∑k=1Mbj(k)=1,1≤j≤N
∑i=1Nπi=1∑j=1Naij=1,1≤i≤N∑k=1Mbj(k)=1,1≤j≤N
由此,得到模型 μ0μ0.令 i=0i=0,执行下面的EM估计。
2. EM计算
E步:由模型 μiμi根据公式18-1和18-2计算 ξt(i,j)ξt(i,j)和 γt(i)γt(i);
M步:用E步得到的期望值重新估计模型参数 πi,aij,bj(k)πi,aij,bj(k),得到模型 μi+1μi+1
3. 循环计算:
令 i=i+1i=i+1, 重复EM计算,直到 πi,aij,bj(k)πi,aij,bj(k)收敛。一个HMM模型实例
下面我们用一个简单的实例来描述上面抽象出的HMM模型。这是一个盒子与球的模型,例子来源于李航的《统计学习方法》。
假设我们有3个盒子,每个盒子里都有红色和白色两种球,这三个盒子里球的数量分别是:
words = set() tags = set() for words_with_tag in sentences: for word_with_tag in words_with_tag: word, tag = word_with_tag words.add(word) tags.add(tag) words = list(words) tags = list(tags) # 统计 词性到词性转移矩阵A 词性到词转移矩阵B 初始向量pi # 先初始化 A = {tag: {tag: 0 for tag in tags} for tag in tags} B = {tag: {word: 0 for word in words} for tag in tags} pi = {tag: 0 for tag in tags} # 统计A,B for words_with_tag in sentences: head_word, head_tag = words_with_tag[0] pi[head_tag] += 1 B[head_tag][head_word] += 1 for i in range(1, len(words_with_tag)): A[words_with_tag[i-1][1]][words_with_tag[i][1]] += 1 B[words_with_tag[i][1]][words_with_tag[i][0]] += 1 # 拉普拉斯平滑处理并转换成概率 sum_pi_tag = sum(pi.values()) for tag in tags: pi[tag] = (pi[tag] + 1) / (sum_pi_tag + len(tags)) sum_A_tag = sum(A[tag].values()) sum_B_tag = sum(B[tag].values()) for next_tag in tags: A[tag][next_tag] = (A[tag][next_tag] + 1) / (sum_A_tag + len(tags)) for word in words: B[tag][word] = (B[tag][word] + 1) / (sum_B_tag + len(words)以上代码是我通过同学的见解一起实现完成的可能有一些小错误。
四、基于维特比算法进行解码
维特比算法是一种动态规划算法用于寻找最有可能产生观测事件序列的-维特比路径-隐含状态序列,可以解决任何一个图中的最短路径问题,特别是在马尔可夫信息源上下文和隐马尔可夫模型中。 术语“维特比路径”和“维特比算法”也被用于寻找观察结果最有可能解释相关的动态规划算法。例如在统计句法分析中动态规划算法可以被用于发现最可能的上下文无关的派生(解析)的字符串,有时被称为“维特比分析”
def decode_by_viterbi(sentence): words = sentence.split() sen_length = len(words) T1 = [{tag: float('-inf') for tag in tags} for i in range(sen_length)] T2 = [{tag: None for tag in tags} for i in range(sen_length)] # 先进行第一步 for tag in tags: T1[0][tag] = math.log(pi[tag]) + math.log(B[tag][words[0]]) # 继续后续解码 for i in range(1, sen_length): for tag in tags: for pre_tag in tags: current_prob = T1[i-1][pre_tag] + math.log(A[pre_tag][tag]) + math.log(B[tag][words[i]]) if current_prob > T1[i][tag]: T1[i][tag] = current_prob T2[i][tag] = pre_tag # 获取最后一步的解码结果 last_step_result = [(tag, prob) for tag, prob in T1[sen_length-1].items()] last_step_result.sort(key=lambda x: -1*x[1]) last_step_tag = last_step_result[0][0] # 向前解码 step = sen_length - 1 result = [last_step_tag] while step > 0: last_step_tag = T2[step][last_step_tag] result.append(last_step_tag) step -= 1 result.reverse() return list(zip(words, result))运行结果
decode_by_viterbi('你 喝 我 的 奶茶') [('你', 'r/代词'), ('喝', 'd/动词'), ('我', 'r'/代词), ('的', 'u'/助词), ('奶茶', 'n'/名词)]主要参考:机器学习基础 HMM模型(隐马尔科夫)_落花雨时的博客-CSDN博客
以上就是我实现的结果谢谢大家观看。