热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(转)全文检索技术学习(三)——Lucene支持中文分词

http:blog.csdn.netyerenyuan_pkuarticledetails72591778分析器(Analyzer)的执行过程如下图是语


http://blog.csdn.net/yerenyuan_pku/article/details/72591778




分析器(Analyzer)的执行过程

如下图是语汇单元的生成过程: 
 
从一个Reader字符流开始,创建一个基于Reader的Tokenizer分词器,经过三个TokenFilter生成语汇单元Token。 
要看分析器的分析效果,只需要看TokenStream中的内容就可以了。每个分析器都有一个方法tokenStream,返回的是一个TokenStream对象。


标准分析器的分词效果

之前我们创建索引库的时候,就用到了官方推荐的标准分析器——org.apache.lucene.analysis.standard.StandardAnalyzer。现在我们就来看看其分词效果,可在LuenceFirst单元测试类中编写如下方法:


public class LuenceFirst {
// 查看分析器的分词效果
@Test
public void testAnanlyzer() throws IOException { // 1、创建一个分析器对象 Analyzer analyzer = new StandardAnalyzer(); // 官方推荐的标准分析器 // 2、从分析器对象中获得tokenStream对象 // 参数1:域的名称,可以为null,或者是"" // 参数2:要分析的文本 TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a comprehensive programming and configuration model."); // 3、设置一个引用(相当于指针),这个引用可以是多种类型,可以是关键词的引用,偏移量的引用等等 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); // charTermAttribute对象代表当前的关键词 // 偏移量(其实就是关键词在文档中出现的位置,拿到这个位置有什么用呢?因为我们将来可能要对该关键词进行高亮显示,进行高亮显示要知道这个关键词在哪?) OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); // 4、调用tokenStream的reset方法,不调用该方法,会抛出一个异常 tokenStream.reset(); // 5、使用while循环来遍历单词列表 while (tokenStream.incrementToken()) { System.out.println("start→" + offsetAttribute.startOffset()); // 关键词起始位置 // 6、打印单词 System.out.println(charTermAttribute); System.out.println("end→" + offsetAttribute.endOffset()); // 关键词结束位置 } // 7、关闭tokenStream对象 tokenStream.close(); } }

 


  • 运行以上方法,Eclipse控制台打印: 

 
从上图中我们可以清楚地看到当前的关键词,以及该关键词的起始位置和结束位置。


中文分析器分析

Lucene自带中文分词器


Lucene自带的中文分词器有:


  • StandardAnalyzer 
    单字分词,就是按照中文一个字一个字地进行分词。如:“我爱中国”,效果:“我”、“爱”、“中”、“国”。
  • CJKAnalyzer 
    二分法分词,按两个字进行切分。如:“我是中国人”,效果:“我是”、“是中”、“中国”、“国人”。 
    上边这两个分词器一看就无法满足需求。
  • SmartChineseAnalyzer 
    对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理。

现在我们来看看第三个中文分析器的分析效果,相比前两个中文分析器,SmartChineseAnalyzer绝对要胜出一筹。为了观看其分析效果,我们可将LuenceFirst单元测试类中的testAnanlyzer方法改造为:


public class LuenceFirst {
// 查看分析器的分词效果
@Test
public void testAnanlyzer() throws IOException { // 1、创建一个分析器对象 Analyzer analyzer = new SmartChineseAnalyzer(); // 智能中文分析器 // 2、从分析器对象中获得tokenStream对象 // 参数1:域的名称,可以为null,或者是"" // 参数2:要分析的文本 TokenStream tokenStream = analyzer.tokenStream("", "数据库中存储的数据是结构化数据,即行数据java,可以用二维表结构来逻辑表达实现的数据。"); // 3、设置一个引用(相当于指针),这个引用可以是多种类型,可以是关键词的引用,偏移量的引用等等 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); // charTermAttribute对象代表当前的关键词 // 偏移量(其实就是关键词在文档中出现的位置,拿到这个位置有什么用呢?因为我们将来可能要对该关键词进行高亮显示,进行高亮显示要知道这个关键词在哪?) OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); // 4、调用tokenStream的reset方法,不调用该方法,会抛出一个异常 tokenStream.reset(); // 5、使用while循环来遍历单词列表 while (tokenStream.incrementToken()) { System.out.println("start→" + offsetAttribute.startOffset()); // 关键词起始位置 // 6、打印单词 System.out.println(charTermAttribute); System.out.println("end→" + offsetAttribute.endOffset()); // 关键词结束位置 } // 7、关闭tokenStream对象 tokenStream.close(); } }

  • 1
  • 2

运行以上方法,Eclipse控制台打印: 
 
虽然SmartChineseAnalyzer分析器对中文支持较好,但扩展性差,扩展词库,禁用词库和同义词库等不好处理。故实际开发中我们也是弃用的,取而代之的是第三方中文分析器。


第三方中文分析器


第三方中文分析器有:


  • paoding:庖丁解牛最新版在https://code.google.com/p/paoding/ ,其最多只支持Lucene3.0,且最新提交的代码在2008-06-03,在svn中最新也是2010年提交,已经过时,不予考虑。
  • mmseg4j:最新版已从https://code.google.com/p/mmseg4j/移至https://github.com/chenlb/mmseg4j-solr,支持Lucene4.10,且在github中最新提交代码是2014年6月,从09年~14年一共有18个版本,也就是一年几乎有3个大小版本,有较大的活跃度,用了mmseg算法。
  • IK-analyzer:最新版在https://code.google.com/p/ik-analyzer/上,支持Lucene4.10,从2006年12月推出1.0版开始,IKAnalyzer已经推出了4个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。从3.0版本开始,IK发展为面向Java的公用分词组件,独立于Lucene项,同时提供了对Lucene的默认优化实现。在2012版本中,IK实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。但是也就在2012年12月后没有再更新了。
  • ansj_seg:最新版本在[https://github.com/NLPchina/ansj_seg tags](https://github.com/NLPchina/ansj_seg tags),仅有1.1版本,从2012年到2014年更新了大小6次,但是作者本人在2014年10月10日说明:“可能我以后没有精力来维护ansj_seg了”,现在由”nlp_china”管理。2014年11月有更新。并未说明是否支持Lucene,是一个由CRF(条件随机场)算法所做的分词算法。
  • imdict-chinese-analyzer:最新版在https://code.google.com/p/imdict-chinese-analyzer/,最新更新也在2009年5月,可下载源码,不支持Lucene4.10。它是利用HMM(隐马尔科夫链)算法。
  • Jcseg:最新版本在git.oschina.net/lionsoul/jcseg,支持Lucene 4.10,作者有较高的活跃度。其利用的是mmseg算法。

但在这里,我使用的是IK-analyzer,所以下面的讲解也是围绕着该中文分析器来进行的。下面是我下载的IK-analyzer: 
 
解压缩之后,其目录结构是: 


IK-analyzer中文分析器的使用


IK-analyzer中文分析器的使用步骤:


  1. 把IKAnalyzer2012FF_u1.jar包添加到工程中。
  2. 把配置文件和扩展词典和停用词词典添加到classpath下。

注意:扩展词典和停用词词典这两个文件的字符集一定要保证是UTF-8字符集,注意是无BOM的UTF-8编码,严禁使用Windows的记事本编辑。 
下面我们来看看IK-analyzer这个第三方中文分析器的分析效果。现在随着互联网的日趋发展,网络用语层出不穷,例如“高富帅”,“白富美”等等,像这样的网络用语是不需要进行分词的,而是当作一个整体的关键词, 这样像这种不用分词的网络用语就应该存储在扩展词典中。为了清楚地观看IK-analyzer这个第三方中文分析器的分析效果,在扩展词典添加“高富帅”。如下: 
 
接着将LuenceFirst单元测试类中的testAnanlyzer方法改造为:


public class LuenceFirst {
// 查看分析器的分词效果
@Test
public void testAnanlyzer() throws IOException { // 1、创建一个分析器对象 Analyzer analyzer = new IKAnalyzer(); // 智能中文分析器 // 2、从分析器对象中获得tokenStream对象 // 参数1:域的名称,可以为null,或者是"" // 参数2:要分析的文本 TokenStream tokenStream = analyzer.tokenStream("", "数据库中存储的数据是结构化数据高富帅,即行数据java,可以用二维表结构来逻辑表达实现的数据。"); // 3、设置一个引用(相当于指针),这个引用可以是多种类型,可以是关键词的引用,偏移量的引用等等 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); // charTermAttribute对象代表当前的关键词 // 偏移量(其实就是关键词在文档中出现的位置,拿到这个位置有什么用呢?因为我们将来可能要对该关键词进行高亮显示,进行高亮显示要知道这个关键词在哪?) OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); // 4、调用tokenStream的reset方法,不调用该方法,会抛出一个异常 tokenStream.reset(); // 5、使用while循环来遍历单词列表 while (tokenStream.incrementToken()) { System.out.println("start→" + offsetAttribute.startOffset()); // 关键词起始位置 // 6、打印单词 System.out.println(charTermAttribute); System.out.println("end→" + offsetAttribute.endOffset()); // 关键词结束位置 } // 7、关闭tokenStream对象 tokenStream.close(); } }

  • 1

运行以上方法,Eclipse控制台打印: 
 
从上图可清楚地看出“高富帅”并没有分词,这正是我们所期望的结果。 
除此之外,对于一些敏感的词,如“习”,像这样的敏感词汇就不应该出现在单词列表中,所以可将这种敏感词汇存储在停用词词典中,如下: 
 
接着将LuenceFirst单元测试类中的testAnanlyzer方法改造为:


public class LuenceFirst {
// 查看分析器的分词效果
@Test
public void testAnanlyzer() throws IOException { // 1、创建一个分析器对象 Analyzer analyzer = new IKAnalyzer(); // 智能中文分析器 // 2、从分析器对象中获得tokenStream对象 // 参数1:域的名称,可以为null,或者是"" // 参数2:要分析的文本 TokenStream tokenStream = analyzer.tokenStream("", "数据库中存储的数据是结构化数据高富帅,即行数据java,可以用二维表结构来逻辑表达实现的数据。"); // 3、设置一个引用(相当于指针),这个引用可以是多种类型,可以是关键词的引用,偏移量的引用等等 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); // charTermAttribute对象代表当前的关键词 // 偏移量(其实就是关键词在文档中出现的位置,拿到这个位置有什么用呢?因为我们将来可能要对该关键词进行高亮显示,进行高亮显示要知道这个关键词在哪?) OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); // 4、调用tokenStream的reset方法,不调用该方法,会抛出一个异常 tokenStream.reset(); // 5、使用while循环来遍历单词列表 while (tokenStream.incrementToken()) { System.out.println("start→" + offsetAttribute.startOffset()); // 关键词起始位置 // 6、打印单词 System.out.println(charTermAttribute); System.out.println("end→" + offsetAttribute.endOffset()); // 关键词结束位置 } // 7、关闭tokenStream对象 tokenStream.close(); } }

  • 1

运行以上方法,Eclipse控制台打印: 
 
从上图可知,像“”这样的敏感词汇并没有出现在单词列表中。


分析器的应用场景

索引时使用Analyzer


输入关键字进行搜索,当需要让该关键字与文档域内容所包含的词进行匹配时需要对文档域内容进行分析,需要经过Analyzer分析器处理生成语汇单元(Token)。分析器分析的对象是文档中的Field域。当Field的属性tokenized(是否分词)为true时会对Field值进行分析,如下图: 

对于一些Field可以不用分析:


  1. 不作为查询条件的内容,比如文件路径
  2. 不是匹配内容中的词而匹配Field的整体内容,比如订单号、身份证号等

搜索时使用Analyzer


对搜索关键字进行分析和索引分析一样,使用Analyzer对搜索关键字进行分析、分词处理,使用分析后的每个词语进行搜索。比如:搜索关键字:spring web,经过分析器进行分词,得出:spring web,拿词去索引词典表查找 ,找到索引链接到Document,解析Document内容。 
对于匹配整体Field域的查询可以在搜索时不分析,比如根据订单号、身份证号查询等。 
注意:搜索使用的分析器要和索引使用的分析器最好保持一致





 







0










推荐阅读
  • SpringBoot整合SpringSecurity+JWT实现单点登录
    SpringBoot整合SpringSecurity+JWT实现单点登录,Go语言社区,Golang程序员人脉社 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记
    本文介绍了大数据Hadoop生态(20)MapReduce框架原理OutputFormat的开发笔记,包括outputFormat接口实现类、自定义outputFormat步骤和案例。案例中将包含nty的日志输出到nty.log文件,其他日志输出到other.log文件。同时提供了一些相关网址供参考。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 标题: ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • Sleuth+zipkin链路追踪SpringCloud微服务的解决方案
    在庞大的微服务群中,随着业务扩展,微服务个数增多,系统调用链路复杂化。Sleuth+zipkin是解决SpringCloud微服务定位和追踪的方案。通过TraceId将不同服务调用的日志串联起来,实现请求链路跟踪。通过Feign调用和Request传递TraceId,将整个调用链路的服务日志归组合并,提供定位和追踪的功能。 ... [详细]
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • 项目运行环境配置及可行性分析
    本文介绍了项目运行环境配置的要求,包括Jdk1.8、Tomcat7.0、Mysql、HBuilderX等工具的使用。同时对项目的技术可行性、操作可行性、经济可行性、时间可行性和法律可行性进行了分析。通过对数据库的设计和功能模块的设计,确保系统的完整性和安全性。在系统登录、系统功能模块、管理员功能模块等方面进行了详细的介绍和展示。最后提供了JAVA毕设帮助、指导、源码分享和调试部署的服务。 ... [详细]
  • Struts2+Sring+Hibernate简单配置
    2019独角兽企业重金招聘Python工程师标准Struts2SpringHibernate搭建全解!Struts2SpringHibernate是J2EE的最 ... [详细]
author-avatar
总裁班的草根
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有