java应用集成HanLP进行中文自然语言分词详细完整案例以及demo源码

简介: java应用集成HanLP进行中文自然语言分词详细完整案例以及demo源码

什么是自然语言,什么是自然语言分词及例子

什么是自然语言

狭义地讲,利用计算机进行语言分析的研究是一门语言学与计算机科学的交叉学科,学术界称之为计算语言学,或者是自然语言处理,可以理解为语言学范畴+计算模型[1]。其中,语言学范畴是指由语言学家定义的语言学概念和标准,如词、词性、语法、语义角色、篇章结构等,自然语言处理的任务大多来源于此,但具体实现的计算模型或算法通常由计算机学家研制。

一般来说,通用的自然语言处理总是与语言学领域的范畴直接相关联的,研究包括词干提取、分词、词性标注、命名实体识别、词义消歧、组块识别、句法分析、语义角色标注、篇章分析等。还有一些自然语言处理研究不与语言学范畴直接关联,而是面向文本处理应用的,比如机器翻译、信息抽取、情感分类、信息检索、问答系统等,这些面向应用的自然语言处理技术多少会依赖于前面所介绍的几类自然语言处理基础研究

什么是自然语言分词及例子

举个例子 ,这句话 “你好美丽的祖国大地,

你好美丽的大好河山”,如果分解成人类可以理解的词组,用程序的话该怎么分呢,程序不是人类,没法判断哪几个字组成一个词

所以这时候自然语言分词就该排上作用了,我跑自然分词得程序结果,“你好 美丽 的 祖国 大地 , 你好 美丽 的 大好河山”,

可以看得出基本上是按照人类理解的词语分词的

实现自然语言分词的一些框架

SnowNLP, Thulac, HanLP,LTP,CoreNLP

hanLP介绍以及优点

hanLP 官网域名 hanlp.hankcs.com

面向生产环境的多语种自然语言处理工具包,基于PyTorch和TensorFlow 2.x双引擎,目标是普及落地最前沿的NLP技术。HanLP具备功能完善、精度准确、性能高效、语料时新、架构清晰、可自定义的特点。

借助世界上最大的多语种语料库,HanLP2.1支持包括简繁中英日俄法德在内的130种语言上的10种联合任务以及多种单任务。HanLP预训练了十几种任务上的数十个模型并且正在持续迭代语料库与模型:

java应用程序集成hanLP实现自然语言分词

代码结构

自然语言包下载

自然语言包也就是输入字符串进行匹配我们类似新华字典或者单词词典的分词基础

也就是上图的hanlp-dir

自然语言包下载地址

a74f1accc4ad46bc9be4aa1c1da30a1b.png

最新版语言包下载地址

解压后将语言包放到某个目录下即可

自然语言包配置


resource资源文件夹下新建hanlp.perperties ,如下图:

hanlp.properties 配置文件内容如下

