IKAnalyzer分词器及lucene使用IKAnalyzer分析_第1页
IKAnalyzer分词器及lucene使用IKAnalyzer分析_第2页
IKAnalyzer分词器及lucene使用IKAnalyzer分析_第3页
IKAnalyzer分词器及lucene使用IKAnalyzer分析_第4页
IKAnalyzer分词器及lucene使用IKAnalyzer分析_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、IKAnalyzer版本Jar包下载IKAnalyzer3.2.8_bin下载地址:下载后包含说明及API文档(在目录doc3.2.8中)。源码下载IKSegmentation浅析(纯IK分词)IKSegmentation是IK中独立的分词器,和lucene没有关系。不继承,不扩展,不使用lucene相关的类。IK主分词器构造函数/* * IK主分词器构造函数 * param input * param isMaxWordLength 当为true时,分词器进行最大词长切分 */public IKSegmentation(Reader input , boolean isMaxWordLeng

2、th)this.input = input ;segmentBuff = new charBUFF_SIZE;context = new Context(segmentBuff , isMaxWordLength);segmenters = Configuration.loadSegmenter();Reader input 是一个输入流,用于读取文件内容。IKSegmentation的构造器,作了3个事1、 new Context(segmentBuff , isMaxWordLength) 创建上下文对象Contextcontext = new Context(segmentBuff ,

3、isMaxWordLength);Contex主要是存储分词结果集和记录分词处理的游标位置。2、 Configuration.loadSegmenter() 加载词典、创建分词器 Configuration.loadSegmenter() 方法实现在加载词典,创建分词器详情如下。/* * 初始化子分词器实现 * (目前暂时不考虑配置扩展) * return List<ISegmenter> */public static List<ISegmenter> loadSegmenter()/初始化词典单例,如果查看getInstance()发现里面有详细的初始化词典的相关方

