序列标注是自然语言处理的基本任务,而隐马尔可夫模型前向算法是序列标注任务中的经典算法,在序列标注任务中,观测状态:词序列;隐状态:词性标注序列。
隐马尔可夫模型前向算法一般用于解决三类问题
<1>给定隐马尔可夫模型M=(A,B),计算某个观测序列O出现的概率,即计算P(O|M) (A表示转移概率,B表示发射概率) 。
<2> 给定一个观测序列O和一个HMM模型M,寻找最好的隐序列Q以便最好的解释观测值 (解码)
<3>使用基于统计的方法,学习最佳HMM参数模型A和B.(学习)
对于第一个任务,只要学习过贝叶斯定理就知道如何计算概率值。
第二个任务的详细解析、及C++实现的源代码
今天完成第三个任务,使用传统的基于统计的方法来进行参数估计、构建模型、并根据我们自己训练的模型对于给定的任意观测序列O,输出最佳隐序列。
概念回顾: 一个隐马尔可夫模型µ(A,B,π):
µ初始概率分布 隐藏状态的初始概率分布 :一句话中第一个词是什么词性的概率 [词性]
A转移概率分布 隐藏状态之间的转移 [词性][词性]
B发射概率分布 从观测状态转移到隐状态的概率 [词性][单词]
1.使用已经标注好的人民日报语料库
显然 语料库中第一行是中文分词后的词序列 第二行是对应的词性标注
2.读入文件
f = open("199801_dependency_treebank_2003pos2103230114.txt","r")
txt = f.read() # 一次性读入全部
f.close()
3.使用nltk工具包创建频率分布 nltk.FreqDist()
lines = txt.split("\n") # 按行切割
row = 0 # 源文本文件从第一行开始每隔四行为词汇统计行 中文分词结果
list_vocab=[]
while row<len(lines):
for word in lines[row].split(): #将分好的词全部加进list_vocab中
list_vocab.append(word)
row+=5
import nltk
fdist_vocab = nltk.FreqDist(w for w in list_vocab) #创建词汇的频率分布
row = 1 # 源文本文件从第二行开始每隔四行为词性标注统计行
list_pos=[]
while row<len(lines):
for pos in lines