#本配置文件中的路径的根目录,根目录+其他路径=完整路径(支持相对路径,请参考:https://github.com/hankcs/HanLP/pull/254)
#Windows用户请注意,路径分隔符统一使用/
root=E:/code/study/study-foundation/study-foundation-one/hanlp-dir
#好了,以上为唯一需要修改的部分,以下配置项按需反注释编辑。
#核心词典路径
#CoreDictionaryPath=data/dictionary/CoreNatureDictionary.txt
#2元语法词典路径
#BiGramDictionaryPath=data/dictionary/CoreNatureDictionary.ngram.txt
#自定义词典路径,用;隔开多个自定义词典,空格开头表示在同一个目录,使用“文件名 词性”形式则表示这个词典的词性默认是该词性。优先级递减。
#所有词典统一使用UTF-8编码,每一行代表一个单词,格式遵从[单词] [词性A] [A的频次] [词性B] [B的频次] ... 如果不填词性则表示采用词典的默认词性。
CustomDictionaryPath=data/dictionary/custom/CustomDictionary.txt; 现代汉语补充词库.txt; 全国地名大全.txt ns; 人名词典.txt; 机构名词典.txt; 上海地名.txt ns;data/dictionary/person/nrf.txt nrf;
#停用词词典路径
#CoreStopWordDictionaryPath=data/dictionary/stopwords.txt
#同义词词典路径
#CoreSynonymDictionaryDictionaryPath=data/dictionary/synonym/CoreSynonym.txt
#人名词典路径
#PersonDictionaryPath=data/dictionary/person/nr.txt
#人名词典转移矩阵路径
#PersonDictionaryTrPath=data/dictionary/person/nr.tr.txt
#繁简词典根目录
#tcDictionaryRoot=data/dictionary/tc
#HMM分词模型
#HMMSegmentModelPath=data/model/segment/HMMSegmentModel.bin
#分词结果是否展示词性
#ShowTermNature=true
#IO适配器,实现com.hankcs.hanlp.corpus.io.IIOAdapter接口以在不同的平台(Hadoop、Redis等)上运行HanLP
#默认的IO适配器如下,该适配器是基于普通文件系统的。
#IOAdapter=com.hankcs.hanlp.corpus.io.FileIOAdapter
#感知机词法分析器
#PerceptronCWSModelPath=data/model/perceptron/pku1998/cws.bin
#PerceptronPOSModelPath=data/model/perceptron/pku1998/pos.bin
#PerceptronNERModelPath=data/model/perceptron/pku1998/ner.bin
#CRF词法分析器
#CRFCWSModelPath=data/model/crf/pku199801/cws.txt
#CRFPOSModelPath=data/model/crf/pku199801/pos.txt
#CRFNERModelPath=data/model/crf/pku199801/ner.txt
#更多配置项请参考 https://github.com/hankcs/HanLP/blob/master/src/main/java/com/hankcs/hanlp/HanLP.java#L59 自行添加

重点是这个部分

这个是指定语言包根目录的

52a9713cab10457db7494f3db1a57d59.png

java 代码明细

pom 依赖

        <!--hanlp 依赖-->
        <dependency>
            <groupId>com.hankcs</groupId>
            <artifactId>hanlp</artifactId>
            <version>portable-1.8.2</version>
        </dependency>

代码部分,3个类

Word.java

public class Word implements Comparable {
    // 词名
    private String name;
    // 词性
    private String pos;
    // 权重,用于词向量分析
    private Float weight;
    public Word(String name, String pos) {
        this.name = name;
        this.pos = pos;
    }
    @Override
    public int hashCode() {
        return Objects.hashCode(this.name);
    }
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Word other = (Word) obj;
        return Objects.equals(this.name, other.name);
    }
    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        if (name != null) {
            str.append(name);
        }
        if (pos != null) {
            str.append("/").append(pos);
        }
        return str.toString();
    }
    @Override
    public int compareTo(Object o) {
        if (this == o) {
            return 0;
        }
        if (this.name == null) {
            return -1;
        }
        if (o == null) {
            return 1;
        }
        if (!(o instanceof Word)) {
            return 1;
        }
        String t = ((Word) o).getName();
        if (t == null) {
            return 1;
        }
        return this.name.compareTo(t);
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPos() {
        return pos;
    }
    public void setPos(String pos) {
        this.pos = pos;
    }
    public Float getWeight() {
        return weight;
    }
    public void setWeight(Float weight) {
        this.weight = weight;
    }
}

Tokenizer.java

public class Tokenizer {
    /**
     * 分词
     */
    public static List<Word> segment(String sentence) {
        //1、 采用HanLP中文自然语言处理中标准分词进行分词
        List<Term> termList = HanLP.segment(sentence);
        //打印分词结果。
//        System.out.println(termList.toString());
        //2、重新封装到Word对象中(term.word代表分词后的词语,term.nature代表改词的词性)
        return termList.stream().map(
                term -> new Word(term.word, term.nature.toString())).collect(Collectors.toList()
        );
    }
}