4、法Dictionary.getInstance();List<ISegmenter> segmenters = new ArrayList<ISegmenter>(4);/处理数量词的子分词器segmenters.add(new QuantifierSegmenter();/处理中文词的子分词器segmenters.add(new CJKSegmenter();/处理字母的子分词器segmenters.add(new LetterSegmenter(); return segmenters;得到Lexeme 这是IK分词器的语义单元对象,相当于Lucene中的Token

5、词元对象。由于3.0版本被设计为独立于Lucene的Java分词器实现,因此它需要Lexeme来代表分词的结果。调用的next()方法,会返回Lexeme 对象,如果没有下一个分词结果,会返回null。源码如下/* * 获取下一个语义单元 * return 没有更多的词元,则返回null * throws IOException */public synchronized Lexeme next() throws IOException if(context.getResultSize() = 0)/* * 从reader中读取数据,填充buffer * 如果reader是分次读入buffer

6、的,那么buffer要进行移位处理 * 移位处理上次读入的但未处理的数据 */int available = fillBuffer(input); if(available <= 0) context.resetContext(); return null; else /分词处理 int analyzedLength = 0; for(int buffIndex = 0 ; buffIndex < available ; buffIndex+) /移动缓冲区指针 context.setCursor(buffIndex); /进行字符规格化(全角转半角,大写转小写处理) segmen

7、tBuffbuffIndex = CharacterHelper.regularize(segmentBuffbuffIndex); /遍历子分词器 for(ISegmenter segmenter : segmenters) segmenter.nextLexeme(segmentBuff , context); analyzedLength+; /* * 满足一下条件时, * 1.available = BUFF_SIZE 表示buffer满载 * 2.buffIndex < available - 1 && buffIndex > available - BU

8、FF_EXHAUST_CRITICAL表示当前指针处于临界区内 * 3.!context.isBufferLocked()表示没有segmenter在占用buffer * 要中断当前循环(buffer要进行移位,并再读取数据的操作) */ if(available = BUFF_SIZE && buffIndex < available - 1 && buffIndex > available - BUFF_EXHAUST_CRITICAL && !context.isBufferLocked() break; for(ISegmen

9、ter segmenter : segmenters)segmenter.reset(); /System.out.println(available + " : " + buffIndex); /记录最近一次分析的字符长度 context.setLastAnalyzed(analyzedLength); /同时累计已分析的字符长度 context.setBuffOffset(context.getBuffOffset() + analyzedLength); /如果使用最大切分,则过滤交叠的短词元 if(context.isMaxWordLength() context.

10、excludeOverlap(); /读取词元池中的词元 return buildLexeme(context.firstLexeme(); else/读取词元池中的已有词元return buildLexeme(context.firstLexeme();Lexeme说明n public int getBeginPosition() 说明:获取诧义单元的起始字符在文本中的位置 返回值:int , 诧义单元相对于文本的绝对起始位置 n public int getEndPosition() 说明:获取诧义单元的结束字符的下一个位置 返回值:int , 诧义单元相对于文本的绝对终止位置的下一个字符

11、位置 n public int getLength() 说明:获取诧义单元包含字符串的长度 返回值:int , 诧义单元长度 = getEndPosition getBeginPosition n public String getLexemeText() 说明:获取诧义单元包含字符串内容 返回值:String, 诧义单元的实际内容,即分词的结果 完整代码示例private static void IKFenCi() FileInputStream fis;try fis = new FileInputStream("F:tmp1234.txt");InputStreamR

12、eader isr=new InputStreamReader(fis, "UTF-8"); BufferedReader br = new BufferedReader(isr); IKSegmentation ik = new IKSegmentation(br, true);Lexeme lex = null;while(lex=ik.next()!=null) System.out.println(lex.getLexemeText()+"| LexemeType ="+lex.getLexemeType() +"| TYPE_CJK_

13、NORMAL= "+lex.TYPE_CJK_NORMAL); catch (FileNotFoundException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (UnsupportedEncodingException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IOException e) / TODO Auto-generated catch blocke.printStackTrace(); Lucene使用

14、IKAnalyzer分词实例化IKAnalyzer分词器代码Analyzer analyzer = new IKAnalyzer(true);代码剖析Analyzer 类是lucene的一个类org.apache.lucene.analysis.Analyzer,IKAnalyzer类继承此类(public final class IKAnalyzer extends Analyzer)并覆盖了tokenStream方法。IKAnalyzer构造方法说明它有一个构造方法接收一个参数isMaxWordLength,这个参数是标识IK是否采用最大词长分词,还是采用最细粒度切分两种分词算法。实际两种

15、算法的实现,最大词长切分是对最细粒度切分的一种后续处理,是对最细粒度切分结果的过滤,选择出最长的分词结果。调用tokenStream()方法返回分词对象StringReader reader=new StringReader(“这是要分的词”); TokenStream ts=analyzer.tokenStream("", reader);追踪源码查看真正的分词对象1、类IKAnalyzer 的方法 tokenStreampublic TokenStream tokenStream(String fieldName, Reader reader) return new I

16、KTokenizer(reader , isMaxWordLength();返回一个IKTokenizer对象2、IKTokenizer类的构造器中实例化了IKSegmentation由此可见IKSegmentation才是真正的分词实现。IKSegmentation详见上面的说明。Lucene如何得到IKSegmentation的分词结果1、这里要说到几个类org.apache.lucene.analysis.TokenStreamorg.apache.lucene.analysis.Tokenizerorg.wltea.analyzer.lucene.IKTokenizer它们之间的关系如

17、下图所示Tokenizer 扩展了 TokenStreamIKTokenizer 扩展了Tokenizer由上图可见,IKAnalyzer类的tokenStream()方法返回的是IKTokenizer。2、 再看看IKTokenizer类作了些什么public final class IKTokenizer extends TokenizerIKTokenizer 的构造器构造器实例化了IKSegmentation用于分词。IKTokenizer 扩展了Tokenizer覆盖了其中的几个方法方法incrementToken()比较重要,这个方法用于测试是否还有下一个分词结果,并生成分词结果。

18、它会调用Lexeme nextLexeme = _IKImplement.next();得到下一个分词结果,如果有,会存入到属性(private TermAttribute termAtt;)中,代码如下:if(nextLexeme != null)/将Lexeme转成Attributes/设置词元文本termAtt.setTermBuffer(nextLexeme.getLexemeText();/设置词元长度termAtt.setTermLength(nextLexeme.getLength();/设置词元位移offsetAtt.setOffset(nextLexeme.getBeginP

19、osition(), nextLexeme.getEndPosition();/记录分词的最后位置finalOffset = nextLexeme.getEndPosition();/返会true告知还有下个词元return true;分词结果存在termAtt,那么通过什么方法得到呢。通过类org.apache.lucene.analysis.Tokenizer的getAttribute方法得到。代码如下: TermAttribute term = ts.getAttribute(TermAttribute.class);通过循环调用incrementToken()方法可不断得到分词结果,代码如下: try while(ts.incrementToken() System.out.print(term.toString()+"|&qu

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论