源码请到:自然语言处理练习: 学习自然语言处理时候写的一些代码 (gitee.com)

一、马尔科夫模型概念

1.1 马尔科夫模型:具有马尔可夫性质并以随机过程为基础的模型

1.2 马尔科夫性质:过去状态只能影响现在状态,影响不了将来的状态

1.3 马尔科夫过程:随机过程满足马尔科夫性质,状态转移矩阵不会随着时间的变化而发生变化

1.4 马尔科夫模型举例

如图所示,天气有晴天、多云、雷雨三种状态,三种状态之间的变换是随机的,并且三种之间的状态概率是固定的,并且昨天的天气只能影响今天的天气,对明天的天气无法产生影响,就是一个马尔科夫模型。

二、隐马尔科夫模型

2.1 在马尔科夫模型中,无法直观的观察到状态,仅仅可以观测到表象,则称之为隐马尔科夫模型。

2.2 举例:在第一节的例子中,如果是在热带雨林中,看不见天所以无法直接观测到天气的情况,但是可以通过观察海藻的生长状态来判断当前的天气,这就是个隐马尔科夫模型

2.3 隐马尔科夫模型的表示

隐马尔科夫模型可以表示为:

其中π为初始状态,A为状态转移概率矩阵,B为生成观测状态概率矩阵

2.4 隐马尔科夫模型要解决的问题

2.4.1 给定模型λ=(A,B,π)及观测序列O={o1,o2……oT} 计算其出现的概率P(O|λ)

  • 暴力求解法

推导过程如下: 

其中

其中

就是B矩阵的内容

所以

最终

时间复杂度为O(TNT) N为隐藏状态个数, 指数次复杂度,比较难得出结果

  • 前向算法

在给定t时刻隐藏状态为i,观测序列为{O1,O2……OT}的概率叫做前向概率

那么我们只需要求得T时刻所有隐藏状态的前向概率就可以了

又可以得到

有了递推公式,则这个问题被转移成了一个动态规划,时间复杂度变为了O(N2T)

举例:

观测序列为{红 白 红}

在时刻1:

红色球,盒子1:

红色球,盒子2:

红色球,盒子3:

时刻2:

白色球,盒子1:

白色球,盒子2:

白色球,盒子3:

时刻3:

红色球,盒子1:

红色球,盒子2:

红色球,盒子3:

所以

2.4.2 给定观测序列O={o1,o2……oT} 求参数λ=(A,B,π)使得P(O|λ)最大

  • 给定状态序列I={i1,i2……iT}

给定状态序列的话,模型参数十分好求

初始概率π直接查询状态序列就可以了

状态转移概率公式:

生成观测概率:

  • 未给定状态序列

需要使用em算法

列概率最大值的对数似然方程

其中后部分

可视为一个常数

所以

其中三部分分别仅存在π、A、B参数,分别使用拉格朗日乘子法就可以求解

2.4.3 已知模型λ=(A,B,π)和观测序列O={o1,o2……oT} ,求状态序列I={i1,i2……iT}使得P(O|λ)最大

维特比算法

对于t时刻,隐藏状态为i,要找到所有可能路径的最大值

递推公式为

概率最大路径中t-1的状态为

举例:

观测到序列为 {红 白 红}

t1时刻

t2时刻

t3时刻

此时3最大,所以隐藏序列为(3,3,3)

三、hmmlearn工具安装

hmmlearn工具安装十分方便,执行

pip install hmmlearn

就可以了

四、维特比算法求隐藏序列

# 隐藏状态:三个盒子
states = ['box1', 'box2', 'box3']
n_states = len(states) # 观测状态:两种球
observations = ['red', 'white']
n_observations = len(observations) # 模型参数
start_probability = np.array([0.2, 0.4, 0.4])
transition_probability = np.array([
[0.5, 0.2, 0.3],
[0.3, 0.5, 0.2],
[0.2, 0.3, 0.5]
])
emission_probability = np.array([
[0.5, 0.5],
[0.4, 0.6],
[0.7, 0.3]
]) # 用于离散观测状态的模型
model = hmm.CategoricalHMM(n_components=n_states)
model.startprob_ = start_probability
model.transmat_ = transition_probability
model.emissionprob_ = emission_probability
model.n_features = n_observations # 维特比算法,假设看到的是[红,白,红]
seen = np.array([[0, 1, 0]]).T
logprob, box = model.decode(seen, algorithm='viterbi')
print(np.array(states)[box]) box2 = model.predict(seen)
print(np.array(states)[box2])

