中文分词概述

词是最小的能够独立活动的有意义的语言成分,一般分词是自然语言处理的第一项核心技术。英文中每个句子都将词用空格或标点符号分隔开来,而在中文中很难对词的边界进行界定,难以将词划分出来。在汉语中,虽然是以字为最小单位,但是一篇文章的语义表达却仍然是以词来划分的。因此处理中文文本时,需要进行分词处理,将句子转为词的表示,这就是中文分词。

分词是词法分析(还包括词性标注和命名实体识别)中最基本的任务,可以说既简单又复杂。说简单是因为分词的算法研究已经很成熟了,大部分的准确率都可以达到95%以上,说复杂是因为剩下的5%很难有突破,主要因为三点:

  1. 粒度,不同应用对粒度的要求不一样,比如“苹果手机”可以是一个词也可以是两个词
  2. 歧义,比如“下雨天留人天留我不留”
  3. 未登录词,比如“skrrr”、“打call”等新兴词语

然而,在真实的应用中往往会因为以上的难点造成分词效果欠佳,进而影响之后的任务。对于追求算法表现的童鞋来说,不仅要会调分词包,也要对这些基础技术有一定的了解,在做真正的工业级应用时有能力对分词器进行调整。

中文分词是怎么走到今天的

话说上个世纪,中文自动分词还处于初级阶段,每句话都要到汉语词表中查找,有没有这个词?有没有这个词?所以研究集中在:怎么查找最快、最全、最准、最狠......,所以就出现了正向最大匹配法、逆向最大匹配法、双向扫描法、助词遍历法......,用新世纪比较流行的一个词来形容就是:你太low了!

中文自动分词最难的两个问题:1)歧义消除;2)未登陆词识别。说句公道话,没有上个世纪那么low的奠定基础,也就没有这个世纪研究重点提升到这两个高级的问题

ps:未登录词就是新词,词表里没有的词

本世纪计算机软硬件发展迅猛,计算量存储量都不再是问题,因此基于统计学习的自动分词技术成为主流,所以就出现了各种新分词方法,也更适用于新世纪文本特点

中文分词的三个难题:

分词规则,消除歧义和未登录词识别。

构建完美的分词规则便可以将所有的句子正确的划分,但是这根本无法实现,语言是长期发展自然而然形成的,而且语言规则庞大复杂,很难做出完美的分词规则。

在中文句子中,很多词是由歧义性的,在一句话也可能有多种分词方法。比如:”结婚/的/和尚/未结婚/的“,“结婚/的/和/尚未/结婚/的”,人分辨这样的句子都是问题,更何况是机器。

此外对于未登陆词,很难对其进行正确的划分。

目前主流分词方法:

基于规则,基于统计以及二者混合。

基于规则的分词:

主要是人工建立词库也叫做词典,通过词典匹配的方式对句子进行划分。其实现简单高效,但是对未登陆词很难进行处理。主要有正向最大匹配法,逆向最大匹配法以及双向最大匹配法。

正向最大匹配法(FMM)

FMM的步骤是:

(1)从左向右取待分汉语句的m个字作为匹配字段,m为词典中最长词的长度。

(2)查找词典进行匹配。

(3)若匹配成功,则将该字段作为一个词切分出去。

(4)若匹配不成功,则将该字段最后一个字去掉,剩下的字作为新匹配字段,进行再次匹配。

(5)重复上述过程,直到切分所有词为止。

分词的结果为:

逆向最大匹配法(RMM)

RMM的基本原理与FMM基本相同,不同的是分词的方向与FMM相反。RMM是从待分词句子的末端开始,也就是从右向左开始匹配扫描,每次取末端m个字作为匹配字段,匹配失败,则去掉匹配字段前面的一个字,继续匹配。

分词的结果为:

双向最大匹配法(Bi-MM)

Bi-MM是将正向最大匹配法得到的分词结果和逆向最大匹配法得到的结果进行比较,然后按照最大匹配原则,选取词数切分最少的作为结果。据SunM.S.和Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子,正向最大匹配法和逆向最大匹配法完全重合且正确,只有大概9.0%的句子两种切分方法得到的结果不一样,但其中必有一个是正确的(歧义检测成功),只有不到1.0%的句子,使用正向最大匹配法和逆向最大匹配法的切分虽然重合但是错的,或者两种方法切分不同但结果都不对(歧义检测失败)。

双向最大匹配的规则是:

(1)如果正反向分词结果词数不同,则取分词数量少的那个。

