分析器是lucene中非常重要的一个组件,许多包都是分析器的子包,这是因为分析器需要支持很多不同的语言。
lucene中的分析器
分析器可能会做的事情有:将文本拆分为单词,去除标点,将字母变为小写,去除停用词,词干还原,词形归并,敏感词过滤等等。lucene中默认自带的分析器有4个:WhitespaceAnalyzer,SimpleAnalyzer,StopAnalyzer, StandardAnalyzer,分别用来过滤空白字符,过滤空白符并自动变小写,去掉停用词,标准化分词。其中,最常用的是StandardAnalyzer。分析器之所以能做这么多事,与之简洁而强大的类设计是分不开的。
事实上,这部分就使用了一个装饰器模式,但是由此可以做许多事情,因为filter可以不停的添加新功能。下面是类结构图。
Analyzer中最重要的就是tokenStream方法,它得到一个TokenStream对象。这个方法最开始从reuseStrategy中取得一个TokenStreamComponent,reuseStrategy是重用的策略,默认有两个实现GLOBAL_REUSE_STRATEGY和PER_FIELD_REUSE_STRATEGY,前者让所有field共用一个TokenStreamComponent,后者每个field一个TokenStreamComponent,而实际存储这些Component的地方是Analyzer中的storedValue。接下来初始化reader并设置到component。最后从component得到TokenStream
- public final TokenStream tokenStream(final String fieldName,
- final Reader reader) throws IOException {
- TokenStreamComponents components = reuseStrategy.getReusableComponents(this, fieldName);
- final Reader r = initReader(fieldName, reader);
- if (components == null) {
- components = createComponents(fieldName, r);
- reuseStrategy.setReusableComponents(this, fieldName, components);
- } else {
- components.setReader(r);
- }
- return components.getTokenStream();
- }
下面是lucene中一些Tokenizer和TokenFilter的列表。无论从名字还是实现都相对简单,这里就不过多分析了。
分词
接下来来看看分析器的一个比较重要的功能,分词。所谓分词,就是为了便于倒排索引的查询而将一个句子切分为一个一个的term,切分的最好标准就是每个词尽量符合它在句子中语义,但实际上往往是很难达到的。大家可以试想一下,如果是一句英文的句子,那么一种简单的分词方式可以用split(" "),这样英文中的每个单词就是一个term。但是如果是一句中文,我们能够每个字一个term吗?如果这样,那搜素出来的肯定牛头不对马嘴。因为汉语中的单词通常是词组,词组才是组成确定语义的单位。因而如何分词就是需要注意的问题了。
关于中文分词,目前大概有这样几种方法:
1. 基于字符串匹配的分词方法。比较著名的几个开源项目有IkAnalyzer和paoding。
这种分词方法简单来讲就是用待分词的句子与词典中的词进行匹配,找出最合适的匹配。这种方式实现的分词,优点是快速;但制约因素是词典本身要好,而且不在词典中的词就无法匹配,因为是纯粹匹配,碰上歧义时分词器本身也不认识到底应该识别哪一个,因而消除歧义的能力较差。比如知乎上的这样一段测试文本,中间有很多歧义的部分:“工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作”。这样的识别对这类分词器而言是比较大的挑战。
分词按照方向可以分为正向或者逆向,按照匹配的贪婪程度,可以分为最大匹配,最少次数划分(有分词理论),最细粒度匹配。之所以会有这些划分,是因为基于字符串匹配的算法通常能够解决一类问题,但是另一类会差一些。而按照这样的划分,能够给予分词一定的启发式规则。
以上面的句子为例,如果随意划分,那么开头就会是"工信/处女/干事...",显然是有问题的。
按照最大匹配划分,就是"工信处/女/干事",但是最大匹配划分也有问题,matrix67的文中有个例子"北京大学生前来应聘"会被划分为"北京大学/生前/来/应聘",这也是有问题的。
所以有逆向的匹配,比如上面这句,就可以匹配成"北京/大学生/前来/应聘"。
另一种划分方式,就是最细粒度划分,还是以最初的歧义句子为例,它可以被最细粒度划分为"工信/处女/干事/每月/月经/经过...",可以看到它并没有消除歧义,只是增加了搜索到这个句子的词。
以上这些方式实际上都是可以举出反例的,其实就是让中国人来听,汉语也只有76%的准确度。
讲讲几个开源项目IkAnalyzer, paoding和mmseg。
IkAnalyzer是用的正向迭代最细粒度切分算法以及一个智能分词法,目前IkAnalyzer实际上是比较活跃的,作者也经常更新。
paoding实际上在2010年更新了一版支持lucene3.0之后就销声匿迹了。
mmseg的算法也挺有意思,它有下面4条启发式的消除歧义规则:
1)备选词组合的长度之和最大。
2)备选词组合的平均词长最大;
3)备选词组合的词长变化最小;
4)备选词组合中,单字词的出现频率统计值最高。
最开始它从左到右扫描一遍,识别出3个词的不同组合,然后用上面4条规则匹配出最好的一个词组,然后再次用这4条规则匹配剩下的词,这样消歧能力有明显的提高。参考中有篇文章介绍mmseg,不过居然是96年发表的
2. 基于统计和机器学习的分词。比如CRF,HMM(隐式马尔科夫模型),MEMM(最大熵隐马模型)。
这种分词方式在最初需要提供一个训练集去喂,这个训练集就是已经标注好的分词词组,然后在分词阶段通过构建模型来计算各种可能分法的概率,通过概率来最终判断。实际上,这是目前公认的比较准确的方式。CRF即条件随机场(Conditional Random Field),在《数学之美》中已经对其描述过。可以想象,这个训练集对于分词的准确性也是非常重要的。CRF比隐马模型好在,隐马模型由于简化,每个观察值只考虑到了当前状态,而条件随机场则是考虑到了前后的状态。通俗的讲,隐马模型对于现在的输出也只考虑现在的条件;而CRF对于现在的输出需要考虑过去,现在和未来的条件。如图,上面是隐马模型,对于观测值x2,只取决于产生的状态y2;下图则是条件随机场,x2不仅取决于y2,还取决于y1以及y3.
CRF最初是被用来对一个句子做句法成分分析的,比如:我爱地球,通过条件随机场能判断出句子成分是:主语/谓语/宾语。而这个判断的过程是一个分类的过程。如果我们将这个分类换成一个4标记B, S, M, E的方式
- 词首,常用B表示
- 词中,常用M表示
- 词尾,常用E表示
- 单子词,常用S表示
参考:matrix67写的关于CRF的博文 http://www.matrix67.com/blog/archives/4212
另一个中文分词项目Ansj http://blog.csdn.net/blogdevteam/article/details/8148451
IkAnalyzer作者博客及项目地址 http://linliangyi2007.iteye.com/ https://code.google.com/p/ik-analyzer/
CRF的更多介绍 http://blog.csdn.net/ifengle/article/details/3849852
standford的CRF实现 http://nlp.stanford.edu/software/segmenter.shtml
CRF++实现 http://www.coreseek.cn/opensource/
mmseg http://technology.chtsai.org/mmseg/
中文分词方案(知乎) http://www.zhihu.com/question/19578687
CRF详细介绍 http://wenku.baidu.com/view/f32a35d2240c844769eaee55.html
中文分词之trie树 http://blog.csdn.net/wzb56_earl/article/details/7902669
数学之美--谈谈中文分词
中文分词与马尔科夫模型之二(隐马尔科夫模型与维特比) http://blog.sina.com.cn/s/blog_68ffc7a40100uebv.html
维特比算法 http://zh.wikipedia.org/wiki/%E7%BB%B4%E7%89%B9%E6%AF%94%E7%AE%97%E6%B3%95
http://blog.csdn.net/liweisnake/article/details/12568209
机器学习课程:http://edu.51cto.com/course/course_id-3560.html
推荐系统课程:http://edu.51cto.com/course/course_id-3792.html
大家可以加我个人微信号:scccdgf
相关推荐
### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1. 总论 全文检索系统是一种高效的信息检索技术,能够帮助用户在海量文档中快速找到包含特定关键词的信息。Lucene是Java领域内最受欢迎的全文...
在本教程中,我们将探讨如何将IK分词器集成到Lucene 4.5版本中,以提升中文文本处理的效率和准确性。 首先,让我们了解一下IKAnalyzer。IKAnalyzer是由国人开发的一款开源中文分词库,它具有较好的分词效果和较高的...
在本文中,我们将深入探讨如何将Lucene 4.5集成到SSI(Server Side Includes)系统中,以实现高效、灵活的全文搜索引擎功能。Lucene是Apache软件基金会的一个开源项目,它是一个高性能、全功能的文本搜索库,而SSI则...
Lucene学习总结之四:Lucene索引过程分析(1) Lucene学习总结之四:Lucene索引过程分析(2) Lucene学习总结之四:Lucene索引过程分析(3) Lucene学习总结之四:Lucene索引过程分析(4) www.chinaandroid.com
赠送jar包:lucene-core-7.7.0.jar; 赠送原API文档:lucene-core-7.7.0-javadoc.jar; 赠送源代码:lucene-core-7.7.0-sources.jar; 赠送Maven依赖信息文件:lucene-core-7.7.0.pom; 包含翻译后的API文档:lucene...
通过学习Lucene源码,我们可以定制自己的分词器、查询解析器,甚至优化搜索算法,以满足特定的搜索需求。例如,在中文环境下,可以使用IK Analyzer或者jieba分词库来增强对中文的支持。 总结,Lucene作为Java平台上...
24 Lucene学习总结之八:Lucene的查询语法,JavaCC及QueryParser(1)
《Lucene 2.4.1 源码分析——Analyzer深入解析》 在Lucene这个强大的全文搜索引擎库中,Analyzer扮演着至关重要的角色。它负责将输入的文本进行分词,过滤,标准化等预处理操作,使得搜索引擎能够正确理解和索引...
10. **性能调优**:通过分析源码,开发者可以了解到如何调整各种参数,如缓存大小、合并策略等,来优化Lucene的性能。 总的来说,深入学习Lucene 3.5.0的源码,可以帮助开发者掌握全文检索的核心技术,了解其内部...
- **分析器(Analyzer)**:分析器负责将用户输入的文本进行分词,形成可以被索引的术语。5.0版本提供了更多可定制的分析器,如语言敏感分析器,满足不同场景的需求。 - **查询解析器(Query Parser)**:将用户的...
赠送jar包:lucene-sandbox-6.6.0.jar; 赠送原API文档:lucene-sandbox-6.6.0-javadoc.jar; 赠送源代码:lucene-sandbox-6.6.0-sources.jar; 赠送Maven依赖信息文件:lucene-sandbox-6.6.0.pom; 包含翻译后的API...
反向信息词--->文档文件有:数据类型:Lucene索引文件中Byte:最基本的数据类型Uint32:由4个byte组成VInt:长度变化的数据类型,可能包含多
5. `contrib`:这里包含了各种社区贡献的模块,例如数据分析器、查询解析器等。 Solr-4.5.0版本的主要改进和特性: 1. **分布式搜索和复制**:SolrCloud模式允许在多个节点上分布索引,提供高可用性和故障恢复。此...
1. 分析器(Analyzer):负责将输入的文本进行分词,创建可搜索的Token流。默认的StandardAnalyzer可以处理大部分情况,但也可以根据需求自定义Analyzer。 2. 索引(Index):构建索引的过程,将文档内容转化为可...
在这个主题中,我们将对Lucene的源码进行深入的分析。 1. **Lucene的基本结构** - Lucene的核心组件包括索引(Index)、查询解析器(Query Parser)、搜索器(Searcher)和分词器(Tokenizer)。索引是搜索引擎的...
`lucene-analyzers-common-4.10.2.jar`是Lucene的通用分析器包。分析器是处理文本的关键组件,它负责将原始文本转换为可以被索引和搜索的标准化形式。这个包中包含多种语言的分析器,如英文、法文、德文等,它们能...
Lucene.Net 的源码结构清晰,分为多个模块,如索引、查询解析、分词器等,每个模块都有明确的职责。源码主要由 C# 编写,遵循面向对象的设计原则,包括封装、继承和多态。通过阅读源码,开发者可以深入了解搜索引擎...
同时,这也为自定义分析器、优化搜索性能、解决实际问题提供了便利。 总之,Lucene 2.4.1在Eclipse中的调试运行不仅是一个技术实践,也是学习和掌握全文检索技术的关键步骤。通过这种方式,我们可以逐步揭开Lucene...
《Lucene5源码教程:拼音检索与分词器实战》 在当今的信息化社会,搜索引擎已经成为我们获取信息的重要工具。Lucene,作为Apache软件基金会的开源全文检索库,为开发者提供了强大的文本检索功能。本教程将深入探讨...
4. **分析器(Analyzer)**:分析器负责处理文档中的文本,将其转化为一系列可供搜索的词项(Term)。Lucene提供了多种内置分析器,如标准分析器(StandardAnalyzer),也可以自定义分析器以适应特定需求。 5. **...