转:IK分词原理
IKAnalyzer是一个开源的,基于Java语言开发的轻量级的中文分词语言包,它是以Lucene为应用主体,结合词典分词和文法分析算法的中文词组组件。从3.0版本开始,IK发展为面向java的公用分词组件,独立Lucene项目,同时提供了对Lucene的默认优化实现。
以下这篇博客是我在通读IK分词代码后对IK分词的理解,如果有什么地方出现纰漏请大家指正。
回到最初
如果让我自己在看IK分词之前自己写一个分词器,那我会怎么做? 如果我会想到的是:比如对"周末有欧冠决赛"做分词处理,人为的分词是:“周末|有|欧冠|决赛”,那为什么会出现这样的分词效果,首先必须有一个词典,词典中可以标记出“周末”、“欧冠”、“决赛”这些词,因为分词器并不具备人工智能的能力,所以它所做的就是把文本和词典中的词进行比较,按照词典中已有的词进行匹配,匹配完成之后即达到了分词的效果。
现在虽然找不到第一个写分词的人是如何设计分词的算法的,但是我想是差不多的。
K分词其实也是这么来做的。将一段文字进行IK分词处理一般经过:词典加载、预处理、分词器分词、歧义处理、善后结尾 五个部分。
词典加载:
主程序需要加载词典。IK分词的词典主要包括 main2012.dic(主词典)、quantifier.dic(量词)、stopword.dic(停用词)、ext.dic(扩展词,可选)四个字典。字典的结构使用字典树进行存储。关于字典树的具体介绍可以参考: http://www.cnblogs.com/rush/archive/2012/12/30/2839996.html
预处理:
预处理是在加载文档的时候做的,其实预处理部分只是做两件事情:
- 识别出每个字符的字符类型
- 字符转化:全角转半角,大写转小写
字符类型是在分词的时候需要,不同的分词器会根据不同的字符类型做特别处理。而字符转化则是要求文本字符与词典中的字符想匹配,比如对于12288、32这两个字符,分别是汉字和英文的空格,如果一篇文本中包含了汉字包含了这两个字符,那么分词器在分词的时候需要判断两个都是空格。同理在英文大小写上也存在类似的问题。预处理主要在org.wltea.analyzer.core.CharacterUtil.java类中实现。
分词器分词:
IK分词包括三个分词器:LetterSegmenter(字符分词器),CN_QuantifierSegmenter(中文数量词分词器),CJKSegmenter(中日韩文分词器)。分词器分词有两种模式,即:smart模式和非smart模式,非smart模式可以认为是最小力度的分词,smart模式则反之。
具体的实例:
张三说的确实在理
smart模式的下分词结果为:
张三 | 说的 | 确实 | 在理
而非smart模式下的分词结果为:
张三 | 三 | 说的 | 的确 | 的 | 确实 | 实在 | 在理
IK分词使用了”正向迭代最细粒度切分算法“,简单说来就是: Segmenter会逐字识别词元,设输入”中华人民共和国“并且”中“单个字也是字典里的一个词,那么过程是这样的:”中“是词元也是前缀(因为有各种中开头的词),加入词元”中“;继续下一个词”华“,由于中是前缀,那么可以识别出”中华“,同时”中华“也是前缀因此加入”中华“词元,并把其作为前缀继续;接下来继续发现“华人”是词元,“中华人”是前缀,以此类推……
关于IK分词的三个分词器,基本上逻辑是一样的,如果有兴趣了解的话,重点看一下CJKSegmenter就好了。
歧义处理:
非smart模式所做的就是将能够分出来的词全部输出;smart模式下,IK分词器则会根据内在方法输出一个认为最合理的分词结果,这就涉及到了歧义判断。
以“张三说的确实在理”为依据,分词的结果为:
张三 | 三 | 说的 | 的确 | 的 | 确实 | 实在 | 在理
在判断歧义的时候首先要看词与词之间是否用冲突,“张三”与“三”相冲突,“说的”,“的确”,“的”,“确实”,“实在”,“在理”相冲突,所以分成两部分进行歧义判断。我们以后一种为例:“说的”,“的确”,“的”,“确实”,“实在”, 按照默认的生成的一组结果为“说的|确实|在理”,与这个结果相冲突的词是“的确”、“的”、“实在”。回滚生成的结果,将这三个词倒叙逐一放入到生成的结果中,生成可选分词方案是:
"实在"放入后,分词方案为:"说的|实在|";
"的"放入后,生成的分词方案为:"的|确实|在理";
"的确"放入后,生成的分词方案为:"的确|实在";
这样加上原有的一共四种可选的分词方案,从中选取最优的方案。选取的原则顺序如下:
1、比较有效文本长度
2、比较词元个数,越少越好
3、路径跨度越大越好
4、最后一个词元的位置越靠后约好(根据统计学结论,逆向切分概率高于正向切分,因此位置越靠后的优先)
5、词长越平均越好
6、词元位置权重比较
总体说来就是: 主要使用的就是贪心算法获取局部最优解,然后继续处理来获取最终的结果。
善后结尾:
- 处理遗漏中文字符,遍历输入文本,把词之间每个中文字符也作为词输出,虽然词典中没有这样的词。
- 处理数量词,如果中文量词刚好出现在中文数词的后面,或者中文量词刚好出现在阿拉伯数字的后面,则把数词和量词合并。比如"九寸""十二亩"。
其它
Ik的排序方法特别粗略,如果比较发现path1的词个数,比path2的个数少,就直接判定path1更优。其实这样的规则,并未完整的参考各个分出来的词的实际情况,我们可能想加入每个词经统计出现的频率等信息,做更全面的打分,这样IK原有的比较方法就是不可行的。
转:IK分词原理的更多相关文章
- IK分词器实现原理剖析 —— 一个小问题引发的思考
前言: 网上很多的文章都建议在使用IK分词器的时候,建立索引的时候使用ik_max_word模式:搜索的时候使用ik_smart模式.理由是max_word模式分词的结果会包含smart分词的结果,这 ...
- IK分词器原理与源码分析
原文:http://3dobe.com/archives/44/ 引言 做搜索技术的不可能不接触分词器.个人认为为什么搜索引擎无法被数据库所替代的原因主要有两点,一个是在数据量比较大的时候,搜索引擎的 ...
- IK分词器 原理分析 源码解析
IK分词器在是一款 基于词典和规则 的中文分词器.本文讲解的IK分词器是独立于elasticsearch.Lucene.solr,可以直接用在java代码中的部分.关于如何开发es分词插件,后续会有文 ...
- ElasticSearch已经配置好ik分词和mmseg分词(转)
ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进行数据索引 ...
- Elasticsearch使用系列-ES增删查改基本操作+ik分词
Elasticsearch使用系列-ES简介和环境搭建 Elasticsearch使用系列-ES增删查改基本操作+ik分词 一.安装可视化工具Kibana ES是一个NoSql数据库应用.和其他数据库 ...
- [Linux]Linux下安装和配置solr/tomcat/IK分词器 详细实例一.
在这里一下讲解着三个的安装和配置, 是因为solr需要使用tomcat和IK分词器, 这里会通过图文教程的形式来详解它们的安装和使用.注: 本文属于原创文章, 如若转载,请注明出处, 谢谢.关于设置I ...
- ElasticSearch ik分词安装
1.下载对应版本的ES ik分词 https://github.com/medcl/elasticsearch-analysis-ik/releases 2.解压elasticsearch-analy ...
- IK分词器 整合solr4.7 含同义词、切分词、停止词
转载请注明出处! IK分词器如果配置成 <fieldType name="text_ik" class="solr.TextField"> < ...
- Elasticsearch5.1.1+ik分词器+HEAD插件安装小记
一.安装elasticsearch 1.首先需要安装好java,并配置好环境变量,详细教程请看 http://tecadmin.net/install-java-8-on-centos-rhel-an ...
随机推荐
- 腾讯新闻构建高性能的 react 同构直出方案
在腾讯新闻抢金达人活动 node 同构直出渲染方案的总结文章中我们整体了解了下同构直出渲染方案在我们项目中的使用.正如我在上篇文章结尾所说的: 应用型技术的难点不是在克服技术问题,而是在于能够不断的结 ...
- map和set的使用及top K问题
1.map和set的应用和比较 map和set都是关联式容器,底层容器都是红黑树. map以键值对的形式进行存储,方便进行查找,关键词起到索引的作用,值则表示与索引相关联的数据,以红黑树的结构实现,插 ...
- 算法笔记codeup-Contest100000567
A 1 #include <stdio.h> 2 #include <math.h> 3 int main() 4 { 5 double a=0; 6 double b=0; ...
- maven聚合(依赖聚合)
maven聚合工程 原文地址:http://juvenshun.iteye.com/blog/305865 http://blog.csdn.NET/woxueliuyun/article/detai ...
- Ubuntu18.04.3 LTS初体验
安装系统 想来虚拟机安装太慢,正好有一台旧电脑,干脆整个乌班图系统. 启动盘工具:UltraISO,老牌工具了. 上官网下载ISO镜像文件: https://cn.ubuntu.com/downloa ...
- centos6升级openssh至7.9
1.为了防止升级失败登陆不了,所以需要安装telnet mkdir /root/ssh_updateyum install -y telnet-serveryum install -y xinetd ...
- [增强for循环] 格式
比如:
- java编程思想第四版第七章总结
1. 实现类的复用通常有两种方式 组合:在新的类中产生现有类的对象 继承:按照现有类的类型来创造新类 2. 一个特殊的方法toString() 在非基本类型的对象中, 都有toString()方法 当 ...
- hdu 3549 Flow Problem (Dinic)
Flow ProblemTime Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- 力扣(LeetCode)两整数之和 个人题解
不使用运算符 + 和 - ,计算两整数 a .b 之和. 示例 1: 输入: a = 1, b = 2 输出: 3 示例 2: 输入: a = -2, b = ...