TokenizerTester.java

/**
 * @Author alan.wang
 */
public class TokenizerTester {
    public static void main(String[] args){
        String text = "你好美丽的祖国大地,你好美丽的大好河山";
//        String text = "HanLP采用的数据预处理与拆分比例与流行方法未必相同,比如HanLP采用了完整版的MSRA命名实体识别语料,而非大众使用的阉割版;HanLP使用了语法覆盖更广的Stanford Dependencies标准,而非学术界沿用的Zhang and Clark (2008)标准;HanLP提出了均匀分割CTB的方法,而不采用学术界不均匀且遗漏了51个黄金文件的方法。HanLP开源了一整套语料预处理脚本与相应语料库,力图推动中文NLP的透明化。\n" +
//                "\n" +
//                "总之,HanLP只做我们认为正确、先进的事情,而不一定是流行、权威的事情。";
        List<Word> words = Tokenizer.segment(text);
        String wordStr = words.stream().map(word -> word.getName()).collect(Collectors.joining(" "));
        System.out.println(wordStr);
    }
}

验证分词结果

我们先输入字符串:你好美丽的祖国大地,你好美丽的大好河山

输出结果如下:

我们再输入字符串:HanLP采用的数据预处理与拆分比例与流行方法未必相同,比如HanLP采用了完整版的MSRA命名实体识别语料,而非大众使用的阉割版;HanLP使用了语法覆盖更广的Stanford Dependencies标准,而非学术界沿用的Zhang and Clark (2008)标准;HanLP提出了均匀分割CTB的方法,而不采用学术界不均匀且遗漏了51个黄金文件的方法。HanLP开源了一整套语料预处理脚本与相应语料库,力图推动中文NLP的透明化。总之,HanLP只做我们认为正确、先进的事情,而不一定是流行、权威的事情。

输出结果如下:

f6a257e61d8045fdaa2b72db422cda50.png

结语

从输入输出来看,基本上是按照我们自然语言进行分词的,达到了我们人类可以理解的中文分词需求,hanlp 还支持个人主动训练词库,如果自己有特殊分词需要可以按照自己定制化训练方式去训练自己的词库,然后放入词库

相关文章
|
6天前
|
运维 Java
Java版HIS系统 云HIS系统 云HIS源码 结构简洁、代码规范易阅读
云HIS系统分为两个大的系统,一个是基层卫生健康云综合管理系统,另一个是基层卫生健康云业务系统。基层卫生健康云综合管理系统由运营商、开发商和监管机构使用,用来进行运营管理、运维管理和综合监管。基层卫生健康云业务系统由基层医院使用,用来支撑医院各类业务运转。
28 5
|
2天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
19 0
|
1天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
1天前
|
设计模式 JavaScript Java
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
[设计模式Java实现附plantuml源码~行为型] 对象状态及其转换——状态模式
|
1天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
1天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
2天前
|
Java 调度
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
Java面试必考题之线程的生命周期,结合源码,透彻讲解!
24 1
|
2天前
|
Java
Java中的并发编程:理解和应用线程池
【4月更文挑战第23天】在现代的Java应用程序中,性能和资源的有效利用已经成为了一个重要的考量因素。并发编程是提高应用程序性能的关键手段之一,而线程池则是实现高效并发的重要工具。本文将深入探讨Java中的线程池,包括其基本原理、优势、以及如何在实际开发中有效地使用线程池。我们将通过实例和代码片段,帮助读者理解线程池的概念,并学习如何在Java应用中合理地使用线程池。
|
6天前
|
JavaScript Java 测试技术
基于Java的电影评论系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的电影评论系统的设计与实现(源码+lw+部署文档+讲解等)
21 0
|
6天前
|
JavaScript Java 测试技术
基于Java的在线日语培训平台的设计与实现(源码+lw+部署文档+讲解等)
基于Java的在线日语培训平台的设计与实现(源码+lw+部署文档+讲解等)
23 0