当前位置:   article > 正文

自然语言处理系列二十三》词性标注》词性标注原理》HMM词性标注_hmm 标注

hmm 标注

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】

自然语言处理系列二十三

词性标注

词性标注(Part-Of-Speech tagging, POS tagging)也被称为语法标注(grammatical tagging)或词类消疑(word-category disambiguation),是语料库语言学(corpus linguistics)中将语料库内单词的词性按其含义和上下文内容进行标记的文本数据处理技术。
词性标注可以由人工或特定算法完成,使用机器学习(machine learning)方法实现词性标注是自然语言处理(Natural Language Processing, NLP)的研究内容。常见的词性标注算法包括隐马尔可夫模型(Hidden Markov Model, HMM)、条件随机场(Conditional random fields, CRFs)等。词性标注主要被应用于文本挖掘(text mining)和NLP领域,是各类基于文本的机器学习任务,例如语义分析(semantic analysis)和指代消解(coreference resolution)的预处理步骤。下面我们分别从原理和实战工具给大家详细讲解。

HMM词性标注

HMM也就是隐马尔科夫模型,我们再回顾下其原理,隐马尔科夫模型是结构最简单的动态贝叶斯网络。描述由一个隐藏的马尔科夫链随机生成不可观测的状态随机序列,再由各个状态生成一个观测而产生随机序列的过程。隐藏的马尔科夫链随机生成的状态的序列称为状态序列,每个状态生成一个观测,称为观测序列。
隐马尔科夫做了两个基本的假设:
齐次马尔科夫假设,即假设隐藏的马尔科夫链在任意时刻t的状态只依赖于前一时刻的状态,去其他观测状态无关。
观测独立性假设,即假设任意时刻的观测只依赖于该时刻的马尔科夫链的状态,与其他观测以及状态无关。
隐马尔科夫模型由初始状态概率向量π,状态转移概率矩阵A,以及观测概率矩阵B决定。
在词性标注问题中,初始状态概率为每个语句序列开头出现的词性的概率,状态转移概率矩阵由相邻两个单词的词性得到,观测序列为分词后的单词序列,状态序列为每个单词的词性,观测概率矩阵B也就是一个词性到单词的概率矩阵。
隐马尔科夫模型有三个基本问题:
概率计算问题,给出模型和观测序列,计算在模型λ下观测序列O出现的概率
学习问题,估计模型λ=(A,B,π)参数,使得该模型下观测序列P(0|λ)最大,也就是用极大似然的方法估计参数
观测问题,已知模型λ和观测序列O,求对给的观测序列条件概率P(I|O)最大的状态序列I,即给的观测序列,求最可能的状态序列。
在词性标注问题中,需要解决的是学习问题和观测问题。学习问题即转移矩阵的构建,观测问题即根据单词序列得到对应的词性标注序列。
接下来我们举个例子用Python代码实现。
例子:小明和小芳是两个城市的学生,现在小明知道小芳在下雨天时待在家看电视的概率为60%、出去逛街的概率为10%,洗衣服的概率为30%;晴天时洗衣服的概率为45%,出去逛街的概率为50%,在家看电视的概率为5%;阴天时出去逛街的概率为55%,洗衣服的概率为30%,看电视的概率为15%。那么三天内小芳出现“逛街-洗衣服-看电视”的情况的概率是多少?
HMM的构成主要有以下五个参数:
1.模型的状态数(晴天,雨天,阴天)
2.模型的观测数(逛街,洗衣,看电视)
3.模型的状态转移概率矩阵Aij,表示step n-1 到step n 状态i下一个是状态j的概率
4.模型的状态发射概率矩阵Bi(k)表示i状态下产生k观测状态的概率
5.π初始状态分布概率矩阵。
首先求解上面的参数,代码如下所示:

def ChinesePOS():
    #转移概率Aij,t时刻由状态i变为状态J的频率
    #观测概率Bj(k),由状态J观测为K的概率
    #PAI i 初始状态q出现的频率
    #先验概率矩阵
    pi = {}
    a = {}
    b = {}
#所有的词语
    ww = {}
