ansj源码浅析1
来源:互联网 发布:全球数据交换中心 编辑:程序博客网 时间:2024/06/05 15:20
开始之前先盗个图,下图是lucene分词结构的类关系图,可以看出所有的分词流都是基于TokenStream来做的。它下面有两个继承类,一个是
来分词的(Tokenizer),一个是来过滤的(TokenFilter)。我们主要来分析分词的类。
ansj分词器的构造函数如下
public AnsjTokenizer(Analysis ta,String stopwordsDir, boolean pstemming) {this.ta = ta;this.pstemming = pstemming;}
这里面ta是比较重要的。ansj常用的是IndexAnalysis。回到AnsjTokenizer,这个类的核心方法如下
public final boolean incrementToken() throws IOException {clearAttributes();int position = 0;Term term = null;String name = null;int length = 0;boolean flag = true;do {term = ta.next();<span></span>//利用Analysis获取下一个termif (term == null) {break;}name = term.getName();length = name.length();if (pstemming && term.termNatures() == TermNatures.EN) {name = stemmer.stem(name);term.setName(name);}if (filter != null && filter.contains(name)) {continue;} else {position++;flag = false;}} while (flag);if (term != null) {positionAttr.setPositionIncrement(position);termAtt.setEmpty().append(term.getName());offsetAtt.setOffset(term.getOffe(), term.getOffe() + length);return true;} else {return false;}}下面看看Analysis的next函数
public Term next() throws IOException {Term term = null;if (!terms.isEmpty()) {<span></span>//当前terms不为空则直接返回第一个termterm = terms.poll();term.updateOffe(offe);return term;}String temp = br.readLine();<span></span>//当前terms为空,则需要从输入流中读出下一条数据offe = br.getStart();while (StringUtil.isBlank(temp)) {<span></span>//判断当前的读入是否为空,若是则继续读入下一条if (temp == null) {return null;} else {temp = br.readLine();}}// 歧异处理字符串analysisStr(temp);<span></span>//利用temp构造termsif (!terms.isEmpty()) {term = terms.poll();term.updateOffe(offe);return term;}return null;}下面继续看analysisStr(temp)
private void analysisStr(String temp) {Graph gp = new Graph(temp);<span></span>//构造分词图int startOffe = 0;if (this.ambiguityForest != null) {<span></span>//将近义词加入图GetWord gw = new GetWord(this.ambiguityForest, gp.chars);String[] params = null;while ((gw.getFrontWords()) != null) {if (gw.offe > startOffe) {analysis(gp, startOffe, gw.offe);}params = gw.getParams();startOffe = gw.offe;for (int i = 0; i < params.length; i += 2) {gp.addTerm(new Term(params[i], startOffe, new TermNatures(new TermNature(params[i + 1], 1))));startOffe += params[i].length();}}}if (startOffe < gp.chars.length - 1) {analysis(gp, startOffe, gp.chars.length);}List<Term> result = this.getResult(gp);<span></span>//根据图得到分词后的term集合terms.addAll(result);<span></span>//将temp分出的所有term加入}
这里的graph主要是把句子根据词典切分构成一个有向完全图。这里会将用户定义的近义词加入图的对应位置,以方便分词。下面盗一张别人的图来看看:
图1是没加入近义词的图,图2是加入近义词的图。
接下来的List<Term> result = this.getResult(gp);就会通过图选一条最优路径,并把路径上所有的term得到加入terms数组。并返回给上层调用。至此一句话的分词过程就结束了。
这里,这里面图的构造涉及的算法比较复杂,getResult涉及的东西也比较多,接下来一篇我们来进行分析。
有不对的地方请不吝指正,谢谢
0 0
- ansj源码浅析1
- ansj源码浅析2
- ansj源码浅析3
- ansj中文分词分词过程浅析
- android5.1 RelativeLayout源码浅析
- android5.1 FrameLayout源码浅析
- 基于 Ansj 的 elasticsearch 2.3.1 中文分词插件
- SolrCloud-5.5.1配置中文分词ansj-3.4.6
- ansj 分词
- ansj 分词
- Ansj分词
- ansj分词
- nginx源码浅析--源码编译
- Hibernate源码浅析
- TProactor源码浅析一
- LinkedList源码浅析
- Spring FactoryBean源码浅析
- Hessian源码浅析-HessianSkeleton
- UITableVIew优化
- 编码练习——Java-1-基础
- (Java)常用排序
- 微服务实战(二):使用API Gateway
- Bootstrap使用Tab和dropdown实现导航下拉菜单效果
- ansj源码浅析1
- HDU 1242 Rescue
- 【计算机组成原理】存储器
- Android中Dex分包实践
- 贪心_4
- CXF发布中java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log问题
- Linux中TCP黏包问题及其解决方案
- vs2015编译CEF
- web前端多重筛选、json