【Lucene3.6.2入门系列】第04节_中文分词器
package com.jadyer.lucene; import java.io.IOException;
import java.io.StringReader; import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.analysis.tokenattributes.TypeAttribute;
import org.apache.lucene.util.Version; import com.chenlb.mmseg4j.analysis.ComplexAnalyzer;
import com.chenlb.mmseg4j.analysis.MMSegAnalyzer; /**
* 【Lucene3.6.2入门系列】第04节_中文分词器
* @see -----------------------------------------------------------------------------------------------------------------------
* @see Lucene3.5推荐的四大分词器:SimpleAnalyzer,StopAnalyzer,WhitespaceAnalyzer,StandardAnalyzer
* @see 这四大分词器有一个共同的抽象父类,此类有个方法public final TokenStream tokenStream(),即分词的一个流
* @see 假设有这样的文本"how are you thank you",实际它是以一个java.io.Reader传进分词器中
* @see Lucene分词器处理完毕后,会把整个分词转换为TokenStream,这个TokenStream中就保存所有的分词信息
* @see TokenStream有两个实现类,分别为Tokenizer和TokenFilter
* @see Tokenizer---->用于将一组数据划分为独立的语汇单元(即一个一个的单词)
* @see TokenFilter-->过滤语汇单元
* @see -----------------------------------------------------------------------------------------------------------------------
* @see 分词流程
* @see 1)将一组数据流java.io.Reader交给Tokenizer,由其将数据转换为一个个的语汇单元
* @see 2)通过大量的TokenFilter对已经分好词的数据进行过滤操作,最后产生TokenStream
* @see 3)通过TokenStream完成索引的存储
* @see -----------------------------------------------------------------------------------------------------------------------
* @see Tokenizer的一些子类
* @see KeywordTokenizer-----不分词,传什么就索引什么
* @see StandardTokenizer----标准分词,它有一些较智能的分词操作,诸如将'jadyer@yeah.net'中的'yeah.net'当作一个分词流
* @see CharTokenizer--------针对字符进行控制的,它还有两个子类WhitespaceTokenizer和LetterTokenizer
* @see WhitespaceTokenizer--使用空格进行分词,诸如将'Thank you,I am jadyer'会被分为4个词
* @see LetterTokenizer------基于文本单词的分词,它会根据标点符号来分词,诸如将'Thank you,I am jadyer'会被分为5个词
* @see LowerCaseTokenizer---它是LetterTokenizer的子类,它会将数据转为小写并分词
* @see -----------------------------------------------------------------------------------------------------------------------
* @see TokenFilter的一些子类
* @see StopFilter--------它会停用一些语汇单元
* @see LowerCaseFilter---将数据转换为小写
* @see StandardFilter----对标准输出流做一些控制
* @see PorterStemFilter--还原一些数据,比如将coming还原为come,将countries还原为country
* @see -----------------------------------------------------------------------------------------------------------------------
* @see eg:'how are you thank you'会被分词为'how','are','you','thank','you'合计5个语汇单元
* @see 那么应该保存什么东西,才能使以后在需要还原数据时保证正确的还原呢???其实主要保存三个东西,如下所示
* @see CharTermAttribute(Lucene3.5以前叫TermAttribute),OffsetAttribute,PositionIncrementAttribute
* @see 1)CharTermAttribute-----------保存相应的词汇,这里保存的就是'how','are','you','thank','you'
* @see 2)OffsetAttribute-------------保存各词汇之间的偏移量(大致理解为顺序),比如'how'的首尾字母偏移量为0和3,'are'为4和7,'thank'为12和17
* @see 3)PositionIncrementAttribute--保存词与词之间的位置增量,比如'how'和'are'增量为1,'are'和'you'之间的也是1,'you'和'thank'的也是1
* @see 但假设'are'是停用词(StopFilter的效果),那么'how'和'you'之间的位置增量就变成了2
* @see 当我们查找某一个元素时,Lucene会先通过位置增量来取这个元素,但如果两个词的位置增量相同,会发生什么情况呢
* @see 假设还有一个单词'this',它的位置增量和'how'是相同的,那么当我们在界面中搜索'this'时
* @see 也会搜到'how are you thank you',这样就可以有效的做同义词了,目前非常流行的一个叫做WordNet的东西,就可以做同义词的搜索
* @see -----------------------------------------------------------------------------------------------------------------------
* @see 中文分词器
* @see Lucene默认提供的众多分词器完全不适用中文
* @see 1)Paoding--庖丁解牛分词器,官网为http://code.google.com/p/paoding(貌似已托管在http://git.oschina.net/zhzhenqin/paoding-analysis)
* @see 2)MMSeg4j--据说它使用的是搜狗的词库,官网为https://code.google.com/p/mmseg4j(另外还有一个https://code.google.com/p/jcseg)
* @ses 3)IK-------https://code.google.com/p/ik-analyzer/
* @see -----------------------------------------------------------------------------------------------------------------------
* @see MMSeg4j的使用
* @see 1)下载mmseg4j-1.8.5.zip并引入mmseg4j-all-1.8.5-with-dic.jar
* @see 2)在需要指定分词器的位置编写new MMSegAnalyzer()即可
* @see 注1)由于使用的mmseg4j-all-1.8.5-with-dic.jar中已自带了词典,故直接new MMSegAnalyzer()即可
* @see 注2)若引入的是mmseg4j-all-1.8.5.jar,则应指明词典目录,如new MMSegAnalyzer("D:\\Develop\\mmseg4j-1.8.5\\data")
* @see 但若非要使用new MMSegAnalyzer(),则要将mmseg4j-1.8.5.zip自带的data目录拷入classpath下即可
* @see 总结:直接引入mmseg4j-all-1.8.5-with-dic.jar就行了
* @see -----------------------------------------------------------------------------------------------------------------------
* @create Aug 2, 2013 5:30:45 PM
* @author 玄玉<http://blog.csdn.net/jadyer>
*/
public class HelloChineseAnalyzer {
/**
* 查看分词信息
* @see TokenStream还有两个属性,分别为FlagsAttribute和PayloadAttribute,都是开发时用的
* @see FlagsAttribute----标注位属性
* @see PayloadAttribute--做负载的属性,用来检测是否已超过负载,超过则可以决定是否停止搜索等等
* @param txt 待分词的字符串
* @param analyzer 所使用的分词器
* @param displayAll 是否显示所有的分词信息
*/
public static void displayTokenInfo(String txt, Analyzer analyzer, boolean displayAll){
//第一个参数没有任何意义,可以随便传一个值,它只是为了显示分词
//这里就是使用指定的分词器将'txt'分词,分词后会产生一个TokenStream(可将分词后的每个单词理解为一个Token)
TokenStream stream = analyzer.tokenStream("此参数无意义", new StringReader(txt));
//用于查看每一个语汇单元的信息,即分词的每一个元素
//这里创建的属性会被添加到TokenStream流中,并随着TokenStream而增加(此属性就是用来装载每个Token的,即分词后的每个单词)
//当调用TokenStream.incrementToken()时,就会指向到这个单词流中的第一个单词,即此属性代表的就是分词后的第一个单词
//可以形象的理解成一只碗,用来盛放TokenStream中每个单词的碗,每调用一次incrementToken()后,这个碗就会盛放流中的下一个单词
CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
//用于查看位置增量(指的是语汇单元之间的距离,可理解为元素与元素之间的空格,即间隔的单元数)
PositionIncrementAttribute pia = stream.addAttribute(PositionIncrementAttribute.class);
//用于查看每个语汇单元的偏移量
OffsetAttribute oa = stream.addAttribute(OffsetAttribute.class);
//用于查看使用的分词器的类型信息
TypeAttribute ta = stream.addAttribute(TypeAttribute.class);
try {
if(displayAll){
//等价于while(stream.incrementToken())
for(; stream.incrementToken() ;){
System.out.println(ta.type() + " " + pia.getPositionIncrement() + " ["+oa.startOffset()+"-"+oa.endOffset()+"] ["+cta+"]");
}
}else{
System.out.println();
while(stream.incrementToken()){
System.out.print("[" + cta + "]");
}
}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 测试一下中文分词的效果
* @author 玄玉<http://blog.csdn.net/jadyer>
*/
public static void main(String[] args) {
String txt = "我来自中国黑龙江省哈尔滨市巴彦县兴隆镇";
displayTokenInfo(txt, new StandardAnalyzer(Version.LUCENE_36), false);
displayTokenInfo(txt, new StopAnalyzer(Version.LUCENE_36), false);
displayTokenInfo(txt, new SimpleAnalyzer(Version.LUCENE_36), false);
displayTokenInfo(txt, new WhitespaceAnalyzer(Version.LUCENE_36), false);
displayTokenInfo(txt, new MMSegAnalyzer(), false); //等价于new com.chenlb.mmseg4j.analysis.MaxWordAnalyzer()
displayTokenInfo(txt, new com.chenlb.mmseg4j.analysis.SimpleAnalyzer(), false);
displayTokenInfo(txt, new ComplexAnalyzer(), false);
}
}
【Lucene3.6.2入门系列】第04节_中文分词器的更多相关文章
- 【Lucene3.6.2入门系列】第05节_自定义停用词分词器和同义词分词器
首先是用于显示分词信息的HelloCustomAnalyzer.java package com.jadyer.lucene; import java.io.IOException; import j ...
- 【Lucene3.6.2入门系列】第03节_简述Lucene中常见的搜索功能
package com.jadyer.lucene; import java.io.File; import java.io.IOException; import java.text.SimpleD ...
- 【Lucene3.6.2入门系列】第14节_SolrJ操作索引和搜索文档以及整合中文分词
package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import org.apache.solr. ...
- 【Lucene3.6.2入门系列】第15节_SolrJ高亮
package com.jadyer.solrj; import java.util.ArrayList; import java.util.List; import java.util.Map; i ...
- 【Lucene3.6.2入门系列】第10节_Tika
首先贴出来的是演示了借助Tika创建索引的HelloTikaIndex.java PS:关于Tika的介绍及用法,详见下方的HelloTika.java package com.jadyer.luce ...
- Solr7.3.0入门教程,部署Solr到Tomcat,配置Solr中文分词器
solr 基本介绍 Apache Solr (读音: SOLer) 是一个开源的搜索服务器.Solr 使用 Java 语言开发,主要基于 HTTP 和 Apache Lucene 实现.Apache ...
- HanLP《自然语言处理入门》笔记--3.二元语法与中文分词
笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 3. 二元语法与中文分词 上一章中我们实现了块儿不准的词典分词,词典分词无法消歧. ...
- Spring Boot入门系列(十)如何使用拦截器,一学就会!
前面介绍了Spring Boot 如何整合定时任务已经Spring Boot 如何创建异步任务,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhon ...
- Solr入门之(8)中文分词器配置
Solr中虽然提供了一个中文分词器,但是效果很差,可以使用IKAnalyzer或Mmseg4j 或其他中文分词器. 一.IKAnalyzer分词器配置: 1.下载IKAnalyzer(IKAnalyz ...
随机推荐
- ASP.NET的错误处理机制
对于一个Web应用程序来说,出错是在所难免的,因此我们应该未雨绸缪,为可能出现的错误提供恰当的处理.事实上,良好的错误处理机制正是衡量Web应用程序好坏的一个重要标准.试想一下,当用户不小心在浏览器输 ...
- js 正则实例
1.匹配url参数 var re = /([^&=]+)=?([^&]*)/g while (r = re.exec("aaa1a=aabbbbbbb")) { a ...
- JS 正则 获取URL参数
function getQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&] ...
- android studio笔记之编译运行错误
错误类型: Error:java.lang.UnsupportedClassVersionError: com/android/dx/command/Main : Unsupported major错 ...
- Spark Streaming揭秘 Day32 WAL框架及实现
Spark Streaming揭秘 Day32 WAL框架及实现 今天会聚焦于SparkStreaming中非常重要的数据安全机制WAL(预写日志). 设计要点 从本质点说,WAL框架是一个存储系统, ...
- python自定义线程池
关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主 ...
- ubuntu1304下安装boa服务器
本测试在ubuntu1304下测试,具体步骤如下: 1下载源码:www.boa.org,可在ubuntu下自带的火狐浏览器下载,也可在window下下载,然后再移到ubuntu下: 2打开终端,将bo ...
- MySQL创建数据库[保存mojo格式的数据库]已经常用的utf8格式数据库
一.创建最新编码utf8mb4格式的库: CREATE DATABASE IF NOT EXISTS yourdbname CHARACTER SET utf8mb4 COLLATE utf8mb4_ ...
- Redhat 显示系统版本号和内核版本号
1./etc/issue 和 /etc/redhat-release都是系统安装时默认的发行版本信息,通常安装好系统后文件内容不会发生变化.[root@rac1 mysql]# cat /etc/is ...
- "!x++" 我之见解
"!x++"之说,各人见解不同,但真理只有一个.我只尝试着说出一种见解,未知真相. 何如? "!x++"等价于"!(x++)". 理论分析 ...