文档章节

Lucene与中文分词

潘少online
 潘少online
发布于 2015/04/29 09:50
字数 1409
阅读 140
收藏 2

Lucene中的Analyzer

处理英文的流程

  • WhitespaceTokenizer

  •      空格分隔

  • WordDelimiterFilter

  •      对单词进一步分隔

  •      同时合并单词(catenateWords参数)

  • LowercaseFilter

  •      小写化

实现代码如下:

public class MyAnalyzer extends Analyzer {
  @Override
  public TokenStream tokenStream(String fieldName, Reader reader) {
  //以空格方式切分Token
  TokenStream stream = new WhitespaceTokenizer(reader);
  //删除过短或过长的词,例如 in、of、it
  stream = new LengthFilter(stream, 3, Integer.MAX_VALUE);
  //给每个词标注词性
  stream = new PartOfSpeechAttributeImpl.PartOfSpeechTaggingFilter(stream);
  return stream;
  }
}

//Attribute 接口是基本属性接口,定义一个词性的接口
public interface PartOfSpeechAttribute extends Attribute {
/*
 * 用枚举类型定义词的词性
 */
public static enum PartOfSpeech {
  Noun, Verb, Adjective, Adverb, Pronoun, Preposition, Conjunction, Article, Unknown
}
§ // setter
public void setPartOfSpeech(PartOfSpeech pos);
§ // getter
public PartOfSpeech getPartOfSpeech();
}

PartOfSpeechTaggingFilter:

public static class PartOfSpeechTaggingFilter extends TokenFilter {
  PartOfSpeechAttribute posAtt;
  TermAttribute termAtt;
  public PartOfSpeechTaggingFilter(TokenStream input) {
  super(input);
  posAtt = addAttribute(PartOfSpeechAttribute.class);
  termAtt = addAttribute(TermAttribute.class);
  }
  public boolean incrementToken() throws IOException {
  if (!input.incrementToken()) {
  return false;
  }
  posAtt.setPartOfSpeech(determinePOS(termAtt.termBuffer(), 0,
  termAtt.termLength()));
  return true;
  }
  //判断term的词性
  protected PartOfSpeech determinePOS(char[] term, int offset, int length) {
  // naive implementation that tags every uppercased word as noun
  if (length > 0 && Character.isUpperCase(term[0])) {
  return PartOfSpeech.Noun;
  }
  return PartOfSpeech.Unknown;
  }
}

PerFieldAnalyzerWrapper:

    不同的索引列切分方式可能不一样。为了对不同的索引列使用不同的分析器,可以使用PerFieldAnalyzerWrapper。在PerFieldAnalyzerWrapper中,可以指定一个缺省的分析器,也可以通过addAnalyzer方法对不同的列使用不同的分析器。例如:

PerFieldAnalyzerWrapper aWrapper = new PerFieldAnalyzerWrapper(new CnAnalyzer());

//地址列使用AddAnalyzer 

aWrapper.addAnalyzer("address", new AddAnalyzer());

//公司名称列使用CompanyAnalyzer 

aWrapper.addAnalyzer("companyName", new CompanyAnalyzer());

为什么要分词:

l中文分词是理解中文的第一步

中文分词就是对中文断句,这样能消除文字的部分歧义

有个笑话:请用“天真”造句。

天真冷啊。今天天真蓝。


l分词的任务

分词:把输入的标题或者文本内容等分成词。

词性标注(POS):给分出来的词标注上名词或动词等词性。

语义标注:把每个词标注上语义编码。

分词:

l索引内容分词

切分标题列:中国一重|n  利润|n  骤减|v  有|v  玄机|n 

切分内容列:嫩江|ns  西岸|s  的|uj  富拉尔基|ns  ,|w  距离|n  齐齐哈尔市|ns  中心|n  城区|n  37|m  公里|q  。|w 

切分公司名:艾博/关键词 (国际)/行政区划 塑胶/行业词 进出口有限公司/功能词

切分地址:广西/省 南宁市/市 青秀区/区 安湖路/街道 1号/号 新锐大厦/地标建筑

切分电话号码:0371/区位号  63949884/尾号


词性标注:

词性标注可以部分消除词的歧义,例如“行”作为量词和作为形容词表示的意思不一样。

标注的类型有

l小标注集(40类左右)

l大标注集(最多可到100类左右)

小标注集代词都归为一类,大标注集可以把代词进一步分成三类:

l人称代词:你 我 他 它 你们 我们 他们

l疑问代词:哪里  什么  怎么 

l指示代词:这里 那里  这些  那些

语义:


l一词多义

  • 苹果:电脑、水果

  • 黑莓:手机、水果


l一义多词

  • 大豆、黄豆

  • 西红柿、番茄

  • 宾馆、酒店


语义标注:

l同义词词林语义编码

用树型结构表示了词的同义和上下位关系

把词汇分成大、中、小三类,大类有12个,中类有97个,小类有1,400个。例如A大类代表人、B大类代表物

Bp31B 表

Bp31B01= 表 手表

Bp31B02= 马表 跑表 停表

Bp31B03= 怀表 挂表

