Java不用模型,直接实现中文分词(HanLP)

一、背景

因为项目需要进行中文分词后,按关键词进行检索,为此小功能引入一个分词小模型占用GPU算力,不值得。

所以经过研究和测试,决定使用Han Language Processing (HanLP)进行免模型中文分词。它的分词效果和速度经过多方测试,表现都不错。

二、依赖引用

HanLP在2.0版本以上,只能使用在线版。我们内网中,必须离线使用,因此使用1.x版本。

首先引入pom依赖:

java 复制代码
		<dependency>
			<groupId>com.hankcs</groupId>
			<artifactId>hanlp</artifactId>
			<version>portable-1.8.2</version>
		</dependency>

注:如果想使用持久化的自定义词库,或者针对分词进行一些定制化操作,还需要下载数据包:

http://nlp.hankcs.com/download.php?file=data

关于自定义配置和数据包的使用,请参考官网:

https://github.com/hankcs/HanLP/tree/1.x

如果没有特殊自定义需求,就不用下载和处理这个数据包。

三、分词功能使用

  • 标准分词
    开箱即用"的静态分词器。
java 复制代码
String inputStr = "windows系统的时钟服务怎么设置?";
List<Term> termList = StandardTokenizer.segment(inputStr);
for (Term t : StandardTokenizer.segment(inputStr)) {
    System.out.println(t.word);
}
System.out.println(termList);
  • NLP分词
    基于NLPTokenizer(9970万字的大型综合语料库),执行词性标注和命名实体识别。
java 复制代码
System.out.println(NLPTokenizer.segment("我新造一个词叫攻城狮,你能识别并标注正确词性吗?"));
  • 极速分词
    基于AhoCorasickDoubleArrayTrie实现的词典分词,适用于"高吞吐量""精度一般"的场合。
java 复制代码
for (Term t : SpeedTokenizer.segment(inputStr)) {
            System.out.println(t.word);
        }

四、关键词提取功能使用

java 复制代码
public static void test() {
        String content = "程序员(英文Programmer)是从事程序开发、维护的专业人员。一般将程序员分为程序设计人员和程序编码人员,但两者的界限并不非常清楚,特别是在中国。软件从业人员分为初级程序员、高级程序员、系统分析员和项目经理四大类。";
        //List<String> keywordList = HanLP.extractKeyword(content, 10);
        List<String> keywordList = TextRankKeyword.getKeywordList(content, 10);
        System.out.println(keywordList);
    }

五、短语提取功能使用

java 复制代码
public static void test2() {
        String text = "算法工程师\n" +
                "算法(Algorithm)是一系列解决问题的清晰指令,也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。如果一个算法有缺陷,或不适合于某个问题,执行这个算法将不会解决这个问题。不同的算法可能用不同的时间、空间或效率来完成同样的任务。一个算法的优劣可以用空间复杂度与时间复杂度来衡量。算法工程师就是利用算法处理事物的人。\n" +
                "\n" +
                "1职位简介\n" +
                "算法工程师是一个非常高端的职位;\n" +
                "专业要求:计算机、电子、通信、数学等相关专业;\n" +
                "学历要求:本科及其以上的学历,大多数是硕士学历及其以上;\n" +
                "语言要求:英语要求是熟练,基本上能阅读国外专业书刊;\n" +
                "必须掌握计算机相关知识,熟练使用仿真工具MATLAB等,必须会一门编程语言。\n" +
                "\n" +
                "2研究方向\n" +
                "视频算法工程师、图像处理算法工程师、音频算法工程师 通信基带算法工程师\n" +
                "\n" +
                "3目前国内外状况\n" +
                "目前国内从事算法研究的工程师不少,但是高级算法工程师却很少,是一个非常紧缺的专业工程师。算法工程师根据研究领域来分主要有音频/视频算法处理、图像技术方面的二维信息算法处理和通信物理层、雷达信号处理、生物医学信号处理等领域的一维信息算法处理。\n" +
                "在计算机音视频和图形图像技术等二维信息算法处理方面目前比较先进的视频处理算法:机器视觉成为此类算法研究的核心;另外还有2D转3D算法(2D-to-3D conversion),去隔行算法(de-interlacing),运动估计运动补偿算法(Motion estimation/Motion Compensation),去噪算法(Noise Reduction),缩放算法(scaling),锐化处理算法(Sharpness),超分辨率算法(Super Resolution),手势识别(gesture recognition),人脸识别(face recognition)。\n" +
                "在通信物理层等一维信息领域目前常用的算法:无线领域的RRM、RTT,传送领域的调制解调、信道均衡、信号检测、网络优化、信号分解等。\n" +
                "另外数据挖掘、互联网搜索算法也成为当今的热门方向。\n" +
                "算法工程师逐渐往人工智能方向发展。";
        //List<String> phraseList = HanLP.extractPhrase(text, 10);
        IPhraseExtractor extractor = new MutualInformationEntropyPhraseExtractor();
        List<String> phraseList = extractor.extractPhrase(text, 12);
        System.out.println(phraseList);
    }

六、向分词字典中动态添加自定义词汇

java 复制代码
public static void addSeg() {
        {
            // 动态增加
            CustomDictionary.add("攻城狮");
            // 强行插入
            CustomDictionary.insert("白富美", "nz 1024");
            // 删除词语(注释掉试试)
//        CustomDictionary.remove("攻城狮");
            System.out.println(CustomDictionary.add("单身狗", "nz 1024 n 1"));
            System.out.println(CustomDictionary.get("单身狗"));

            String text = "攻城狮逆袭单身狗,迎娶白富美,走上人生巅峰";  // 怎么可能噗哈哈!

            // AhoCorasickDoubleArrayTrie自动机扫描文本中出现的自定义词语
            final char[] charArray = text.toCharArray();
            CustomDictionary.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit<CoreDictionary.Attribute>()
            {
                @Override
                public void hit(int begin, int end, CoreDictionary.Attribute value)
                {
                    System.out.printf("[%d:%d]=%s %s\n", begin, end, new String(charArray, begin, end - begin), value);
                }
            });

            // 自定义词典在所有分词器中都有效
            System.out.println(HanLP.segment(text));
        }
    }
相关推荐
手握风云-11 分钟前
JavaEE初阶第十二期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(十)
java·开发语言·java-ee
盖世英雄酱5813618 分钟前
加了锁,加了事务 还是重复报名❓
java·数据库·后端
Pigwantofly21 分钟前
SpringAI入门及浅实践,实战 Spring‎ AI 调用大模型、提示词工程、对话记忆、Adv‎isor 的使用
java·大数据·人工智能·spring
GEM的左耳返42 分钟前
互联网大厂Java面试:微服务与AI技术深度交锋
spring cloud·ai·微服务架构·java面试·rag技术
微笑听雨1 小时前
Java 设计模式之单例模式(详细解析)
java·后端
微笑听雨1 小时前
【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
java·后端
猫猫的小茶馆1 小时前
【STM32】FreeRTOS 任务的删除(三)
java·linux·stm32·单片机·嵌入式硬件·mcu·51单片机
天天摸鱼的java工程师1 小时前
🔧 MySQL 索引的设计原则有哪些?【原理 + 业务场景实战】
java·后端·面试
空影学Java2 小时前
Day44 Java数组08 冒泡排序
java
追风少年浪子彦2 小时前
mybatis-plus实体类主键生成策略
java·数据库·spring·mybatis·mybatis-plus