'''
数据集:人民日报1998年中文标注语料库
------------------------------
运行结果:
-------------------原文----------------------
深圳有个打工者阅览室
去年12月,我在广东深圳市出差,听说南山区工商分局为打工者建了个免费图书阅览室,这件新鲜事引起了我的兴趣。
12月18日下午,我来到了这个阅览室。阅览室位于桂庙,临南油大道,是一间轻体房,面积约有40平方米,内部装修得整洁干净,四周的书架上摆满了书,并按政治、哲学、法律法规、文化教育、经济、科技、艺术、中国文学、外国文学等分类,屋中央有两排书架,上面也摆满了图书和杂志。一些打工青年或站或蹲,认真地阅读,不时有人到借阅台前办理借书或还书手续。南山区在深圳市西边,地处城乡结合部,外来打工者较多。去年2月,南山区工商分局局长王安全发现分局对面的公园里常有不少打工者业余时间闲逛,有时还滋扰生事。为了给这些打工者提供一个充实自己的场所,他提议由全分局工作人员捐款,兴建一个免费阅览室。领导带头,群众响应,大家捐款1.4万元,购买了近千册图书。3月6日,建在南头繁华的南新路和金鸡路交叉口的阅览室开放了。从此,这里每天都吸引了众多借书、看书的人们,其中不仅有打工者,还有机关干部、公司职员和个体户。到了夏天,由于阅览室所在地被工程征用,南山区工商分局便把阅览室迁到了桂庙。阅览室的管理人员是两名青年,男的叫张攀,女的叫赵阳。张攀自己就是湖北来的打工者,听说南山区工商分局办免费阅览室,便主动应聘来服务。阅览室每天从早9时开到晚10时,夜里张攀就住在这里。他谈起阅览室里的图书,翻着一本本的借阅名册,如数家珍,对图书和工作的挚爱之情溢于言表。我在这里碰到南山区华英大厦一位叫聂煜的女青年,她说她也是个打工者,由于春节探家回来后就要去市内工作,很留恋这里的这个免费阅览室,想抓紧时间多看些书,她还把自己买的几本杂志捐给了阅览室。在阅览室的捐书登记簿上,记录着这样的数字:工商系统内部捐书3550册,社会各界捐书250册。我在阅览室读到了这样几封感谢信:深圳瑞兴光学厂的王志明写道:“我们这些年轻人远离了家乡,来到繁华紧张的都市打工,辛劳之余,能有机会看书读报,感到特别充实。”深圳文光灯泡厂的江虹说:“南山区工商分局的干部职工捐款、捐书,给我们打工者提供良好的学习环境,鼓励我们求知上进,真是办了一件大好事,他们是我们打工者的知音。”(本报记者罗华)
-------------------分词后----------------------
深圳|有个|打|工者|阅览室
去年|12月|,|我|在|广东|深圳|市出|差|,|听|说|南|山区|工商|分局|为|打|工者|建了|个|免费|图书|阅览室|,|这件|新|鲜事|引起|了|我|的|兴趣|。
12月|18日|下午|,|我来|到|了|这个|阅览室|。|阅览|室位|于|桂庙|,|临南油|大道|,|是|一间|轻|体房|,|面积|约|有|40|平方|米|,|内|部装|修得|整洁|干净|,|四|周|的|书架|上|摆满|了|书|,|并|按|政治|、|哲学|、|法律|法规|、|文化|教育|、|经济|、|科技|、|艺术|、|中国|文学|、|外国|文学|等|分类|,|屋|中央|有|两排|书架|,|上面|也|摆满|了|图书|和|杂志|。|一些|打工|青年|或站|或|蹲|,|认真|地阅|读|,|不时|有|人到|借阅|台前|办理|借书|或|还书|手续|。|南|山区|在|深圳|市|西边|,|地处|城乡|结合部|,|外来|打|工者|较|多|。|去年|2月|,|南|山区|工商|分局|局长|王|安全|发现|分局|对面|的|公园|里|常有|不少|打|工者|业余|时间|闲逛|,|有时|还|滋扰|生事|。|为|了|给|这些|打|工者|提供|一个|充实|自己|的|场所|,|他|提议|由全|分局|工作|人员|捐款|,|兴建|一个|免费|阅览室|。|领导|带头|,|群众|响应|,|大家|捐款|1.4万|元|,|购买|了|近|千册|图书|。|3月|6日|,|建在|南头|繁华|的|南|新路|和|金鸡|路交|叉口|的|阅览室|开放|了|。|从此|,|这里|每天|都|吸引|了|众多|借书|、|看书|的|人们|,|其中|不仅|有|打|工者|,|还|有|机关|干部|、|公司|职员|和|个|体户|。|到|了|夏天|,|由于|阅览室|所|在|地|被|工程|征用|,|南|山区|工商|分局|便|把|阅览|室迁|到|了|桂庙|。|阅览室|的|管理|人员|是|两|名|青年|,|男|的|叫|张|攀|,|女|的|叫|赵阳|。|张|攀|自己|就|是|湖北|来|的|打|工者|,|听|说|南|山区|工商|分局|办|免费|阅览室|,|便|主动|应|聘来|服务|。|阅览室|每天|从|早9时|开到|晚|10|时|,|夜里|张|攀|就|住|在|这里|。|他谈|起|阅览|室里|的|图书|,|翻着|一|本本|的|借阅|名册|,|如数|家珍|,|对|图书|和|工作|的|挚爱|之|情溢|于|言表|。|我|在|这里|碰到|南|山区|华英|大厦|一位|叫|聂|煜|的|女|青年|,|她|说|她|也|是|个|打|工者|,|由于|春节|探家|回来|后|就|要|去市|内|工作|,|很|留恋|这里|的|这个|免费|阅览室|,|想|抓紧|时间|多|看些|书|,|她|还|把|自己|买|的|几本|杂志|捐给|了|阅览室|。|在|阅览室|的|捐书|登|记簿|上|,|记录|着|这样|的|数字|:|工商|系统|内部|捐书|3550册|,|社会|各界|捐书|250册|。|我|在|阅览室|读到|了|这样|几|封感|谢信|:|深圳|瑞兴|光学|厂|的|王|志明|写道|:|“|我们|这些|年|轻人|远离|了|家乡|,|来到|繁华|紧张|的|都|市|打工|,|辛劳|之余|,|能|有|机会|看书|读报|,|感到|特别|充实|。|”|深圳|文光|灯|泡厂|的|江虹|说|:|“|南|山区|工商|分局|的|干部|职工|捐款|、|捐书|,|给|我们|打|工者|提供|良好|的|学习|环境|,|鼓励|我们|求知|上进|,|真是|办|了|一件|大好|事|,|他们|是|我们|打|工者|的|知音|。|”|(|本报|记者|罗华|)
运行时长:3.6s
'''
import numpy as np
import timedef trainParameter(fileName):'''依据训练文本统计PI、A、B:param fileName: 训练文本:return: 三个参数'''#定义一个查询字典,用于映射四种标记在数组中对应的位置,方便查询# B:词语的开头# M:一个词语的中间词# E:一个词语的结果# S:非词语,单个词statuDict = {'B':0, 'M':1, 'E':2, 'S':3}#每个字只有四种状态,所以下方的各类初始化中大小的参数均为4#初始化PI的一维数组,因为对应四种状态,大小为4PI = np.zeros(4)#初始化状态转移矩阵A,涉及到四种状态各自到四种状态的转移,因为大小为4x4A = np.zeros((4, 4))#初始化观测概率矩阵,分别为四种状态到每个字的发射概率#因为是中文分词,使用ord(汉字)即可找到其对应编码,这里用一个65536的空间来保证对于所有的汉字都能#找到对应的位置来存储B = np.zeros((4, 65536))#去读训练文本fr = open(fileName, encoding='utf-8')#文本中的每一行认为是一个训练样本#在统计上,三个参数依据“10.3.2” Baum-Welch算法内描述的统计#PI依据式10.35#A依据10.37#B依据10.38#注:并没有使用Baum-Welch算法,只是借助了其内部的三个参数生成公式,其实#公式并不是Baum-Welch特有的,只是在那一节正好有描述for line in fr.readlines():#---------------------训练集单行样例--------------------#深圳  有  个  打工者  阅览室#------------------------------------------------------#可以看到训练样本已经分词完毕,词语之间空格隔开,因此我们在生成统计时主要借助以下思路:# 1.先将句子按照空格隔开,例如例句中5个词语,隔开后变成一个长度为5的列表,每个元素为一个词语# 2.对每个词语长度进行判断:#       如果为1认为该词语是S,即单个字#       如果为2则第一个是B,表开头,第二个为E,表结束#       如果大于2,则第一个为B,最后一个为E,中间全部标为M,表中间词# 3.统计PI:该句第一个字的词性对应的PI中位置加1#           例如:PI = [0, 0, 0, 0],当本行第一个字是B,即表示开头时,PI中B对应位置为0,#               则PI = [1, 0, 0, 0],全部统计结束后,按照计数值再除以总数得到概率#   统计A:对状态链中位置t和t-1的状态进行统计,在矩阵中相应位置加1,全部结束后生成概率#   统计B:对于每个字的状态以及字内容,生成状态到字的发射计数,全部结束后生成概率#   注:可以看一下“10.1.1 隐马尔可夫模型的定义”一节中三个参数的定义,会有更清晰一点的认识#-------------------------------------------------------#对单行句子按空格进行切割curLine = line.strip().split()#对词性的标记放在该列表中wordLabel = []#对每一个单词进行遍历for i in range(len(curLine)):#如果长度为1,则直接将该字标记为S,即单个词if len(curLine[i]) == 1:label = 'S'else:#如果长度不为1,开头为B,最后为E,中间添加长度-2个M#如果长度刚好为2,长度-2=0也就不添加了,反之添加对应个数的Mlabel = 'B' + 'M' * (len(curLine[i]) - 2) + 'E'#如果是单行开头第一个字,PI中对应位置加1,if i == 0: PI[statuDict[label[0]]] += 1#对于该单词中的每一个字,在生成的状态链中统计Bfor j in range(len(label)):#遍历状态链中每一个状态,并找到对应的中文汉字,在B中#对应位置加1B[statuDict[label[j]]][ord(curLine[i][j])] += 1#在整行的状态链中添加该单词的状态链#注意:extend表直接在原先元素的后方添加,#可以百度一下extend和append的区别wordLabel.extend(label)#单行所有单词都结束后,统计A信息#因为A涉及到前一个状态,因此需要等整条状态链都生成了才能开始统计for i in range(1, len(wordLabel)):#统计t时刻状态和t-1时刻状态的所有状态组合的出现次数A[statuDict[wordLabel[i - 1]]][statuDict[wordLabel[i]]] += 1#上面代码在统计上全部是统计的次数,实际运算需要使用概率,#下方代码是将三个参数的次数转换为概率#----------------------------------------#对PI求和,概率生成中的分母sum = np.sum(PI)#遍历PI中每一个元素,元素出现的次数/总次数即为概率for i in range(len(PI)):#如果某元素没有出现过,该位置为0,在后续的计算中这是不被允许的#比如说某个汉字在训练集中没有出现过,那在后续不同概率相乘中只要有#一项为0,其他都是0了,此外整条链很长的情况下,太多0-1的概率相乘#不管怎样最后的结果都会很小,很容易下溢出#所以在概率上我们习惯将其转换为log对数形式,这在书上是没有讲的#x大的时候,log也大,x小的时候,log也相应小,我们最后比较的是不同#概率的大小,所以使用log没有问题#那么当单向概率为0的时候,log没有定义,因此需要单独判断#如果该项为0,则手动赋予一个极小值if PI[i] == 0:  PI[i] = -3.14e+100#如果不为0,则计算概率,再对概率求logelse: PI[i] = np.log(PI[i] / sum)#与上方PI思路一样,求得A的概率对数for i in range(len(A)):sum = np.sum(A[i])for j in range(len(A[i])):if A[i][j] == 0: A[i][j] = -3.14e+100else: A[i][j] = np.log(A[i][j] / sum)#与上方PI思路一样,求得B的概率对数for i in range(len(B)):sum = np.sum(B[i])for j in range(len(B[i])):if B[i][j] == 0: B[i][j] = -3.14e+100else:B[i][j] = np.log(B[i][j] / sum)#返回统计得到的三个参数return PI, A, Bdef loadArticle(fileName):'''加载文章:param fileName:文件路径:return: 文章内容'''#初始化文章列表artical = []#打开文件fr = open(fileName, encoding='utf-8')#按行读取文件for line in fr.readlines():#读到的每行最后都有一个\n,使用strip将最后的回车符去掉line = line.strip()#将该行放入文章列表中artical.append(line)#将文章返回return articaldef participle(artical, PI, A, B):'''分词算法依据“10.4.2 维特比算法”:param artical:要分词的文章:param PI: 初始状态概率向量PI:param A: 状态转移矩阵:param B: 观测概率矩阵:return: 分词后的文章'''#初始化分词后的文章列表retArtical = []#对文章按行读取for line in artical:#初始化δ,δ存放四种状态的概率值,因为状态链中每个状态都有#四种概率值,因此长度时该行的长度delta = [[0 for i in range(4)] for i in range(len(line))]#依据算法10.5 第一步:初始化for i in range(4):#初始化δ状态链中第一个状态的四种状态概率delta[0][i] = PI[i] + B[i][ord(line[0])]#初始化ψ,初始时为0psi = [[0 for i in range(4)] for i in range(len(line))]#算法10.5中的第二步:递推#for循环的符号与书中公式一致,可以对比着看来理解#依次处理整条链for t in range(1, len(line)):#对于链中的米格状态,求四种状态概率for i in range(4):#初始化一个临时列表,用于存放四种概率tmpDelta = [0] * 4for j in range(4):# 计算第二步中的δ,该部分只计算max内部,不涉及后面的bi(o)# 计算得到四个结果以后,再去求那个max即可# 注:bi(Ot)并不在max的式子中,是求出max以后再乘b的#   此外读者可能注意到书中的乘法在这里变成了加法,这是由于原先是概率#   直接相乘,但我们在求得概率时,同时取了log,取完log以后,概率的乘法#   也就转换为加法了,同时也简化了运算#   所以log优点还是很多的对不?tmpDelta[j] = delta[t - 1][j] + A[j][i]#找到最大的那个δ * a,maxDelta = max(tmpDelta)#记录最大值对应的状态maxDeltaIndex = tmpDelta.index(maxDelta)#将找到的最大值乘以b放入,#注意:这里同样因为log变成了加法delta[t][i] = maxDelta + B[i][ord(line[t])]#在ψ中记录对应的最大状态索引psi[t][i] = maxDeltaIndex#建立一个状态链列表,开始生成状态链sequence = []#算法10.5 第三步:终止#在上面for循环全部结束后,很明显就到了第三步了#获取最后一个状态的最大状态概率对应的索引i_opt = delta[len(line) - 1].index(max(delta[len(line) - 1]))#在状态链中添加索引#注:状态链应该是B、M、E、S,这里图方便用了0、1、2、3,其实一样的sequence.append(i_opt)#算法10.5 第四步:最优路径回溯#从后往前遍历整条链for t in range(len(line) - 1, 0, -1):#不断地从当前时刻t的ψ列表中读取到t-1的最优状态i_opt = psi[t][i_opt]#将状态放入列表中sequence.append(i_opt)#因为是从后往前将状态放入的列表,所以这里需要翻转一下,变成了从前往后sequence.reverse()#开始对该行分词curLine = ''#遍历该行每一个字for i in range(len(line)):#在列表中放入该字curLine += line[i]#如果该字是3:S->单个词  或  2:E->结尾词 ,则在该字后面加上分隔符 |#此外如果改行的最后一个字了,也就不需要加 |if (sequence[i] == 3 or sequence[i] == 2) and i != (len(line) - 1):curLine += '|'#在返回列表中添加分词后的该行retArtical.append(curLine)#返回分词后的文章return retArticalif __name__ == '__main__':# 开始时间start = time.time()#依据现有训练集统计PI、A、BPI, A, B = trainParameter('HMMTrainSet.txt')#读取测试文章artical = loadArticle('testArtical.txt')#打印原文print('-------------------原文----------------------')for line in artical:print(line)#进行分词partiArtical = participle(artical, PI, A, B)#打印分词结果print('-------------------分词后----------------------')for line in partiArtical:print(line)#结束时间print('time span:', time.time() - start)

