ANSJ是由孙健(ansjsun)开源的一个中文分词器,为ICTLAS的Java版本,也采用了Bigram + HMM分词模型:在Bigram分词的基础上,识别未登录词,以提高分词准确度。
虽然基本分词原理与ICTLAS的一样,但是Ansj做了一些工程上的优化,比如:用DAT高效地实现检索词典、邻接表实现分词DAG、支持自定义词典与自定义消歧义规则等。
1.项目地址
项目的github地址:https://github.com/NLPchina/ansj_seg
项目的文档地址:http://nlpchina.github.io/ansj_seg/
2.导入
2.1依赖
Ansj最新依赖包是5.1.6版本的,2018年更新的,最近已经不更新了:
2.2 配置文件
字段名 | 默认值 | 说明 |
---|---|---|
isNameRecognition | true | 是否开启人名识别 |
isNumRecognition | true | 是否开启数字识别 |
isQuantifierRecognition | true | 是否数字和量词合并 |
isRealName | false | 是否取得真实的词,默认情况会取得标注化后的 |
isSkipUserDefine | false | 是否用户辞典不加载相同的词 |
dic | "library/default.dic" | 自定义词典路径 |
dic_[key] | "你的词典路径" | 针对不同语料调用不同的自定义词典 |
ambiguity | "library/ambiguity.dic" | 歧义词典路径 |
ambiguity_[key] | "library/ambiguity.dic" | 歧义词典路径 |
crf | null | crf词典路径,不设置为默认 |
crf_[key] | "你的模型路径" | 针对不同语料调用不同的分词模型 |
synonyms | "默认的同义词典" | 针对不同语料调用不同的分词模型 |
synonyms_[key] | "你的同义词典路径" | 针对不同语料调用不同的分词模型 |
默认的配置文件格式:
3.分词实现
3.1 ToAnalysis 精准分词
3.2 DicAnalysis 用户自定义词典优先策略的分词
3.3 NlpAnalysis 带有新词发现功能的分词
3.4 IndexAnalysis 面向索引的分词
3.5 BaseAnalysis 最小颗粒度的分词
3.6 功能统计
名称 | 用户自定义词典 | 数字识别 | 人名识别 | 机构名识别 | 新词发现 |
---|---|---|---|---|---|
BaseAnalysis | X | X | X | X | X |
ToAnalysis | √ | √ | √ | X | X |
DicAnalysis | √ | √ | √ | X | X |
IndexAnalysis | √ | √ | √ | X | X |
NlpAnalysis | √ | √ | √ | √ | √ |
4、使用实例
4.1 分词demo
package com.*;
import org.ansj.splitWord.analysis.*;
import org.junit.Test;
import java.util.*;
/**
* @author
* @date 2023-07-26 15:29
*/
public class SegTest {
@Test
public void test(){
String str = "ANSJ是由孙健(ansjsun)开源的一个中文分词器,为ICTLAS的Java版本,也采用了Bigram + HMM分词模型:在Bigram分词的基础上,识别未登录词,以提高分词准确度。" ;
System.out.println(BaseAnalysis.parse(str));
System.out.println(ToAnalysis.parse(str));
System.out.println(DicAnalysis.parse(str));
System.out.println(IndexAnalysis.parse(str));
System.out.println(NlpAnalysis.parse(str));
}
}
分词结果:
BaseAnalysis
ToAnalysis:
DicAnalysis:
IndexAnalysis:
NlpAnalysis :
4.2 使用demo
以ToAnalysis为例,其它方法大同小异:
public static void main(String[] args) {
String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我!" ;
Result result = ToAnalysis.parse(str); //分词结果的一个封装,主要是一个List<Term>的terms
System.out.println(result.getTerms());
List<Term> terms = result.getTerms(); //拿到terms
System.out.println(terms.size());
for(int i=0; i<terms.size(); i++) {
String word = terms.get(i).getName(); //拿到词
String natureStr = terms.get(i).getNatureStr(); //拿到词性
System.out.println(word + ":" + natureStr);
}
}
基本使用方法分为几下几步:
1、使用ToAnalysis.parse(str)将字符串进行分词,会返回一个Result,分词的结果就在它里面。
2、然后继续result.getTerms()获得分词结果的内容,因为是返回的多个分词,所以最终获得的是一个List。
3、然后遍历它,term.getName()获得的是词,term.getNatureStr()拿到的是这个词的词性。
4.3 个性化定制分词词典
4.3.1 自定义常用词典
- 创建一个名为userLibrary.dic的文件,内容如下:
第一个是词语,第二个是词性,第三个是权重。词性这里大家不用关注,编号以此类推即可,不要重复,各个以缩进(\t)分隔。
- 加载自定义词典
4.3.2 自定义停用词典
- 创建一个名为stopLibrary.dic的文件,内容如下:
直接写停用词,每一行写一个。
- 加载自定义词库
4.3.3 自主添加个别词
4.3.4 歧义纠正词典
歧义纠正是Ansj分词的最后最后的大招了,杀伤力巨大,谨慎使用,极可能造成其他的错误。
很多时候,分词发生歧异不是很好调整,用户需要更强的规则来约束所以ansj中增加了歧异消除的一个强规则方式。
- 创建一个名为library/ambiguity.dic 的文件,内容格式如下:
第一列是识别串,第二列是分词结果,奇数行是词,偶数行是词性。这里例子告诉计算机:如果你发现 "李民工作"---> "李/民工/作" 纠正为 --->"李民/工作/" 这种类型
- 在配置文件中设置ambiguity.dic 的路径
- 也可以用 MyStaticValue.ambiguityLibrary = "library/ambiguity.dic" 来设定;
- 也可动态添加歧义纠正词典:
System.out.println(ToAnalysis.parse("据说川府办发的发文很厉害"));
//歧义纠正
Value value = new Value("川府办", "川府办", "n");
Library.insertWord(AmbiguityLibrary.get(), value);
System.out.println(ToAnalysis.parse("据说川府办发的发文很厉害"));;
运行结果: