通过Java实现中文分词与文本关键词提取

 更新时间:2023年06月12日 14:14:09   作者:欧内的手好汗  
这篇文章主要为大家详细介绍了如何利用Java实现中文分词以及文本关键词提取功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习学习

我当前在做的项目需求:在xx单子中提取出我想要的关键词,涉及中文分词的内容,可以借助IK分词器实现此功能。

1、引入依赖

ik用于分词,commons-io用来读取文件内容(我懒)

<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
</dependency>

注意:如果项目使用了ElasticSearch,可能会出现冲突,需根据你的情况手动排除,如下

<dependency>
    <groupId>com.janeluo</groupId>
    <artifactId>ikanalyzer</artifactId>
    <version>2012_u6</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-core</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.lucene</groupId>
            <artifactId>lucene-analyzers-common</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2、创建自己的词典

创建文件,在里面输入自己想要扩充的词语,放到resources中,命名如“keywords.dic”

3、创建分词工具类

package com.iherb.user.util;
import org.apache.commons.io.IOUtils;
import org.wltea.analyzer.cfg.Configuration;
import org.wltea.analyzer.cfg.DefaultConfig;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.dic.Dictionary;
import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class KeywordUtil {
    Configuration cfg;
    List<String> expandWords = new ArrayList<>();
    /**
     * 每个词的最小长度
     */
    private static final int MIN_LEN = 2;
    KeywordUtil() {
        cfg = DefaultConfig.getInstance();
        cfg.setUseSmart(true); //设置useSmart标志位 true-智能切分 false-细粒度切分
        boolean flag = loadDictionaries("keywords.dic");
        if (!flag) {
            throw new RuntimeException("读取失败");
        }
        Dictionary.initial(cfg);
        Dictionary.getSingleton().addWords(expandWords); //词典中加入自定义单词
    }
    /**
     * 加载自定义词典,若无想要添加的词则无需调用,使用默认的词典
     * @param filenames
     * @return
     */
    private boolean loadDictionaries(String... filenames) {
        try {
            for (String filename : filenames) {
                expandWords.addAll(
                    IOUtils.readLines(
                        KeywordUtil.class.getClassLoader().getResourceAsStream(filename),
                        StandardCharsets.UTF_8
                    )
                );
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 提取词语,结果将按频率排序
     * @param text 待提取的文本
     * @return 提取出的词
     */
    public List<String> extract(String text) {
        StringReader reader = new StringReader(text);
        IKSegmenter ikSegmenter = new IKSegmenter(reader, cfg);
        Lexeme lex;
        Map<String, Integer> countMap = new HashMap<>();
        try {
            while ((lex = ikSegmenter.next()) != null) {
                String word = lex.getLexemeText();
                if (word.length() >= MIN_LEN) { //取出的词至少#{MIN_LEN}个字
                    countMap.put(word, countMap.getOrDefault(word, 0) + 1);
                }
            }
            List<String> result = new ArrayList<>(countMap.keySet());
            //根据词出现频率从大到小排序
            result.sort((w1, w2) -> countMap.get(w2) - countMap.get(w1));
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }
    /**
     * 提取存在于我扩充词典的词
     * @param num 需要提取的词个数
     * @return
     */
    public List<String> getKeywords(String text, Integer num) {
        List<String> words = extract(text);
        List<String> result = new ArrayList<>();
        int count = 0;
        for (String word : words) {
            if (expandWords.contains(word)) {
                result.add(word);
                if (++count == num) {
                    break;
                }
            }
        }
        return result;
    }
    public static void main(String[] args) {
        String text = "哈哈无花果翠云草酢浆草是什么,。我是帅哥666无花果真好吃还有北沙参穿心莲翠云草,草豆蔻和蝉蜕酢浆草也不错的";
        KeywordUtil keywordUtil = new KeywordUtil();
        List<String> keywords = keywordUtil.getKeywords(text, 5);
        keywords.forEach(System.out::println);
    }
}

4、测试

以上就是通过Java实现中文分词与文本关键词提取的详细内容,更多关于Java分词的资料请关注脚本之家其它相关文章!

相关文章

  • 深入浅出讲解Spring框架中AOP及动态代理的应用

    深入浅出讲解Spring框架中AOP及动态代理的应用

    在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术
    2022-03-03
  • Swing拆分窗格控件JSplitPane使用详解

    Swing拆分窗格控件JSplitPane使用详解

    这篇文章主要为大家详细介绍了Swing拆分窗格控件JSplitPane的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • java JVM-clinit指令实现原理面试精讲

    java JVM-clinit指令实现原理面试精讲

    这篇文章主要介绍了java JVM-clinit指令实现原理面试精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Spring Boot整合Web项目常用功能详解

    Spring Boot整合Web项目常用功能详解

    这篇文章主要介绍了Spring Boot整合Web项目常用功能详解,在Web应用开发过程中,可以通过Spring Boot的Starter来将这些常用功能进行整合与集中维护,以达到开箱即用的目的。,需要的朋友可以参考下
    2019-06-06
  • Java程序执行cmd命令全过程

    Java程序执行cmd命令全过程

    这篇文章主要介绍了Java程序执行cmd命令全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法

    SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法

    这篇文章主要给大家介绍了关于SpringBoot中@ComponentScan注解过滤排除不加载某个类的3种方法,文中通过实例代码介绍的非常详细,对大家学习或者使用SpringBoot具有一定的参考学习价值,需要的朋友可以参考下
    2023-07-07
  • Java Springboot 重要知识点整理汇总

    Java Springboot 重要知识点整理汇总

    Spring Boot作为微服务中最好的Java框架,本文主要为大家整理汇总了七个Spring Boot的重要知识点,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2021-11-11
  • Spring中@RestControllerAdvice注解的使用详解

    Spring中@RestControllerAdvice注解的使用详解

    这篇文章主要介绍了Spring中@RestControllerAdvice注解的使用详解,@RestControllerAdvice是一个组合注解,由@ControllerAdvice、@ResponseBody组成,而@ControllerAdvice继承了@Component,需要的朋友可以参考下
    2024-01-01
  • Java DriverManager.getConnection()获取数据库连接

    Java DriverManager.getConnection()获取数据库连接

    这篇文章主要介绍了Java DriverManager.getConnection()获取数据库连接,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java中如何读取和写入zip文件问题

    Java中如何读取和写入zip文件问题

    这篇文章主要介绍了Java中如何读取和写入zip文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06

最新评论