#所有的词性
    pos = []
    #每个词性出现的频率
    frep = {}
    #每个词出现的频率
    frew = {}
    fin = codecs.open("处理语料.txt","r","utf8")
    for line in fin.readlines():
        temp = line.strip().split(" ")
        for i in range(1,len(temp)):
            word = temp[i].split("/")
            if len(word) == 2:
                if word[0] not in ww:
                    ww[word[0]] = 1
 
                if word[1] not in pos:
                    pos.append(word[1])
    fin.close()
    ww = ww.keys()
    for i in pos:
        #初始化相关参数
        pi[i] = 0
        frep[i] = 0
        a[i] = {}
        b[i] = {}
        for j in pos:
            a[i][j] = 0
        for j in ww:
            b[i][j] = 0
    for w in ww:
        frew[w] = 0
    line_num = 0
    #计算概率矩阵
    fin= codecs.open("处理语料.txt","r","utf8")
    for line in fin.readlines():
        if line == "\n":
            continue
        tmp = line.strip().split(" ")
        n = len(tmp)
        line_num += 1
        for i in range(1,n):
            word = tmp[i].split("/")
            pre = tmp[i-1].split("/")
            #计算词性频率和词频率
            frew[word[0]] += 1
            frep[word[1]] += 1
            if i ==1:
                pi[word[1]] += 1
            else :
                a[pre[1]][word[1]] += 1
            b[word[1]][word[0]] += 1
    for i in pos:
        #计算各个词性的初始概率
        pi[i] = float(pi[i])/line_num
        for j in pos:
            if a[i][j] == 0:
                a[i][j] = 0.5
        for j in ww:
            if b[i][j] == 0:
                b[i][j] = 0.5
    for i in pos:
        for j in pos:
            #求状态i的转移概率分布
            a[i][j] = float(a[i][j])/(frep[i])
        for j in ww:
            #求词j的发射概率分布
            b[i][j] = float(b[i][j])/(frew[j])
    return a,b,pi,pos,frew,frep
    print "game over"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

参数求解完毕运用动态规划的viterbi算法求解最佳路径,代码如下所示:

def viterbi(a,b,pi,str_token,pos,frew,frep):
    # dp = {}
    #计算文本长度
    num = len(str_token)
    #绘制概率转移路径
    dp = [{} for i in range(0,num)]
    #状态转移路径
    pre = [{} for i in range(0,num)]
    for k in pos:
        for j in range(num):
            dp[j][k] = 0
            pre[j][k] = ''
#句子初始化状态概率分布(首个词在所有词性的概率分布)
    for p in pos:
 
 
        if b[p].has_key(str_token[0]):
 
            dp[0][p] = pi[p]*b[p][str_token[0]]* 1000
        else:
            dp[0][p] = pi[p]*0.5*1000
    for i in range(0,num):
        for j in pos:
            if (b[j].has_key(str_token[i])):
                sep = b[j][str_token[i]] * 1000
            else:
                #计算发射概率,这个词不存在,应该置0.5/frew[str_token[i]],这里默认为1
                sep = 0.5 * 1000
            for k in pos:
                #计算本step i 的状态是j的最佳概率和step i-1的最佳状态k(计算结果为step i 所有可能状态的最佳概率与其对应step i-1的最优状态)
                if (dp[i][j]<dp[i-1][k]*a[k][j]*sep):
 
                    dp[i][j] = dp[i-1][k]*a[k][j]*sep
                    #各个step最优状态转移路径
                    pre[i][j] = k
    resp = {}
    #
    max_state = ""
    #首先找到最后输出的最大观测值的状态设置为max_state
    for j in pos:
        if max_state=="" or dp[num-1][j] > dp[num-1][max_state]:
            max_state = j
    # print
    i = num -1
#根据最大观测值max_state和前面求的pre找到概率最大的一条。
    while i>=0:
        resp[i] = max_state
        max_state = pre[i][max_state]
        i -= 1
    for i in range(0,num):
        print str_token[i] +"\\" +resp[i].encode("utf8")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

主入口函数代码如下所示:

if __name__ == "__main__":
    a,b,pi,pos,frew,frep = ChinesePOS()
    #北京/ns 举行/v 新年/t 音乐会/n
    str_token = [u"北京",u"举行",u"新年",u"音乐会"]
    viterbi(a, b, pi, str_token, pos, frew,frep)
  • 1
  • 2
  • 3
  • 4
  • 5

运行结果如下:
北京\ns
举行\v
新年\t
音乐会\n

总结