(2)如果分词结果词数相同:

1)分词结果相同,没有歧义,返回任意一个。

2)分词结果不同,返回其中单字数量较少的那个。

比如:上述例子中词数相同,但结果不同,逆向最大匹配法的分词结果单字个数是1,所以返回的是逆向最大匹配法的结果。

分词的结果为:

基于规则的分词,一般较为简单高效,但是词典的维护很大的人力维护,同时对于未登录词也没有很好的解决办法。双向最大匹配结合了正反两种方法的结果,结果较为准确,在实用中文信息处理中使用广泛。

统计分词:

统计分词的主要思想是把每个词看做是由字组成的,如果相连的字在不同文本中出现的次数越多,就证明这段相连的字很有可能就是一个词。

传统统计分词模型有:

1.建立统计语言模型(n-gram)(基于统计)

2.对句子进行单词划分,然后对划分结果做概率计算,获取概率最大的分词方式。这里就用到了统计学习算法,如隐马尔科夫模型(HMM),条件随机场(CRF)等(基于序列标注)

语言模型:

语言模型在信息检索,机器翻译,语音识别中承担着重要的任务。这种模型结构简单,直接,但同时也因为数据缺乏而必须采取平滑算法。这里主要介绍n元语言模型(n-gram)。

假设S表示长度为i,由(W1,W2,....,Wi)字序列组成的句子,则代表S的概率为:

P(S) = P(W1,W2,...,Wi) = P(W1)*P(W2|W1)*P(W3|W2,W1)....P(Wi|W1,W2,...,Wi-1)

即每个字的出现都与他之前出现过的字有关,最后整个句子S的概率为这些字概率的乘积。但是这个计算量很大,所以在这里我们可以利用马尔科夫假设,即当前词只与最多前n-1个有限的词相关:

当n=1时,即出现在第i位上的词Wi独立于历史时,一元文法被记作uni-gram,一元语言模型可以记作:

uni-gram

当n=2时,即出现在第i位上的词wi仅与它前面的一个历史词wi-1有关,二元文法模型被称为一阶马尔可夫链(Markov chain),记作bi-gram,二元语言模型可以记作:

bi-gram

当n=3时,即出现在第i位置上的词wi仅与它前面的两个历史词wi-2和wi-1有关,三元文法模型被称为二阶马尔可夫链,记作tri-gram,三元语言模型可以记作:

tri-gram

在实际应用中,一般使用频率计数的比例来计算n元条件概率。

基于HMM的分词:

隐含马尔可夫模型(HMM)是将分词作为字在句子中的序列标注任务来实现的(关于HMM稍后会在另一篇文章中详细介绍)。其基本思路是:每个字在构造一个特定词语时都占据着一个特定的位置即词位,一般采用四结构词位:B(词首),M(词中),E(词尾)和S(单独成词)。比如:

'中文/分词/是/文本处理/不可或缺/的/一步/!',

标注后的形式:

'中/B 文/E 分/B 词/E 是/S 文/B 本/M 处/M 理/E 不/B 可/M 或/M 缺/E 的/S 一/B 步/E !/S'。

其中,词位序列代表着HMM中不可见的隐藏状态序列,而训练集中的文本则为可见的观测序列。这样就变成了已知观测序列,求未知的隐藏序列的HMM问题。

本篇文章中,我们使用有标记的监督学习去训练HMM的参数,无监督学习的Baum-Welch方法(EM)会后续更新到本文中。

实现主要分为三步:

1.使用已经分好词的训练集去训练HMM模型,计算频数得到HMM的三要素(初始状态概率,状态转移概率和发射概率)。

训练HMM参数

2.使用Viterbi算法以及训练好的三个概率矩阵,将待分词的句子转换为'BMES'类型的状态序列。

Viterbi求最大概率序列

3.根据已经求出的状态序列,划分句子进行分词。

分词

最后测试结果:

训练参数

另外一种角度分

分词算法根据其核心思想主要分为两种,第一种是基于字典的分词,先把句子按照字典切分成词,再寻找词的最佳组合方式;第二种是基于字的分词,即由字构词,先把句子分成一个个字,再将字组合成词,寻找最优的切分策略,同时也可以转化成序列标注问题。归根结底,上述两种方法都可以归结为在图或者概率图上寻找最短路径的问题。接下来将以“他说的确实在理”这句话为例,讲解各个不同的分词算法核心思想。

2.1 基于词典的分词

