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;//下次匹配点在这个字符之后 } } }