HMM分词实例
class HMM(object):
def __init__(self):
import os # 主要是用于存取算法中间结果,不用每次都训练模型
self.model_file = 'model/hmm_model.pkl' # 状态值集合
self.state_list = ['B', 'M', 'E', 'S']
# 参数加载,用于判断是否需要重新加载model_file
self.load_para = False # 用于加载已计算的中间结果,当需要重新训练时,需初始化清空结果
def try_load_model(self, trained):
if trained:
import pickle
with open(self.model_file, 'rb') as f:
self.A_dic = pickle.load(f)
self.B_dic = pickle.load(f)
self.Pi_dic = pickle.load(f)
self.load_para = True else:
# 状态转移概率(状态->状态的条件概率)
self.A_dic = {}
# 发射概率(状态->词语的条件概率)
self.B_dic = {}
# 状态的初始概率
self.Pi_dic = {}
self.load_para = False # 计算转移概率、发射概率以及初始概率
def train(self, path): # 重置几个概率矩阵
self.try_load_model(False) # 统计状态出现次数,求p(o)
Count_dic = {} # 初始化参数
def init_parameters():
for state in self.state_list:
self.A_dic[state] = {s: 0.0 for s in self.state_list}
self.Pi_dic[state] = 0.0
self.B_dic[state] = {} Count_dic[state] = 0 def makeLabel(text):
out_text = []
if len(text) == 1:
out_text.append('S')
else:
out_text += ['B'] + ['M'] * (len(text) - 2) + ['E'] return out_text init_parameters()
line_num = -1
# 观察者集合,主要是字以及标点等
words = set()
with open(path, encoding='utf8') as f:
for line in f:
line_num += 1 line = line.strip()
if not line:
continue word_list = [i for i in line if i != ' ']
words |= set(word_list) # 更新字的集合 linelist = line.split() line_state = []
for w in linelist:
line_state.extend(makeLabel(w)) assert len(word_list) == len(line_state) for k, v in enumerate(line_state):
Count_dic[v] += 1
if k == 0:
self.Pi_dic[v] += 1 # 每个句子的第一个字的状态,用于计算初始状态概率
else:
self.A_dic[line_state[k - 1]][v] += 1 # 计算转移概率
self.B_dic[line_state[k]][word_list[k]] = \
self.B_dic[line_state[k]].get(word_list[k], 0) + 1.0 # 计算发射概率 self.Pi_dic = {k: v * 1.0 / line_num for k, v in self.Pi_dic.items()}
self.A_dic = {k: {k1: v1 / Count_dic[k] for k1, v1 in v.items()}
for k, v in self.A_dic.items()}
# 加1平滑
self.B_dic = {k: {k1: (v1 + 1) / Count_dic[k] for k1, v1 in v.items()}
for k, v in self.B_dic.items()}
# 序列化
import pickle
with open(self.model_file, 'wb') as f:
pickle.dump(self.A_dic, f)
pickle.dump(self.B_dic, f)
pickle.dump(self.Pi_dic, f) return self def viterbi(self, text, states, start_p, trans_p, emit_p):
V = [{}]
path = {}
# 初始状态
for y in states:
V[0][y] = start_p[y] * emit_p[y].get(text[0], 0)
path[y] = [y] # 后面状态
for t in range(1, len(text)):
V.append({})
newpath = {} # 检验训练的发射概率矩阵中是否有该字
neverSeen = text[t] not in emit_p['S'].keys() and \
text[t] not in emit_p['M'].keys() and \
text[t] not in emit_p['E'].keys() and \
text[t] not in emit_p['B'].keys()
for y in states:
emitP = emit_p[y].get(text[t], 0) if not neverSeen else 1.0 # 设置未知字单独成词
(prob, state) = max(
[(V[t - 1][y0] * trans_p[y0].get(y, 0) *
emitP, y0)
for y0 in states if V[t - 1][y0] > 0])
V[t][y] = prob newpath[y] = path[state] + [y]
path = newpath if emit_p['M'].get(text[-1], 0) > emit_p['S'].get(text[-1], 0):
(prob, state) = max([(V[len(text) - 1][y], y) for y in ('E', 'M')])
else:
(prob, state) = max([(V[len(text) - 1][y], y) for y in states]) return (prob, path[state]) def cut(self, text):
import os
if not self.load_para:
self.try_load_model(os.path.exists(self.model_file))
prob, pos_list = self.viterbi(text, self.state_list, self.Pi_dic, self.A_dic, self.B_dic)
begin, next = 0, 0
for i, char in enumerate(text):
pos = pos_list[i]
if pos == 'B':
begin = i
elif pos == 'E':
yield text[begin: i + 1]
next = i + 1
elif pos == 'S':
yield char
next = i + 1
if next < len(text):
yield text[next:]
语料库地址: 链接:https://pan.baidu.com/s/1dozkaKD8yQdt51Z-R4ExHQ 提取码:f705
HMM分词实例的更多相关文章
- Baum Welch估计HMM参数实例
Baum Welch估计HMM参数实例 下面的例子来自于<What is the expectation maximization algorithm?> 题面是:假设你有两枚硬币A与B, ...
- Bag标签之中的一个行代码实行中文分词实例2
例1: 分词(返回以逗号隔开每一个词带上引號的词组.gap=",",quotes="'"或quotes='"') 单引號 <bag id=pPa ...
- Lucene使用IKAnalyzer分词实例 及 IKAnalyzer扩展词库
文章转载自:http://www.cnblogs.com/dennisit/archive/2013/04/07/3005847.html 方案一: 基于配置的词典扩充 项目结构图如下: IK分词器还 ...
- Bag标签之中的一个行代码实行中文分词实例1
例1: 分词(返回以逗号隔开的词组,gap=",") <bagid=pPage act=2words name=words gap=",">我喜欢黄 ...
- Bag标签之中的一个行代码实行中文分词实例3
例3: 分词(返回一个书包.以_0._1._2 ...取出分好的词) <bag id=words act=2words>我喜欢黄色高领T恤衫</bag> 注意没有name属性 ...
- NLP自然语言处理中的hanlp分词实例
本篇分享的依然是关于hanlp的分词使用,文章内容分享自 gladosAI 的博客,本篇文章中提出了一个问题,hanlp分词影响了实验判断结果.为何会如此,不妨一起学习一下 gladosAI 的这篇文 ...
- Hanlp分词实例:Java实现TFIDF算法
算法介绍 最近要做领域概念的提取,TFIDF作为一个很经典的算法可以作为其中的一步处理. 关于TFIDF算法的介绍可以参考这篇博客http://www.ruanyifeng.com/blog/2013 ...
- CRF++进行中文分词实例
工具包:https://taku910.github.io/crfpp/#tips 语料:http://sighan.cs.uchicago.edu/bakeoff2005/ 安装: 1)下载linu ...
- HMM模型实例 mahout官网上的案例
原理:http://www.cnblogs.com/CheeseZH/p/4229910.html Example To build a Hidden Markov Model and use it ...
随机推荐
- B-tree B+tree适合文件系统索引和MySQL索引
B-树 B-树,这里的 B 表示 balance( 平衡的意思),B-树是一种多路自平衡的搜索树 它类似普通的平衡二叉树,不同的一点是B-树允许每个节点有更多的子节点.下图是 B-树的简化图. B-树 ...
- Scala类型检查与转换
Scala类型检查与转换 isInstanceOf:检查某个对象是否属于某个给定的类. asInstanceOf:将引用转换为子类的引用. classOf:如果想测试p指向的是一个Employee对象 ...
- ALIZE初涉
ALIZE初涉 在做GMM-UBM和i-vector时都用到了ALIZE,不得不说十分良心,在linux下很方便,但同时也有一些问题,流程总结如下 安装 在http://alize.univ-avig ...
- Android app日志保存功能
每一个App应用应该都需要有日志保存的功能,日志保存可以记录App运行中所遇到的问题,查Bug也比较方便 等等: Android日志保存功能,保存某几天的最新日志文件到某个目录,直接看是如何代码实现的 ...
- ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息
实战一 , 实战二 介绍了ActiveMQ的基本概念和配置方式. 本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之 ...
- Linux应用监控工具
Linux下的监控工具丰富繁杂,如果只知道top.free之类的就太少了,而且也不能胜任日常的Linux管理工作,尤其是在排除Web服务器问题时. 本文给出5个Linux下功能更为强大的监控工具,有了 ...
- jQuery之noConflict() 方法
jQuery 核心 - noConflict() 方法,运行这个函数将变量 $ 的控制权让渡给第一个实现它的那个库.这有助于确保jQuery不会与其他库的$对象发生冲突. noConflict() 方 ...
- Simple Package Tool 学习
Simple Package Tool 学习 1.getattr内置函数 getattr(object, name[, default]) python Packages.py install - ...
- NET 读取Word文档信息
1.添加程序集引用:WindowsBase 2.添加nuget:DocumentFormat.OpenXml 3.代码: var wordPath = @"C:\xxx.docx" ...
- 从B站、爱奇艺、映客的IPO上市,看国内视频公司的内容审核现状
本文由 网易云发布. 3月30日,中央电视台<经济半小时>栏目讲述了网络上的一个顽症——色情内容.在这期主题为<互联网上的“色诱”>的节目中,央视的记者揭示了色情直播的猖獗. ...