统计学习方法|隐马尔可夫模型相关推荐

  1. (九)统计学习方法 | 隐马尔可夫模型

    文章目录 1.隐马尔可夫模型 1.1 简介与定义 1.2 观测序列的生成 2. 隐马尔可夫模型的3个基本问题 2.1 概率计算方法 2.1.1 直接计算法 2.1.2 前向算法 2.1.3 后向算法 ...

  2. AI算法连载20:统计之隐马尔可夫模型

    导语:在人工智能AI如火如荼的大潮下,越来越多的工程师们意识到算法是AI的核心.而面对落地的应用,不懂算法的AI产品经理将是空谈,不仅无法与工程师沟通,更无法深刻理解应用的性能与方式.所以业界逐渐形成 ...

  3. 复现经典:《统计学习方法》第 10 章 隐马尔可夫模型

    本文是李航老师的<统计学习方法>[1]一书的代码复现. 作者:黄海广[2] 备注:代码都可以在github[3]中下载. 我将陆续将代码发布在公众号"机器学习初学者", ...

  4. 机器学习理论《统计学习方法》学习笔记:第十章 隐马尔可夫模型(HMM)

    第十章 隐马尔可夫模型(HMM) 摘要 隐马尔可夫模型的基本概念 前言 生成模型和判别模型 马尔可夫过程 马尔可夫链 马尔可夫模型 隐马尔可夫模型 隐马尔可夫模型的三个问题 第一 概率计算 第二 学习 ...

  5. 李航《统计学习方法》之HMM隐马尔可夫模型

    李航<统计学习方法>之HMM隐马尔可夫模型 文章目录 前言 一.基本概念 1.语言描述: 2.符号表示 3.基本假设 4.例子 5.隐马尔可夫模型解决的三个基本问题 二.概率计算算法 1. ...

  6. 10_隐马尔科夫模型HMM2_统计学习方法

    文章目录 四.学习算法 1.监督学习方法 2.非监督学习方法(Baum-Welch算法) 五.预测算法 1.近似算法 2.维特比算法 (1)最优路径特性 (2)两个变量 (3)维特比算法流程 隐马尔科 ...

  7. 10_隐马尔科夫模型HMM1_统计学习方法

    文章目录 一.几个基本概念 1.隐马尔可夫模型 2.马尔科夫链 3.随机过程 4.马尔科夫性质 二.隐马尔科夫模型 1.隐马尔科夫模型的引入 2.隐马尔科夫模型定义 3.隐马尔科夫模型的两个假设 4. ...

  8. 机器学习:《统计学习方法》笔记(一)—— 隐马尔可夫模型

    参考:<统计学习方法>--李航:隐马尔可夫模型--码农场 摘要 介绍隐马尔可夫模型的基本概念.概率计算.学习方法.预测方法等内容. 正文 1. 基本概念 隐马尔可夫模型是关于时序的模型,描 ...

  9. python做马尔科夫模型预测法_李航《统计学习方法》第十章——用Python实现隐马尔科夫模型...

    相关文章: 李航<统计学习方法>第二章--用Python实现感知器模型(MNIST数据集) 李航<统计学习方法>第三章--用Python实现KNN算法(MNIST数据集) 李航 ...