2.1.1 最大匹配分词算法

最大匹配分词寻找最优组合的方式是将匹配到的最长词组合在一起。主要的思路是先将词典构造成一棵Trie树,也称为字典树,如下图:

Trie树由词的公共前缀构成节点,降低了存储空间的同时提升查找效率。最大匹配分词将句子与Trie树进行匹配,在匹配到根结点时重新由下一个字开始进行查找。比如正向(从左至右)匹配“他说的确实在理”,得出的结果为“他说/的确/实在/理”。如果进行反向最大匹配,则为“他/说/的/确实/在理”。

可见,词典分词虽然可以在O(n)时间对句子进行分词,但是效果很差,在实际情况中基本不使用此种方法。

2.1.2 最短路径分词算法

最短路径分词算法首先将一句话中的所有词匹配出来,构成词图(有向无环图DAG),之后寻找从起始点到终点的最短路径作为最佳组合方式,引用《统计自然语言处理》中的图:

图中每条边的权重都为1。

在求解DAG图的最短路径问题时,总是要利用到一种性质:即两点之间的最短路径也包含了路径上其他顶点间的最短路径。比如S->A->B->E为S到E到最短路径,那S->A->B一定是S到B到最短路径,否则会存在一点C使得d(S->C->B)<d(S->A->B),那S到E的最短路径也会变为S->C->B->E,这就与假设矛盾了。利用上述的最优子结构性质,可以利用贪心算法或动态规划两种求解算法:

  1. 最短路径分词算法

基于Dijkstra算法求解最短路径。该算法适用于所有带权有向图,求解源节点到其他所有节点的最短路径,并可以求得全局最优解。Dijkstra本质为贪心算法,在每一步走到当前路径最短的节点,递推地更新原节点到其他节点的距离。但应用于分词问题时,由于词图是带权有向无环图,无法求得全局最优解。不过针对当前问题,Dijkstra算法的计算结果为:“他/说/的/确实/在理“。可见最短路径分词算法可以满足部分分词要求。

2. N-最短路径分词算法

N-最短路径分词是对Dijkstra算法的扩展,在每一步保存最短的N条路径,并记录这些路径上当前节点的前驱,在最后求得最优解时回溯得到最短路径。该方法的准确率优于Dijkstra算法,但在时间和空间复杂度上都更大。

2.1.3 基于n-gram model的分词算法

在前文的词图中,边的权重都为1。而现实中却不一样,常用词的出现频率/概率肯定比罕见词要大。因此可以将求解词图最短路径的问题转化为求解最大概率路径的问题,即分词结果为“最有可能的词的组合“。计算词出现的概率,仅有词典是不够的,还需要有充足的语料。因此分词任务已经从单纯的“算法”上升到了“建模”,即利用统计学方法结合大数据挖掘,对“语言”进行建模。

语言模型的目的是构建一句话出现的概率p(s),根据条件概率公式我们知道:

而要真正计算“他说的确实在理”出现的概率,就必须计算出上述所有形如 n=1,...,6 的概率,计算量太过庞大,因此我们近似地认为:

其中 为字或单词。我们将上述模型成为二元语言模型(2-gram model)。类似的,如果只对词频进行统计,则为一元语言模型。由于计算量的限制,在实际应用中n一般取3。

我们将基于词的语言模型所统计出的概率分布应用到词图中,可以得到词的概率图

对该词图用2.1.2中的算法求解最大概率的路径,即可得到分词结果。

2.2 基于字的分词

与基于词典的分词不同的是,基于字的分词事先不对句子进行词的匹配,而是将分词看成序列标注问题,把一个字标记成B(Begin), I(Inside), O(Outside), E(End), S(Single)。因此也可以看成是每个字的分类问题,输入为每个字及其前后字所构成的特征,输出为分类标记。对于分类问题,可以用统计机器学习或神经网络的方法求解。

统计机器学习方法通过一系列算法对问题进行抽象,进而得到模型,再用得到的模型去解决相似的问题。也可以将模型看成一个函数,输入X,得到f(X)=Y。另外,机器学习中一般将模型分为两类:生成式模型和判别式模型,两者的本质区别在于X和Y的生成关系。生成式模型以“输出Y按照一定的规律生成输入X”为假设对P(X,Y)联合概率进行建模;判别式模型认为Y由X决定,直接对后验概率P(Y|X)进行建模。两者各有利弊,生成模型对变量的关系描述更加清晰,而判别式模型容易建立和学习。下面对几种序列标注方法做简要介绍。

