ansj中文分词器详解

ansj中文分词器详解

  最近在做一个人工智能的项目,其中用到了分词功能。从网上找了一些java用于分词的工具,最终选择了ansj中文分词器。个人认为效果和功能是比较优秀的。本文将对ansj的所有功能进行详解并提供收集到的文本,下面开始正文:

一、基本使用

  引入如下maven依赖配置:

	<!-- ansj分词插件依赖 -->
	<dependency>
		<groupId>org.ansj</groupId>
		<artifactId>ansj_seg</artifactId>
		<version>5.1.6</version>
	</dependency>

  看下面的测试类:

	public static void main(String[] args) {
        String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
        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);
        }
    }

  这个测试类说明了ansj的基本使用方法分为几下几步:

  1、使用ToAnalysis.parse(str)将字符串进行分词,会返回一个Result,分词的结果就在它里面。

  2、然后继续result.getTerms()获得分词结果的内容,因为是返回的多个分词,所以最终获得的是一个List。

  3、然后遍历它,term.getName()获得的是词,term.getNatureStr()拿到的是这个词的词性。

测试最终结果如下:

欢迎:v
使用:v
ansj:en
_:null
seg:en
,:w
(:w
ansj:en
中文:nz
分词:v
):w
在:p
这里:r
如果:c
你:r
遇到:v
什么:r
问题:n
都:d
可以:v
联系:v
我:r
.:w
我:r
一定:d
尽:v
我:r
所能:v
.:w
帮助:v
大家:r
.:w
ansj:en
_:null
seg:en
更快:d
,:w
更:d
准:a
,:w
更:d
自由:a
!:w  

二、自定义词库

  从上面分词的结果可以看出有些词语我们本来是想让它放在一起的,但是分开了。因为ansj本身有一个词库,它是根据内部词库来进行分词的。但是内部词库也并不是那么完善,所以我们需要自己定义一个词库,在分词的时候把我们自己定义的词库加载进去,这样就可以达到我们预期的效果。

  1、创建一个dic文件
  在你电脑的任意位置创建一个名为userLibrary.dic的文件,内容如下:

尽我所能	v	1
更准	v	2
更自由	v	3

第一个是词语,第二个是词性,第三个是编号。词性这里大家不用关注,编号以此类推即可,不要重复。各个以缩进分隔。

扫描二维码关注公众号,回复: 10881847 查看本文章

  2、加载自定义词库
  你虽然已经定义了自定义词库,但是你还没有把它加入到你的ansj中去。看如下测试类:

public static void main(String[] args) {
	// 关闭名字识别
	MyStaticValue.isNameRecognition = false;
	// 配置自定义词典的位置。注意是绝对路径
	MyStaticValue.ENV.put(DicLibrary.DEFAULT,"D:\\ideaproject\\ocr\\src\\main\\resources\\userLibrary.dic");

    String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
    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);
    }
}

  我在前几行加入了加载自定义词库的代码,你只需要修改你自定义词库的路径即可,下面看测试结果:可以看到之前没有分出来的 ‘尽我所能’ 、‘更准’、‘更自由’ 由于我在自定义词库加入了它们所以成功分在一起了。

欢迎:v
使用:v
ansj:en
_:null
seg:en
,:w
(:w
ansj:en
中文:nz
分词:v
):w
在:p
这里:r
如果:c
你:r
遇到:v
什么:r
问题:n
都:d
可以:v
联系:v
我:r
.:w
我:r
一定:d
尽我所能:v
.:w
帮助:v
大家:r
.:w
ansj:en
_:null
seg:en
更快:d
,:w
更准:v
,:w
更自由:v
!:w

三、自定义停用词库

  大家要知道停用词是什么,就是当我们使用ansj将一句话分词的时候,它分出来的词语会有一些没有任何意义的词,最近我在做的是语义分析,这些词是会影响语义分析结果的,所以必须将其去掉。比如 ‘啊’、‘嗯’、‘哦’等词。创建停用词库步骤如下:

  1、创建一个dic文件
  在你电脑的任意位置创建一个名为stopLibrary.dic的文件,内容如下:

啊
阿
哎
唉
俺
按
吧

直接写停用词,每一行写一个。

  2、加载自定义词库
  直接看如下代码,手写酸了。。。。。

public static void main(String[] args) {
	// 关闭名字识别
	MyStaticValue.isNameRecognition = false;
	// 配置自定义词典的位置。注意是绝对路径
	MyStaticValue.ENV.put(DicLibrary.DEFAULT,"D:\\ideaproject\\ocr\\src\\main\\resources\\userLibrary.dic");

	//去停用词
	List<String> stopWords = getStopWords("D:\\ideaproject\\ocr\\src\\main\\resources\\library\\stopLibrary.dic");
	StopRecognition filter = new StopRecognition();
	filter.insertStopWords(stopWords);

    String str = "欢迎使用ansj_seg,(ansj中文分词)在这里如果你遇到什么问题都可以联系我.我一定尽我所能.帮助大家.ansj_seg更快,更准,更自由!" ;
    Result result = ToAnalysis.parse(str).recognition(filter); //分词结果的一个封装,主要是一个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);
    }
}

  注意看去停用词那块,就是将停用词库的内容获取放到List中然后加入到ansj的停用词库中。还有在分词时ToAnalysis.parse(str).recognition(filter)加入了.recognition(filter)这个,它就是将你停用词库加入到ansj中去。这里我用到了一个getStopWords方法,参数就是你自定义停用词库的路径,内容如下:

private static List<String> getStopWords(String url){
	// 使用一个字符串集合来存储文本中的路径 ,也可用String []数组
    List<String> list = new ArrayList<String>();
    try {
    	FileInputStream fis = new FileInputStream(url);
    	// 防止路径乱码   如果utf-8 乱码  改GBK     eclipse里创建的txt  用UTF-8,在电脑上自己创建的txt  用GBK
    	InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
    	BufferedReader br = new BufferedReader(isr);
    	String line = "";
    	while ((line = br.readLine()) != null) {
    		// 如果 t x t文件里的路径 不包含---字符串       这里是对里面的内容进行一个筛选
    		if (line.lastIndexOf("---") < 0) {
    			list.add(line);
    		}
    	}
    	br.close();
    	isr.close();
    	fis.close();
		
	} catch (Exception e) {
		e.printStackTrace();
	}
    return list;
}

  3、测试结果
  不测试了,手真的酸了。但是这里要说一个小细节,就是去停用词是在分词后,而不是分词前。

四、ansj的五种分词模式

  直接看这篇吧,写的挺好。https://blog.csdn.net/lb521200200/article/details/53696387
  如果对这几种模式还是不太理解,或者觉得这篇博文讲的太官方了,欢迎给我留言
  另外给大家提供搜狗词库去重两百万词库。
    链接:https://pan.baidu.com/s/1CJVOTVwDkbkFkIueBKjgtw
    提取码:3fnn

发布了25 篇原创文章 · 获赞 58 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/student_zz/article/details/100578236
今日推荐