此文章有对应的配套视频,其它更多精彩文章请大家下载充电了么app,可获取千万免费好课和文章,配套新书教材请看陈敬雷新书:《分布式机器学习实战》(人工智能科学与技术丛书)

【新书介绍】
《分布式机器学习实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】
新书特色:深入浅出,逐步讲解分布式机器学习的框架及应用配套个性化推荐算法系统、人脸识别、对话机器人等实战项目

【新书介绍视频】
分布式机器学习实战(人工智能科学与技术丛书)新书【陈敬雷】
视频特色:重点对新书进行介绍,最新前沿技术热点剖析,技术职业规划建议!听完此课你对人工智能领域将有一个崭新的技术视野!职业发展也将有更加清晰的认识!

【精品课程】
《分布式机器学习实战》大数据人工智能AI专家级精品课程

【免费体验视频】:
人工智能百万年薪成长路线/从Python到最新热点技术

从Python编程零基础小白入门到人工智能高级实战系列课

视频特色: 本系列专家级精品课有对应的配套书籍《分布式机器学习实战》,精品课和书籍可以互补式学习,彼此相互补充,大大提高了学习效率。本系列课和书籍是以分布式机器学习为主线,并对其依赖的大数据技术做了详细介绍,之后对目前主流的分布式机器学习框架和算法进行重点讲解,本系列课和书籍侧重实战,最后讲几个工业级的系统实战项目给大家。 课程核心内容有互联网公司大数据和人工智能那些事、大数据算法系统架构、大数据基础、Python编程、Java编程、Scala编程、Docker容器、Mahout分布式机器学习平台、Spark分布式机器学习平台、分布式深度学习框架和神经网络算法、自然语言处理算法、工业级完整系统实战(推荐算法系统实战、人脸识别实战、对话机器人实战)、就业/面试技巧/职业生涯规划/职业晋升指导等内容。

【充电了么公司介绍】

充电了么App是专注上班族职业培训充电学习的在线教育平台。

专注工作职业技能提升和学习,提高工作效率,带来经济效益!今天你充电了么?

充电了么官网
http://www.chongdianleme.com/

充电了么App官网下载地址
https://a.app.qq.com/o/simple.jsp?pkgname=com.charged.app

功能特色如下:

【全行业职位】 - 专注职场上班族职业技能提升

覆盖所有行业和职位,不管你是上班族,高管,还是创业都有你要学习的视频和文章。其中大数据智能AI、区块链、深度学习是互联网一线工业级的实战经验。

除了专业技能学习,还有通用职场技能,比如企业管理、股权激励和设计、职业生涯规划、社交礼仪、沟通技巧、演讲技巧、开会技巧、发邮件技巧、工作压力如何放松、人脉关系等等,全方位提高你的专业水平和整体素质。

【牛人课堂】 - 学习牛人的工作经验

1.智能个性化引擎:

海量视频课程,覆盖所有行业、所有职位,通过不同行业职位的技能词偏好挖掘分析,智能匹配你目前职位最感兴趣的技能学习课程。

2.听课全网搜索

输入关键词搜索海量视频课程,应有尽有,总有适合你的课程。

3.听课播放详情

视频播放详情,除了播放当前视频,更有相关视频课程和文章阅读,对某个技能知识点强化,让你轻松成为某个领域的资深专家。

【精品阅读】 - 技能文章兴趣阅读

1.个性化阅读引擎:

千万级文章阅读,覆盖所有行业、所有职位,通过不同行业职位的技能词偏好挖掘分析,智能匹配你目前职位最感兴趣的技能学习文章。

2.阅读全网搜索

输入关键词搜索海量文章阅读,应有尽有,总有你感兴趣的技能学习文章。

【机器人老师】 - 个人提升趣味学习

基于搜索引擎和智能深度学习训练,为您打造更懂你的机器人老师,用自然语言和机器人老师聊天学习,寓教于乐,高效学习,快乐人生。

【精短课程】 - 高效学习知识

海量精短牛人课程,满足你的时间碎片化学习,快速提高某个技能知识点。

上一篇:自然语言处理系列二十二》词性标注》词性标注原理》词性介绍
下一篇:自然语言处理系列二十四》词性标注》词性标注原理》感知器词性标注

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/348941
推荐阅读
相关标签
  

闽ICP备14008679号