前言:
Java有11大开源中文分词器,分别是word分词器,Ansj分词器,Stanford分词器,FudanNLP分词器,Jieba分词器,Jcseg分词器,MMSeg4j分词器,IKAnalyzer分词器,Paoding分词器,smartcn分词器,HanLP分词器。

不同的分词器有不同的用法,定义的接口也不一样,至于效果哪个好,那要结合自己的应用场景自己来判断。这里我就主要介绍Ansj中文分词器,它是一个开源的 Java 中文分词工具,基于中科院的 ictclas 中文分词算法,比其他常用的开源分词工具(如MMseg4j)的分词准确率更高,目前实现了.中文分词. 中文姓名识别 . 用户自定义词典,关键字提取,自动摘要,关键字标记等功能,适用于对分词效果要求高的各种项目。

  1. ANSJ项目git地址:https://github.com/NLPchina/ansj_seg
  2. ANSJ文档地址:点击此处跳转文档地址链接
  3. Maven
<!-- 开源中文分词器Ansj -->
<dependency>
	<groupId>org.ansj</groupId>
	<artifactId>ansj_seg</artifactId>
	<version>5.1.6</version>
</dependency>

一、基本分词 BaseAnalysis

基本分词是什么?
1、基本就是保证了最基本的分词.词语颗粒度最非常小的…所涉及到的词大约是10万左右.
2、基本分词速度非常快.在macAir上.能到每秒300w字每秒.同时准确率也很高.但是对于新词他的功能十分有限

/**
     * 基本分词
     */
    public static void baseAnalysis () {
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        Result analysisedResult = BaseAnalysis.parse(text);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("基本分词输出词性: " + analysisedResult + "     耗时(" + time + "ms)");
        System.out.println("-----------------------------------------------------------");
        String analysisedText = BaseAnalysis.parse(text).toStringWithOutNature();
        long endTime2 = System.currentTimeMillis();
        long time2 = endTime2 - startTime;
        System.out.println("基本分词仅输出词: " + analysisedText + "     耗时(" + time2 + "ms)");
    }
        public static void main(String[] args) {
        	baseAnalysis();
    }

二、精准分词 ToAnalysis

精准分词是什么?
1、精准分词是Ansj分词的店长推荐款
2、它在易用性,稳定性.准确性.以及分词效率上.都取得了一个不错的平衡.
3、如果你初次赏识Ansj如果你想开箱即用.那么就用这个分词方式是不会错的.

public static void toAnalysis () {
      System.out.println("-----------------------------------------------------------");
      long startTime = System.currentTimeMillis();
      String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
      String analysisedText = ToAnalysis.parse(text).toStringWithOutNature();
      long endTime = System.currentTimeMillis();
      long time = endTime - startTime;
      System.out.println("精准分词: " + analysisedText + "   (耗时" + time + "ms)");
  }
  public static void main(String[] args) {
        	toAnalysis();
    }

三、nlp分词 NlpAnalysis

nlp分词是什么?
1、nlp分词是总能给你惊喜的一种分词方式.
2、它可以识别出未登录词.但是它也有它的缺点.速度比较慢.稳定性差.ps:我这里说的慢仅仅是和自己的其他方式比较.应该是40w字每秒的速度吧.
3、个人觉得nlp的适用方式.1.语法实体名抽取.未登录词整理.只要是对文本进行发现分析等工作

public static void nlpAnalysis () {
        System.out.println("-----------------------------------------------------------");
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        String analysisedText = NlpAnalysis.parse(text).toStringWithOutNature();
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("nlp分词: " + analysisedText + "   (耗时" + time + "ms)");
    }
    public static void main(String[] args) {
        	nlpAnalysis ();
    }

四、面向索引的分词 IndexAnalysis

面向索引的分词是什么?
1、面向索引的分词。故名思议就是适合在lucene等文本检索中用到的分词。 主要考虑以下两点

  • 召回率
    召回率是对分词结果尽可能的涵盖。比如对“上海虹桥机场南路” 召回结果是[上海/ns, 上海虹桥机场/nt, 虹桥/ns, 虹桥机场/nz, 机场/n, 南路/nr]
  • 准确率
    其实这和召回本身是具有一定矛盾性的Ansj的强大之处是很巧妙的避开了这两个的冲突 。比如我们常见的歧义句“旅游和服务”->对于一般保证召回 。大家会给出的结果是“旅游 和服 服务” 对于ansj不存在跨term的分词。意思就是。召回的词只是针对精准分词之后的结果的一个细分。比较好的解决了这个问题
public static void indexAnalysis () {
        System.out.println("-----------------------------------------------------------");
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        String analysisedText = IndexAnalysis.parse(text).toStringWithOutNature();
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("索引分词: " + analysisedText.toString() + "   (耗时" + time + "ms)");
    }
    public static void main(String[] args) {
        	indexAnalysis ();
    }

五、全部代码

package com.yawei.web.controller;

import org.ansj.domain.Result;
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.BaseAnalysis;
import org.ansj.splitWord.analysis.IndexAnalysis;
import org.ansj.splitWord.analysis.NlpAnalysis;
import org.ansj.splitWord.analysis.ToAnalysis;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ansj 分词测试
 */
public class AnsjTest {

    /**
     * 基本分词
     */
    public static void baseAnalysis () {
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        Result analysisedResult = BaseAnalysis.parse(text);
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("基本分词输出词性: " + analysisedResult + "     耗时(" + time + "ms)");
        System.out.println("-----------------------------------------------------------");
        String analysisedText = BaseAnalysis.parse(text).toStringWithOutNature();
        long endTime2 = System.currentTimeMillis();
        long time2 = endTime2 - startTime;
        System.out.println("基本分词仅输出词: " + analysisedText + "     耗时(" + time2 + "ms)");
    }

    public static void toAnalysis () {
        System.out.println("-----------------------------------------------------------");
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        String analysisedText = ToAnalysis.parse(text).toStringWithOutNature();
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("精准分词: " + analysisedText + "   (耗时" + time + "ms)");
    }

    public static void nlpAnalysis () {
        System.out.println("-----------------------------------------------------------");
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        String analysisedText = NlpAnalysis.parse(text).toStringWithOutNature();
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("nlp分词: " + analysisedText + "   (耗时" + time + "ms)");
    }

    public static void indexAnalysis () {
        System.out.println("-----------------------------------------------------------");
        long startTime = System.currentTimeMillis();
        String text = "山东省青岛市崂山区辽阳东路181号崂山市场监督管理局";
        String analysisedText = IndexAnalysis.parse(text).toStringWithOutNature();
        long endTime = System.currentTimeMillis();
        long time = endTime - startTime;
        System.out.println("索引分词: " + analysisedText.toString() + "   (耗时" + time + "ms)");
    }

    public static void main(String[] args) {
        baseAnalysis();
        toAnalysis();
        nlpAnalysis();
        indexAnalysis();
    }
}

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