五、求当前模型下的概率值(log形式)

# 求观测序列的可能性
print(model.score(seen))

六、给定观测序列求模型参数使得概率最大

# em算法求模型参数
model2 = hmm.CategoricalHMM(n_components=n_states, n_iter=20, tol=0.01)
X2 = np.array([[0, 1, 0, 1], [0, 0, 0, 1], [1, 0, 1, 1]])
model2.fit(X2)
print('startprob_', model2.startprob_)
print('transmat_', model2.transmat_)
print('emissionprob_', model2.emissionprob_)
print('score', model2.score(X2))

七、基于HMM算法的中文分词

将字视为观测状态,将词的位置信息视为隐藏状态,就可以实现分词啦

# 实现中文分词
# {B(词开头),M(词中),E(词尾),S(独字词)}{0,1,2,3}
data = [{u'我要吃饭': 'SSBE'}, {u'天气不错': 'BEBE'}, {u'谢天谢地': 'BMME'}] def getwords():
res = []
for line in data:
for key in line:
for word in key:
if word not in res:
res.append(word)
return ''.join(res) def get_startprob(data):
"""
获取bmes起始矩阵
:return:起始矩阵
"""
c = 0
c_map = {'B': 0, 'M': 0, 'E': 0, 'S': 0}
for v in data:
for key in v:
value = v[key]
c = c + 1
print('value[0] is ' + value[0])
c_map[value[0]] = c_map[value[0]] + 1
print('c_map[value[0]] is ' + str(c_map[value[0]]))
res = []
for i in 'BMES':
res.append(c_map[i] / float(c))
return res def get_transmat(data):
"""
获取状态转移矩阵
:return:状态转移矩阵
"""
c = 0
c_map = {}
for v in data:
for key in v:
value = v[key]
print('value[0] is ' + value[0])
for v_i in range(len(value) - 1):
couple = value[v_i:v_i + 2]
c_couple_source = c_map.get(couple, 0)
c_map[couple] = c_couple_source + 1
c = c + 1
print('get_transmat\'s c_map is ' + str(c_map))
res = []
for i in 'BMES':
col = []
col_count = 0
for j in 'BMES':
col_count = c_map.get(i + j, 0) + col_count
for j in 'BMES':
col.append(c_map.get(i + j, 0) / float(col_count))
res.append(col)
return res def get_emissionprob(data):
"""
获取现象转换矩阵
:return:现象转换矩阵
"""
c_map = {}
for v in data:
for key in v:
k = key
value = v[key]
print('value[0] is ' + value[0])
for v_i in range(len(value)):
couple = value[v_i] + k[v_i]
print('emition\'s couple is ' + couple)
c_couple_source = c_map.get(couple, 0)
c_map[couple] = c_couple_source + 1
res = []
print('emmition\'s c_map is ' + str(c_map))
words = getwords()
for i in 'BMES':
col = []
col_count = 0
for j in words:
col_count = c_map.get(i + j, 0) + col_count
for j in words:
col.append(c_map.get(i + j, 0) / float(col_count))
res.append(col)
return res def get_array_from_phase(data, phase):
c_map = {}
c = 0
for line in data:
for key in line:
for word in key:
if word not in c_map.keys():
c_map[word] = c
c = c + 1
res = []
for word in phase:
res.append(c_map[word])
return res startprob = np.array(get_startprob(data))
print('startprob is ', startprob)
transmat = np.array(get_transmat(data))
print('transmat is ', transmat)
emissionprob = np.array((get_emissionprob(data)))
print('emissionprob', emissionprob)
cate_hmm = hmm.CategoricalHMM(n_components=4)
cate_hmm.startprob_ = startprob
cate_hmm.transmat_ = transmat
cate_hmm.emissionprob_ = emissionprob
phase = u'我要吃饭谢天谢地'
X = np.array(get_array_from_phase(data, phase))
X = X.reshape(len(phase), 1)
print('X is ', X)
Y = cate_hmm.predict(X)
print('Y is ', Y)