最新文章

  1. 书评 | 圈内大佬怎么看编程日历
  2. Flex布局新写法兼容写法详解
  3. Silverlight 4 新特性之Silverlight as Drop Target
  4. 使用QT的一些小Tipster
  5. RuntimeError: Model class cmdb.models.UserInfo doesn't declare an explicit app_label
  6. 统考计算机2010年版,2010年计算机专业统考试题数据结构
  7. mongodb查询值不为空_NoSQL之MongoDB——BSON与JSON类型
  8. 【负载观测】永磁同步电机的负载观测及前馈补偿
  9. mac版本 sadptool_EZParkTools下载-智慧停车维护工具 v1.0 官方版 - 安下载
  10. 美萍美发管理系统服务器名称,美萍美发管理系统2017
  11. c#获取网口扫描枪数据
  12. Java实现过滤敏感词汇
  13. 从零开始的Win10系统设置
  14. js 格式化UTC日期
  15. 基于微信小程序校园商铺系统获取(微信小程序毕业设计)
  16. 苹果有arkit,android,ARKit来袭:苹果ar支持哪些设备,苹果手机怎么使用ar?
  17. 希腊字母发音对照表及其latex命令
  18. 论做空工具体验对比,股票下跌可选择 期权?涡轮?CFD差价合约?牛熊交易获利
  19. 计算机、软件专业常去的学习网站
  20. 帧数达不到144用144hz_不看不知道 老司机告诉你60Hz和144Hz的差别

热门文章

  1. [Python基础19]收发电子邮件
  2. 保姆级教程:图解Transformer
  3. 七牛云免费对象存储使用图文教程
  4. 财政部ppp数据库爬虫
  5. 画论31 庄肃《画继补遗》
  6. 【转】产业集群互联网+怎么做?
  7. 浙大互联网协会(INA)2020~2021学年纳新启动!
  8. 杀红眼的京东又开始招人了。。。
  9. 如何测试承载网——TFN TT60 综合网络测试仪
  10. uniapp 底部菜单_uni-app 自定义底部导航栏的实现