2.2.1 生成式模型分词算法

生成式模型主要有n-gram模型、HMM隐马尔可夫模型、朴素贝叶斯分类等。在分词中应用比较多的是n-gram模型和HMM模型。如果将2.1.3中的节点由词改成字,则可基于字的n-gram模型进行分词,不过这种方法的效果没有基于词的效果要好。

HMM模型是常用的分词模型,基于Python的jieba分词器和基于Java的HanLP分词器都使用了HMM。要注意的是,该模型创建的概率图与上文中的DAG图并不同,因为节点具有观测概率,所以不能再用上文中的算法求解,而应该使用Viterbi算法求解最大概率的路径。

2.2.2 判别式模型分词算法

判别式模型主要有感知机、SVM支持向量机、CRF条件随机场、最大熵模型等。在分词中常用的有感知机模型和CRF模型:

  1. 平均感知机分词算法

感知机是一种简单的二分类线性模型,通过构造超平面,将特征空间(输入空间)中的样本分为正负两类。通过组合,感知机也可以处理多分类问题。但由于每次迭代都会更新模型的所有权重,被误分类的样本会造成很大影响,因此采用平均的方法,在处理完一部分样本后对更新的权重进行平均。

2. CRF分词算法

CRF可以说是目前最常用的分词、词性标注和实体识别算法,它对未登陆词有很好的识别能力,但开销较大。

2.2.3 神经网络分词算法

目前对于序列标注任务,公认效果最好的模型是BiLSTM+CRF。结构如图:

利用双向循环神经网络BiLSTM,相比于上述其它模型,可以更好的编码当前字等上下文信息,并在最终增加CRF层,核心是用Viterbi算法进行解码,以得到全局最优解,避免B,S,E这种标记结果的出现。

3. 分词算法中的数据结构

前文主要讲了分词任务中所用到的算法和模型,但在实际的工业级应用中,仅仅有算法是不够的,还需要高效的数据结构进行辅助。

3.1 词典

中文有7000多个常用字,56000多个常用词,要将这些数据加载到内存虽然容易,但进行高并发毫秒级运算是困难的,这就需要设计巧妙的数据结构和存储方式。前文提到的Trie树只可以在O(n)时间完成单模式匹配,识别出“的确”后到达Trie树对也节点,句子指针接着指向“实”,再识别“实在”,而无法识别“确实”这个词。如果要在O(n)时间完成多模式匹配,构建词图,就需要用到Aho-Corasick算法将模式串预处理为有限状态自动机,如模式串是he/she/his/hers,文本为“ushers”。构建的自动机如图:

这样,在第一次到叶节点5时,下一步的匹配可以直接从节点2开始,一次遍历就可以识别出所有的模式串。

对于数据结构的存储,一般可以用链表或者数组,两者在查找、插入和删除操作的复杂度上各有千秋。在基于Java的高性能分词器HanLP中,作者使用双数组完成了Trie树和自动机的存储。

3.2 词图

图作为一种常见的数据结构,其存储方式一般有两种:

  1. 邻接矩阵

邻接矩阵用数组下标代表节点,值代表边的权重,即d[i][j]=v代表节点i和节点j间的边权重为v。如下图:

用矩阵存储图的空间复杂度较高,在存储稀疏图时不建议使用。

2. 邻接表

邻接表对图中的每个节点建立一个单链表,对于稀疏图可以极大地节省存储空间。第i个单链表中的节点表示依附于顶点i的边,如下图:

在实际应用中,尤其是用Viterbi算法求解最优路径时,由于是按照广度优先的策略对图进行遍历,最好是使用邻接表对图进行存储,便于访问某个节点下的所有节点。

4. 总结

分词作为NLP底层任务之一,既简单又重要,很多时候上层算法的错误都是由分词结果导致的。因此,对于底层实现的算法工程师,不仅需要深入理解分词算法,更需要懂得如何高效地实现。而对于上层应用的算法工程师,在实际分词时,需要根据业务场景有选择地应用上述算法,比如在搜索引擎对大规模网页进行内容解析时,对分词对速度要求大于精度,而在智能问答中由于句子较短,对分词的精度要求大于速度。