Bp31B04= 防水表 游泳表

Bp31B05= 表针 指针

Bp31B06= 表盘 表面

l语义标注示例:

  • 例子:我们伟大祖国在新的一年

  • 标注结果:我们/r/Aa02B01 伟大/a/Ed20A01 祖国/n/Di02A18 在/p/Jd01A01 新/a/Eb28A01 的/u/Kd01A01 一/m/Dn04A02 年/q/Ca18A01 ,/w/Dk04D02

中文分词的基本原理:

l机械匹配的方法

  • 正向最大长度匹配(Forward Maximum Match)的方法

  • 逆向最大长度匹配(Reverse Maximum Matching)的方法


l 统计的方法

  • 语言模型的分词方法

  • 条件随机场分词方法、最大熵隐马尔科夫模型等

正向最大长度匹配:

l词典

大  大学   大学生   活动   生活   中   中心  心 


l输入:“大学生活动中心”,首先匹配出“大学生”,然后匹配出“活动”,最后匹配出“中心”。切分过程如下:


正向最大长度匹配实现:

public void wordSegment(String content)//传入一个字符串作为要处理的对象
{
  int senLen = content.length();//首先计算出传入的这句话的字符长度
  int i=0;//控制匹配的起始位置
  
  while(i < senLen)//如果i小于此句话的长度就继续匹配
  {
  String word = dic.matchLong(content, i);//正向最大长度匹配
  if(word!=null)//已经匹配上
  {
  //下次匹配点在这个词之后
  i += word.length();
  //如果这个词是词库中的那么就打印出来
  System.out.print(word + " ");
  }
  else//如果在词典中没有找到匹配上的词,就按单字切分
  {
  word = content.substring(i, i+1);
  //打印一个字
  System.out.print(word + " ");
  ++i;//下次匹配点在这个字符之后
  }
  }
}



© 著作权归作者所有

共有 人打赏支持
潘少online
粉丝 12
博文 58
码字总数 107019
作品 2
深圳
程序员
私信 提问
搜索引擎--FlashDB

系统特色 基于Lucene核心,支持全文检索,查询统计快速高效。 支持SQL语法、数据类型、JDBC驱动标准,使用简单方便。 支持单机、主从复制、数据分片等多种部署模式。 支持丰富的检索函数 集成...

张三34324
2014/06/05
890
0
lucene solr在tomcat中的配置

1.建立d:lucenesolrhome路径。然后将examplesolr目录中的文件拷贝过来 2.建立d:lucenesolrserver将examplewebapp中的solr.war拷贝过来,并解压。 3.修改d:lucenesolrhomeconfsorlconifg.xml中...

dapengking
2012/07/10
0
0
IKAnalyzer的网友评论

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出 了3个大版本。最初,它是以开源项目Luence为应用主体的,结合词典分词...

红薯
2009/12/11
595
1
Apache Lucene 几种分词系统

1、 StopAnalyzer StopAnalyzer能过滤词汇中的特定字符串和词汇,并且完成大写转小写的功能。 2、 StandardAnalyzer StandardAnalyzer根据空格和符号来完成分词,还可以完成数字、字母、E-m...

6pker
2015/02/26
0
0
[转贴] Lucene 3.0 的几种分词系统

1、 StopAnalyzer StopAnalyzer能过滤词汇中的特定字符串和词汇,并且完成大写转小写的功能。 2、 StandardAnalyzer StandardAnalyzer根据空格和符号来完成分词,还可以完成数字、字母、E-m...

红薯
2010/10/20
6.5K
3

没有更多内容

加载失败,请刷新页面

加载更多

第11章 多线程

程序、进程、线程 程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。 **进程(process)**是程序的一次执行过程或是正在运行的一个程序。动...

流小文
20分钟前
2
0
SpringBoot引入第三方jar包或本地jar包的处理方式

在开发过程中有时会用到maven仓库里没有的jar包或者本地的jar包,这时没办法通过pom直接引入,那么该怎么解决呢 一般有两种方法 - 第一种是将本地jar包安装在本地maven库 - 第二种是将本地j...

独钓渔
今天
2
0
五、MyBatis缓存

一、MyBatis缓存介绍 缓存的使用可以明显的加快访问数据速度,提升程序处理性能,生活和工作中,使用缓存的地方很多。在开发过程中,从前端-->后端-->数据库等都涉及到缓存。MyBatis作为数据...

yangjianzhou
今天
2
0
最近研究如何加速UI界面开发,有点感觉了

最近在开发JFinal学院的JBolt开发平台,后端没啥说的,做各种极简使用的封装,开发者上手直接使用。 JBolt开发平台包含常用的用户、角色、权限、字典、全局配置、缓存、增删改查完整模块、电...

山东-小木
今天
3
0
《月亮与六便士》的读后感作文3000字

《月亮与六便士》的读后感作文3000字: 看完英国作家威廉.萨默塞特.毛姆所著《月亮与六便士》(李继宏译),第一疑问就是全书即没提到“月亮”,也没提到“六便士”。那这书名又与内容有什么...

原创小博客
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部