MMSeg4j是一款中文分词器,详细介绍如下:
1、mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法(http://technology.chtsai.org/mmseg/ )实现的中文分词器,并实现 lucene 的 analyzer 和 solr 的TokenizerFactory 以方便在Lucene和Solr中使用。
2、MMSeg 算法有两种分词方法:Simple和Complex,都是基于正向最大匹配。Complex 加了四个规则过虑。官方说:词语的正确识别率达到了 98.41%。mmseg4j 已经实现了这两种分词算法。
1.5版的分词速度simple算法是 1100kb/s左右、complex算法是 700kb/s左右,(测试机:AMD athlon 64 2800+ 1G内存 xp)。
1.6版在complex基础上实现了最多分词(max-word)。“很好听” -> "很好|好听"; “中华人民共和国” -> "中华|华人|共和|国"; “中国人民银行” -> "中国|人民|银行"。
1.7-beta 版, 目前 complex 1200kb/s左右, simple 1900kb/s左右, 但内存开销了50M左右. 上几个版都是在10M左右
可惜的是,MMSeg4j最新版1.9.1不支持Lucene5.0,于是我就修改了它的源码将它升级咯,使其支持Lucene5.x,至于我是怎样修改,这里就不一一说明的,我把我修改过的MMSeg4j最新源码上传到了我的百度网盘,现分享给你们咯:
mmseg4j-1.9.1源码
mmseg4j-1.9.2源码(支持Lucene5.x)
下面是一个MMSeg4j分词器简单使用示例:
-
packagecom.chenlb.mmseg4j.analysis;
-
-
importjava.io.IOException;
-
-
importorg.apache.lucene.analysis.Analyzer;
-
importorg.apache.lucene.analysis.TokenStream;
-
importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-
importorg.apache.lucene.analysis.tokenattributes.OffsetAttribute;
-
importorg.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-
importorg.apache.lucene.analysis.tokenattributes.TypeAttribute;
-
importorg.junit.Assert;
-
importorg.junit.Before;
-
importorg.junit.Ignore;
-
importorg.junit.Test;
-
-
-
-
-
-
publicclassMMSegAnalyzerTest{
-
-
Stringtxt="";
-
-
@Before
-
publicvoidbefore()throwsException{
-
txt="京华时报2009年1月23日报道昨天,受一股来自中西伯利亚的强冷空气影响,本市出现大风降温天气,白天最高气温只有零下7摄氏度,同时伴有6到7级的偏北风。";
-
txt="2009年ゥスぁま是中ABcc国абвгαβγδ首次,我的ⅠⅡⅢ在chenёlbēū全国ㄦ范围ㄚㄞㄢ内①ē②㈠㈩⒈⒑发行地方政府债券,";
-
txt="大S小3U盘浙BU盘T恤T台A股牛B";
-
}
-
-
@Test
-
-
publicvoidtestSimple()throwsIOException{
-
Analyzeranalyzer=newSimpleAnalyzer();
-
displayTokens(analyzer,txt);
-
}
-
-
@Test
-
@Ignore
-
publicvoidtestComplex()throwsIOException{
-
-
-
-
-
-
-
Analyzeranalyzer=newComplexAnalyzer();
-
displayTokens(analyzer,txt);
-
}
-
-
@Test
-
@Ignore
-
publicvoidtestMaxWord()throwsIOException{
-
-
-
-
-
-
-
Analyzeranalyzer=newMaxWordAnalyzer();
-
displayTokens(analyzer,txt);
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
publicstaticvoiddisplayTokens(Analyzeranalyzer,Stringtext)throwsIOException{
-
TokenStreamtokenStream=analyzer.tokenStream("text",text);
-
displayTokens(tokenStream);
-
}
-
-
publicstaticvoiddisplayTokens(TokenStreamtokenStream)throwsIOException{
-
OffsetAttributeoffsetAttribute=tokenStream.addAttribute(OffsetAttribute.class);
-
PositionIncrementAttributepositionIncrementAttribute=tokenStream.addAttribute(PositionIncrementAttribute.class);
-
CharTermAttributecharTermAttribute=tokenStream.addAttribute(CharTermAttribute.class);
-
TypeAttributetypeAttribute=tokenStream.addAttribute(TypeAttribute.class);
-
-
tokenStream.reset();
-
intposition=0;
-
while(tokenStream.incrementToken()){
-
intincrement=positionIncrementAttribute.getPositionIncrement();
-
if(increment>0){
-
position=position+increment;
-
System.out.print(position+":");
-
}
-
intstartOffset=offsetAttribute.startOffset();
-
intendOffset=offsetAttribute.endOffset();
-
Stringterm=charTermAttribute.toString();
-
System.out.println("["+term+"]"+":("+startOffset+"-->"+endOffset+"):"+typeAttribute.type());
-
}
-
}
-
-
-
-
-
-
-
-
-
publicstaticvoidassertAnalyzerTo(Analyzeranalyzer,Stringtext,String[]expecteds)throwsIOException{
-
TokenStreamtokenStream=analyzer.tokenStream("text",text);
-
CharTermAttributecharTermAttribute=tokenStream.addAttribute(CharTermAttribute.class);
-
for(Stringexpected:expecteds){
-
Assert.assertTrue(tokenStream.incrementToken());
-
Assert.assertEquals(expected,charTermAttribute.toString());
-
}
-
Assert.assertFalse(tokenStream.incrementToken());
-
tokenStream.close();
-
}
-
}
mmseg4j分词器有3个字典文件,如图:
chars.dic是汉字字典文件,里面有12638个汉字
units.dic里是中文单位词语,如小时,分钟,米,厘米等等,具体自己打开看看就明白了
words.dic就是用户自定义字典文件,比如:么么哒,T恤,牛B等这些词,放在这个字典文件里,分词器就能把它当作一个词
我们在使用mmseg4j分词器时,是这样用的:
-
Analyzeranalyzer=newSimpleAnalyzer();
查看SimpleAnalyzer的构造函数,
-
publicSimpleAnalyzer(){
-
super();
-
}
调用的是父类MMSegAnalyzer的无参构造函数,接着查看MMSegAnalyzer类的无参构造函数:
-
publicMMSegAnalyzer(){
-
dic=Dictionary.getInstance();
-
}
你会发现是通过Dictionary.getInstance()单实例模式去加载字典文件的,接着查看getInstance方法,
这里的代码注释写的很清楚,告诉了我们字典文件的加载逻辑。
File path = getDefalutPath();用来获取默认的字典文件路径,
然后根据字典文件路径调用getInstance(path)方法去加载字典文件,接着查看该方法,
先从缓存dics里去字典文件,如果缓存里没有找到,则才会根据字典文件路径去加载,然后把加载到的字典文件放入缓存dics即dics.put(),
接着看看Dictionary字典是如何初始化的,查看Dictionary的构造函数源码:
你会发现内部实际是通过调用init(path);方法进行字典初始化的,继续查阅init方法,
内部又是调用的reload方法加载的字典,继续跟踪至reload方法,
内部通过loadDic去加载words和chars两个字典文件,通过loadUnit方法去加载units字典文件,wordsLastTime是用来存放每个字典文件的最后一次修改时间,引入这个map的目的是为了实现字典文件重新加载,通过字典文件的最后一次修改时间来判定文件是否修改过,如果这个map里不存在某字典文件的最后一次修改时间,则表明该字典文件是新加入的,需要重新加载至内存,这是loadDic方法的源码:
-
privateMap<Character,CharNode>loadDic(FilewordsPath)throwsIOException{
-
InputStreamcharsIn=null;
-
FilecharsFile=newFile(wordsPath,"chars.dic");
-
if(charsFile.exists()){
-
charsIn=newFileInputStream(charsFile);
-
addLastTime(charsFile);
-
}else{
-
charsIn=this.getClass().getResourceAsStream("/data/chars.dic");
-
charsFile=newFile(this.getClass().getResource("/data/chars.dic").getFile());
-
}
-
finalMap<Character,CharNode>dic=newHashMap<Character,CharNode>();
-
intlineNum=0;
-
longs=now();
-
longss=s;
-
lineNum=load(charsIn,newFileLoading(){
-
-
publicvoidrow(Stringline,intn){
-
if(line.length()<1){
-
return;
-
}
-
String[]w=line.split("");
-
CharNodecn=newCharNode();
-
switch(w.length){
-
case2:
-
try{
-
cn.setFreq((int)(Math.log(Integer.parseInt(w[1]))*100));
-
}catch(NumberFormatExceptione){
-
-
}
-
case1:
-
-
dic.put(w[0].charAt(0),cn);
-
}
-
}
-
});
-
log.info("charsloadedtime="+(now()-s)+"ms,line="+lineNum+",onfile="+charsFile);
-
-
-
InputStreamwordsDicIn=this.getClass().getResourceAsStream("/data/words.dic");
-
if(wordsDicIn!=null){
-
FilewordsDic=newFile(this.getClass().getResource("/data/words.dic").getFile());
-
loadWord(wordsDicIn,dic,wordsDic);
-
}
-
-
File[]words=listWordsFiles();
-
if(words!=null){
-
for(FilewordsFile:words){
-
loadWord(newFileInputStream(wordsFile),dic,wordsFile);
-
-
addLastTime(wordsFile);
-
}
-
}
-
-
log.info("loadalldicusetime="+(now()-ss)+"ms");
-
returndic;
-
}
大致逻辑就是先加载chars.dic再加载words.dic,最后加载用户自定义字典文件,注意用户自定义字典文件命名需要以words开头且文件名后缀必须为.dic,查找所有用户自定义字典文件是这句代码:
-
File[]words=listWordsFiles();
注意:dicPath.listFiles表示查找dicPath目录下所有文件,dicPath即我们的words.dic字典文件的所在路径,而重载的accept的意思我想大家都懂的,关键点我用红色方框标注出来了,这句代码意思就是查找words.dic字典文件所在文件夹下的以words开头的dic字典文件,包含子文件夹里的字典文件(即递归查找,你懂的)。看到这里,我想至于如何自定义用户自定义字典文件,大家都不言自明了。为了照顾小白,我还是说清楚点吧,自定义用户字典文件方法步骤如下:
如果你想把屌丝,高富帅 当作一个词,那你首先需要新建一个.dic文件,注意dic文件必须是无BOM的UTF-8编码的文件(切记!!!!!!),且自定义字典文件命名需要符合上面说过的那种固定格式,不知道的请看上面那张图,看仔细点,然后一行一个词,你懂的,然后把你自定义的字典文件复制到classPath下的data文件夹下,如果你是简单的Java project,那么就在src下新建一个data包,然后 把你自定义字典文件copy到data包下,如果你是Maven Project,那就在src/main/sources包下新建一个package
名字叫data,同理把你自定义字典文件复制到data包下即可。这样你的自定义词就能被分词器正确切分啦!
mmseg4j就说这么多了吧,mmseg4j我修改过的最新源码上面有贴出百度网盘下载地址,自己去下载,jar包在target目录下,如图:
从我提供的下载地址下载的最新源码包里有打包好的jar包,如图去找就行了,当然为了方便你们,我待会儿也会在底下的附件里将打包的jar包上传上去。
OK,打完收工!!!!如果你还有什么问题,请QQ上联系我(QQ:7-3-6-0-3-1-3-0-5),或者加我的Java技术群跟我们一起交流学习,我会非常的欢迎的。群号:
分享到:
相关推荐
本篇文章将带你深入学习如何在Solr5中集成并使用MMSeg4J分词器,提升中文处理能力。 首先,我们来了解一下MMSeg4J。这是一个高效、灵活的Java实现的中文分词库,它采用了基于词频的动态最大匹配算法(MaxMatch),...
在com.chenlb.mmseg4j.analysis包里扩展lucene analyzer。 MMSegAnalyzer默认使用max-word方式分词(还有:ComplexAnalyzer, SimplexAnalyzer, MaxWordAnalyzer)。
本话题将深入探讨四种常用的Java分词工具:word分词器、ansj分词器、mmseg4j分词器以及ik-analyzer,以及它们在实际应用中的效果评估。 首先,ansj分词器是由李弄潮开发的一款开源分词工具,它具有强大的词典支持和...
5. **API使用**:在Solr中集成mmseg4j,需要配置Solr的schema.xml和solrconfig.xml文件,设置分析器和过滤器链。同时,开发者可能需要了解mmseg4j提供的API,以便自定义分词规则或进行特殊需求的处理。 6. **性能...
5. **扩展性**:mmseg4j还提供了与jieba分词、SmartChineseAnalyzer等其他分词工具的对比功能,这有助于用户根据实际需求选择最合适的分词方案。此外,mmseg4j还可以与其他自然语言处理组件(如词性标注、命名实体...
然而,在处理中文分词时,Lucene原生的分词器可能无法满足复杂的中文语境需求,这时就需要引入第三方分词工具,如MMSEG4J。本文将深入探讨如何在Lucene项目中整合MMSEG4J,并提供一个实际的项目实例作为参考。 一、...
总的来说,MMseg4j中文分词词库是实现高质量中文分词的关键资源,它结合了搜狗词库的丰富词汇和MMseg4j的高效算法,为Lucene和Solr提供了强大的中文处理能力。正确地配置和使用词库,能够显著提升文本检索的准确性和...
它使得mmseg4j可以集成到Solr中,作为Solr的分词器使用,让Solr具备了处理中文分词的能力。需要注意的是,不同版本的mmseg4j-solr插件需要与对应的Solr版本相匹配,以确保稳定性和兼容性。在Solr5.2.1这样的较新版本...
**mmseg4j 2.3 Jar包:Lucene中文分词器详解** 在中文信息处理领域,分词是至关重要的第一步,它涉及到文本的预处理、搜索索引的构建以及信息检索等多个环节。mmseg4j是一款针对Java平台设计的高效、灵活的中文分词...
《中文分词器mmseg4j与Lucene5.x整合详解及源码解析》 中文分词是自然语言处理中的重要一环,尤其在中文文本分析、信息检索、机器翻译等领域有着广泛的应用。mmseg4j是一款高效、灵活的Java实现的中文分词工具,而...
《mmseg4j在Lucene中文分词中的应用与实现》 在中文信息处理领域,分词是至关重要的一步,它决定了后续文本分析的准确性和效率。mmseg4j是Java环境下广泛使用的中文分词库,尤其在搜索引擎构建和文本挖掘中发挥着...
4. **配置schema.xml**:在Solr的schema.xml文件中,为需要进行分词的字段指定mmseg4j分词器。例如: ``` <fieldType name="text_mmseg" class="solr.TextField" positionIncrementGap="100"> ...
1. **安装与配置**:将mmseg4j-solr-2.2.0的jar包添加到Solr的lib目录下,然后在Solr的schema.xml中配置分词器,指定使用mmseg4j-solr的分词算法。 2. **定制词典**:mmseg4j-solr允许用户自定义词典,以适应特定...
本文将深入探讨基于Lucene的四种中文分词器:Paoding、IK、Imdict和Mmseg4j,它们都是针对Java开发的高效、开源的中文分词工具。 1. Paoding(庖丁)分词器: Paoding是一款高性能的中文分词器,设计目标是提供...
mmseg4j用Chih-Hao Tsai 的MMSeg算法实现的中文分词器,并实现lucene的analyzer和solr的TokenizerFactory以方便在Lucene和Solr中使用。 MMSeg 算法有两种分词方法:Simple和Complex,都是基于正向最大匹配。Complex...
**mmseg4j-1.9.1** 是一个基于Java实现的中文分词库,它的出现是为了满足在Java环境中进行高效、精准的中文文本分词需求。在自然语言处理领域,分词是预处理阶段的关键步骤,它将连续的汉字序列切割成具有语义的词汇...
能兼容solr-4.10.2的分词器,大礼包...包括IK分词器,mmseg4j分词器,庖丁分词器.都是经本人测试可用,其中mmseg4j与庖丁都是下载源码,修改重编译并测试生成的.希望大家喜欢.至于与solr的整合方式,网上很多,这里就不介绍了.
提到的两个分词器,mmseg4j 和 IKAnalyzer,都是为中文处理设计的。 1. **mmseg4j** 是一款由 Java 实现的中文分词库,它采用了 MaxMatch(最大匹配)算法。mmseg4j 提供了多种分词模式,如简短模式、精确模式、全...
**mmseg4j-1.8.5** 是一个针对Lucene搜索引擎的中文分词库,主要用于提升中文信息处理的效率和准确性。该版本与Lucene 3.1版本兼容,意味着它可以在基于Lucene 3.1构建的信息检索系统中无缝集成,提供高效的中文分词...
mmseg4j 2.3 源码 Lucene 中文分词器