nlp入门(五)隐马尔科夫模型的更多相关文章

  1. NLP | 自然语言处理 - 标注问题与隐马尔科夫模型(Tagging Problems, and Hidden Markov Models)

    什么是标注? 在自然语言处理中有一个常见的任务,即标注.常见的有:1)词性标注(Part-Of-Speech Tagging),将句子中的每一个词标注词性,比如名词.动词等:2)实体标注(Name E ...

  2. 隐马尔科夫模型HMM学习最佳范例

    谷歌路过这个专门介绍HMM及其相关算法的主页:http://rrurl.cn/vAgKhh 里面图文并茂动感十足,写得通俗易懂,可以说是介绍HMM很好的范例了.一个名为52nlp的博主(google ...

  3. HMM 自学教程(四)隐马尔科夫模型

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在 HMM 学习最佳范例,这是针对 国外网站上一个 HMM 教程 的翻译,作者功底很深,翻译得很精彩 ...

  4. 基于隐马尔科夫模型(HMM)的地图匹配(Map-Matching)算法

    文章目录 1. 1. 摘要 2. 2. Map-Matching(MM)问题 3. 3. 隐马尔科夫模型(HMM) 3.1. 3.1. HMM简述 3.2. 3.2. 基于HMM的Map-Matchi ...

  5. 猪猪的机器学习笔记(十七)隐马尔科夫模型HMM

    隐马尔科夫模型HMM 作者:樱花猪 摘要: 本文为七月算法(julyedu.com)12月机器学习第十七次课在线笔记.隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来 ...

  6. 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...

  7. 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态序列

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数 隐马尔科夫模型HMM(四)维特比算法解码隐藏状态 ...

  8. 机器学习之隐马尔科夫模型HMM(六)

    摘要 隐马尔可夫模型(Hidden Markov Model,HMM)是统计模型,它用来描述一个含有隐含未知参数的马尔科夫过程.其难点是从可观察的参数中确定该过程的隐含参数,然后利用这些参数来作进一步 ...

  9. 隐马尔科夫模型(HMM)与词性标注问题

    一.马尔科夫过程: 在已知目前状态(现在)的条件下,它未来的演变(将来)不依赖于它以往的演变 (过去 ).例如森林中动物头数的变化构成——马尔可夫过程.在现实世界中,有很多过程都是马尔可夫过程,如液体 ...

  10. 隐马尔科夫模型HMM

    崔晓源 翻译 我们通常都习惯寻找一个事物在一段时间里的变化规律.在很多领域我们都希望找到这个规律,比如计算机中的指令顺序,句子中的词顺序和语音中的词顺序等等.一个最适用的例子就是天气的预测. 首先,本 ...

随机推荐

  1. Django-管理员用户的创建

    命令:python manage.py createsuperuser python manage.py createsuperuser Type 'manage.py help' for usage ...

  2. transaction.atomic装饰器

    from django.shortcuts import renderfrom django.http import HttpResponsefrom django.views.generic imp ...

  3. Flutter三棵树系列之详解各种Key

    简介 key是widget.element和semanticsNode的唯一标识,同一个parent下的所有element的key不能重复,但是在特定条件下可以在不同parent下使用相同的key,比 ...

  4. linux DHCP

    目录 一.DHCP概念 二.DHCP工作过程 三.DHCP实验 一.DHCP概念 概念:动态主机配置协议,自动为计算机分配tcp/ip参数 DHCP的优点:1.减少管理员的工作难度 2.避免错误的可能 ...

  5. Doris(五) -- 数据的导入导出

    数据导入 使用 Insert 方式同步数据 用户可以通过 MySQL 协议,使用 INSERT 语句进行数据导入 INSERT 语句的使用方式和 MySQL 等数据库中 INSERT 语句的使用方式类 ...

  6. 使用脚本收发 protobuf 协议数据

    问题背景 最近做了一个 ipv6 相关的功能,发现使用 getifaddrs 获取的本地 ipv6 地址有可能不是真实的网络 ipv6 地址: 例如上图中通过 getifaddrs 获得了多个本地 i ...

  7. Vue3从入门到精通(一)

    Vue3简介 Vue3是Vue.js的最新版本,于2020年9月18日正式发布.Vue3相比Vue2有很多改进和优化,包括但不限于: 更快的渲染速度:Vue3通过使用Proxy代理对象和优化虚拟DOM ...

  8. 自研ORM 完美支持 Exists查询 非常灵活

    示例代码 Case 1 Code var data = db.Query<Product>() .Where(w => db.Query<Product>().Where ...

  9. Rust中的变量的声明和定义

    变量的声明和定义 Rust中合法的标识符(包括变量名.函数名.triat名等)必须由数字.字母.下划线组成,而且不能以数字开头.这个和很多语言都是一样的.Rust将来也会允许其他Unicode字符作为 ...

  10. Linux 线程传递参数

    1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <u ...