白话HMM系列1——从一个缩略语还原的例子说起
HMM到底是一个什么样的东西,我想从我研究的一个应用场景开始说起。之所以想重新描述一下我对HMM的理解,是因为上次面试百度糯米的时候,自己没有把HMM在应用上说的很明白,不过糯米的那位郑姓面试官我也是服,盛气凌人完全不是招聘的样子啊,罢了,还是自己准备的不够充分,特来博客上总结一发。
我所研究的问题,概括来讲,就是缩略语的还原。且看下面的图1所示的例子:
图示很直观,怎么把网络中经常出现的武大电信院,还原为武汉大学电子信息学院呢?类似的例子还有很多,这里不再一一列举。可以说,缩略语的使用在汉语中是非常普遍的现象。如果采用字典查找的方法,当然也可以取得不错的准确率,前提是你构造的字典要足够完备,显然这种方法无法解决新登录缩略语的还原问题。这个场景,如何应用在HMM模型上,我想从这个图中,便可以很直观的感受出来:将待还原的缩略语看成是观测序列,而将缩略语对应的原短语,看成是隐马尔可夫链中的隐藏序列。这样,根据缩略语,寻找最有可能输出该缩略语的原短语,便成为了一个典型的隐马尔可夫模型的求解问题,使用Viterbi算法,便可以轻松的求解出来。
我们知道,HMM模型是基于三个假设产生的,那么这三个假设,在这个应用场景中,分别有什么意义呢?如下:
1)马尔科夫假设,即一阶马尔科夫假设。它的意思就是,下一个状态只依赖于其前一个状态,而和之前的其他状态无关(因此,由于第一个状态没有前一个状态,HMM会有一个参数pi,表示各个状态在马尔科夫链第一个位置出现的概率的大小,状态如不特别声明,都是指的隐藏状态,下同)。这里,拿武汉-大学-电子三个状态来讲,电子只依赖于大学,而和武汉没有关系。这里显然可以根据实际的应用问题,将该假设扩展为高阶假设。
2)不动性假设,也就是时间无关性假设。它的意思是说,状态i转移到状态j,在马尔科夫链上的任何位置发生的概率,是一样大的。在这个例子里面,我们可以这样理解:武汉这个状态i,出现在马尔科夫链的开头时,它转移到大学这个状态j的概率,和武汉出现在马尔科夫链的其他位置转移到大学这个状态的概率,是一样大的。但是这样的假设,在这个应用问题上,显然不是十分合适的,因为按照我们的经验来看,特定的位置上,一般会发生特定类型的转移,比如当武汉这个状态出现在比较靠前的位置,那么其转移到大学这个状态的概率就会大一些。
3)输出独立性假设。即当然得输出状态,仅和当前的隐藏状态有关,而和其他的状态没有关系。这个显然不是很好扩展,而且该假设很大的降低了计算复杂度。试想一下,如果每次你还要计算其他N个状态对该输出的影响,那么计算量是相当可怕的。但是,我们可以利用时间信息来影响输出概率。这显然是合理的,比如,当武汉这个状态出现在马尔科夫链的head处,则其输出“武”这个观测状态的概率,就需要增大,需要进行一定的加权。
这便是HMM的三个假设在该问题上的应用含义。可是,我们要利用HMM解决这个问题,需要哪些数据?我们又该如何进行,模型训练和模型求解呢?这其实就是HMM的三个基本问题:评估问题(数据集的似然概率),解码问题(找出最有可能的隐藏状态序列)以及学习问题(根据数据集训练模型参数)。HMM有三个基本的参数,A,B和pi,假设我们有N个隐藏状态,M个观测状态,则A是N阶矩,B则是N*M大小的矩阵,pi则是1*N的向量(表示第i个状态出现在位置0的概率大小)。那么在这个问题上,我们首先要确定什么是隐藏状态和观测状态。观测状态其实就是缩略语中的每一个字符,而隐藏状态则是中文词表。然而为了减小计算量,我们可以将那些不含有观测状态字符的词,生成该观测状态的概率,设置为0。
需要什么数据呢?首先,HMM的训练是一个非监督的训练(Baum-Welch算法接下来再讲解),我们只需要拿到观测序列的集合即可完成模型的EM方法求解。这是书上说的,但是要这么做,就需要先随机的初始化A和B,再不济你也可以设置A和B均匀分布,这样便可以生成任何的观测序列。然而,这样不负责任的初始化,很容易陷入局部最优解的问题,而且数学之美上也提到过,Baum-Welch算法一般没有监督方法得到的解好,但是监督训练需要大量的人工标注。因此,一般来讲,我们可以拿一份标注的数据,通过标注和统计,将A和B进行一次初始化,然后进行Baum-Welch的迭代优化。而且,由于在我的扩展中,我还需要统计位置信息,所以确实标注一下进行初始化是一个不错的选择,但是,这并不是必须的。
白话HMM系列1——从一个缩略语还原的例子说起的更多相关文章
- 用Qt写软件系列三:一个简单的系统工具(上)
导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
[0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...
- E - 小晴天老师系列——我有一个数列!
E - 小晴天老师系列——我有一个数列! Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/O ...
- [大数据从入门到放弃系列教程]第一个spark分析程序
[大数据从入门到放弃系列教程]第一个spark分析程序 原文链接:http://www.cnblogs.com/blog5277/p/8580007.html 原文作者:博客园--曲高终和寡 **** ...
- acdream 小晴天老师系列——我有一个数列! (ST算法)
小晴天老师系列——我有一个数列! Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)S ...
- 【ABAP系列】SAP 一个完整的SAP的Abap例子(idoc,edi文件的相互转换)
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP 一个完整的SAP的Aba ...
- hdu1465不easy系列之中的一个(错排)
版权声明:本文为博主原创文章,未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/37512659 转载请注明出 ...
- 【SpringBoot 基础系列】实现一个自定义配置加载器(应用篇)
[SpringBoot 基础系列]实现一个自定义配置加载器(应用篇) Spring 中提供了@Value注解,用来绑定配置,可以实现从配置文件中,读取对应的配置并赋值给成员变量:某些时候,我们的配置可 ...
- 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(中)
学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 四.创建一个Blazor应用程序 1. 第一种创 ...
随机推荐
- LightOJ-1028 Trailing Zeroes (I)---因子数目
题目链接: https://cn.vjudge.net/problem/LightOJ-1028 题目大意: 一个十进制数1≤n≤1012,现在用base进制来表示,问有多少种表示方法使得最后一位上的 ...
- Android(java)学习笔记49:通过反射获取私有构造方法并且使用
1. 反射获取私有构造方法并且使用: (1)获取字节码文件.class对象: Class c = Class.forName("cn.itcast_01.Person&qu ...
- python:线程进阶
1,守护线程 import time from threading import Thread def func(): print('开始执行子线程') time.sleep(3) print('子线 ...
- [BJWC2008]秦腾与教学评估
嘟嘟嘟 二分好题. 怎么二分呢?反正我是没想出来. 看了题解. 因为只有一个为奇数的点,所以对于一个位置x,求出区间[0, x]的教总和,如果为奇数,说明x取大了:否则x取小了(妙啊). 虽然答案在i ...
- 课堂笔记:HTML---------一般标签、常用标签
HTML:超文本标记语言 HTML标签---成对儿出现的是双标签元素,单个儿出现的是单标签元素 一.通用标签 1.格式控制标签 <font></font> 文字 color-文 ...
- PHP设计模式——观察者模式
PHP版本 <?php /** * 观察者模式 * 观察者模式能够便利的创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定性功能. * * 为软件添加由某个动作或状态变化激活的,但是松散 ...
- php 引用变量
什么是引用: 官方给的解释是:用不同的名字访问同一个变量内容. 1.普通的变量 运行之后内存空间变化是这样的: 2.引用变量 运行之后内存变化是这样的: 几乎没有什么变化. 3.使用unset 销毁的 ...
- Android学习笔记_50_(转 四种加载方式详解(standard singleTop singleTask singleInstance)
Android之四种加载方式 (http://marshal.easymorse.com/archives/2950 图片) 在多Activity开发中,有可能是自己应用之间的Activity跳转,或 ...
- Android学习笔记_22_服务Service应用之—与Activity进行相互通信的本地服务
一.启动服务的两种方法方法: 第一种: startService()和stopService()启动关闭服务.适用于服务和Activity之间没有调用交互的情况.如果相互之间需要方法调用或者传递参数 ...
- Spring知识点总结(三)之Spring DI
1. IOC(DI) - 控制反转(依赖注入) 所谓的IOC称之为控制反转,简单来说就是将对象的创建的权利及对象的生命周期的管理过程交由Spring框架来处理,从此在开发过程中不再需要关注对象的创建和 ...