系统学习NLP(八)--中文分词整理相关推荐

  1. 组队学习-NLP实践-中文预训练模型泛化能力挑战赛(文本分类,bert)

    组队学习-NLP实践-中文预训练模型泛化能力挑战赛 Docker 安装与使用 阿里云镜像仓库 baseline 本机运行并提交 Docker 安装与使用 参考:https://mp.weixin.qq ...

  2. 系统学习NLP(九)--中文分词算法综述

    转自:https://zhuanlan.zhihu.com/p/33261835 挺好的,推荐! 什么是中文分词 与大部分印欧语系的语言不同,中文在词与词之间没有任何空格之类的显示标志指示词的边界.因 ...

  3. 系统学习NLP(十八)--文本分类概述

    转自:https://blog.csdn.net/u014248127/article/details/80774668 文本分类问题: 给定文档p(可能含有标题t),将文档分类为n个类别中的一个或多 ...

  4. 入门科普:一文看懂NLP和中文分词算法(附代码举例)

    导读:在人类社会中,语言扮演着重要的角色,语言是人类区别于其他动物的根本标志,没有语言,人类的思维无从谈起,沟通交流更是无源之水. 所谓"自然"乃是寓意自然进化形成,是为了区分一些 ...

  5. NLP(2) | 中文分词分词的概念分词方法分类CRFHMM分词

    NLP(1) | 词向量one hot编码词向量编码思想 分词的概念 简单来说就是把词进行分开,分词的难点: 1.如何避免歧义,如:"白开水不如果汁甜".如何让机器避免将" ...

  6. 系统学习NLP(十六)--DSSM

    转自:http://blog.csdn.net/u013074302/article/details/76422551 导语 在NLP领域,语义相似度的计算一直是个难题:搜索场景下query和Doc的 ...

  7. 【NLP】中文分词:原理及分词算法

    一.中文分词 词是最小的能够独立活动的有意义的语言成分,英文单词之间是以空格作为自然分界符的,而汉语是以字为基本的书写单位,词语之间没有明显的区分标记,因此,中文词语分析是中文信息处理的基础与关键. ...

  8. NLP算法-中文分词工具-Jieba

    中文分词工具-Jieba 什么是Jieba? 1.Jieba 的特点 2.Jieba 分词的原理 3.Jieba 分词的三种模式 使用 Jieba 库进行分词 代码示例 测试说明 demo 什么是Ji ...

  9. 系统学习NLP(二十八)--GPT

    论文:Improving Language Understandingby Generative Pre-Training 1. 前言 本文对2018年OpenAi提出的论文<Improving ...

最新文章

  1. 数组去重,ES6数组去重 new Set()
  2. java之ibatis数据缓存
  3. opencv python 官方文档里的“sa”关键字是什么意思?(see also)
  4. TensorFlow--线性回归问题初步
  5. 可视化 - pyecharts
  6. Vue使用Vditor编辑器
  7. Kaggle 注册手机号以获取GPU资源
  8. 【官宣】亚马逊云科技Build On 2022年技能提升计划正式启航
  9. yum 查看java版本_如何查找YUM安装的JAVA_HOME环境变量详解
  10. 版本控制系统(SVN,Git)与项目托管平台(Github,Gitee,Coding)
  11. linux 内核互斥体,内核并发控制---互斥量
  12. 为RecyclerView打造通用Adapter
  13. ftp木马病毒photo.scr,Video.scr,AV.scr文件处理方法(windows服务器)
  14. 理解JPEG图像压缩算法,DCT变换
  15. matlab数据变成一列数据,matlab读取excel表格列数据-matlab导入excel后,怎么把数据提取成一列?...
  16. AKM 48450-1 230B 24B 40mA
  17. 在Linux中配置软 RAID,使用mdadm命令创建RAID5, RAID设备的数据恢复
  18. python_speech_features文档翻译
  19. M1 Mac安装 arm 软件
  20. cloudxns 好玩的智能解析,隐式跳转

热门文章

  1. Ubuntu18.04安装markdown工具Typora
  2. Android objdump/nm/readelf使用
  3. Ashmem、MemoryFile、Binder的共享内存(jni可用)
  4. php 怎么输入php ini,PHP怎么找到php.ini配置文件?-php教程
  5. css列名不动_利用js+css+html实现固定table的列头不动
  6. 编译原理---代码优化基础(自己看)
  7. 长春技师学院计算机系,长春技校排名前五十
  8. 星型模型 3nf的区别_数据库和数据仓库的区别和联系
  9. php h5视频录制上传,基于koa的h5视频录制异步上传
  10. tekla钢结构算量_吉林省中润钢结构科技有限公司应用BIM技术助力润德華城项目建设...