Java利用hanlp完成语句相似度分析的方法详解

2023-12-13 17:08

本文主要是介绍Java利用hanlp完成语句相似度分析的方法详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在做kaoshi系统需求时,后台题库系统提供录入题目的功能。在录入题目的时候,由于题目来源广泛,且参与录入题目的人有多位,因此容易出现录入重复题目的情况。所以需要实现语句相似度分析功能,从而筛选出重复的题目并人工处理之。

下面介绍如何使用 Java 实现上述想法,完成语句相似度分析:

1 、使用 HanLP 完成分词:

首先,添加 HanLP 的依赖:( jsoup 是为了处理题干中的 html 标签,去除 html 标签得到纯文本的题干内容)

分词代码如下,需要处理 html 标签和标点符号:

private static List<String> getSplitWords(String sentence) {// 去除掉 html 标签sentence = Jsoup.parse(sentence.replace(" ","")).body().text();// 标点符号会被单独分为一个 Term ,去除之return HanLP.segment(sentence).stream().map(a -> a.word).filter(s -> !"`~!@#$^&*()=|{}':;',\\[\\].<>/?~ ! @# ¥…… &* ()—— |{} 【】‘;:”“ ' 。,、? ".contains(s)).collect(Collectors.toList());}

2 、合并分词结果,列出所有的词:

3 、统计词频,得到词频构成的向量:

代码如下,其中 allWords 是上一步中得到的所有的词, sentWords 是第一步中对单个句子的分词结果:

4 、计算相似度(两个向量的余弦值):

以上所有方法的完整代码如下,使用 SimilarityUtil.getSimilarity(String s1,String s2) 即可得到 s1 和 s2 的语句相似度:

package com.yuantu.dubbo.provider.questionRepo.utils;import com.hankcs.hanlp.HanLP;import com.hankcs.hanlp.dictionary.CustomDictionary;import org.jsoup.Jsoup;import java.util.ArrayList;import java.util.Calendar;import java.util.Collections;import java.util.List;import java.util.stream.Collectors;public class SimilarityUtil {static {CustomDictionary.add(" 子类 ");CustomDictionary.add(" 父类 ");}private SimilarityUtil() {}/*** 获得两个句子的相似度** @param sentence1* @param sentence2* @return*/public static double getSimilarity(String sentence1, String sentence2) {List<String> sent1Words = getSplitWords(sentence1);System.out.println(sent1Words);List<String> sent2Words = getSplitWords(sentence2);System.out.println(sent2Words);List<String> allWords = mergeList(sent1Words, sent2Words);int[] statistic1 = statistic(allWords, sent1Words);int[] statistic2 = statistic(allWords, sent2Words);double dividend = 0;double divisor1 = 0;double divisor2 = 0;for (int i = 0; i < statistic1.length; i++) {dividend += statistic1[i] * statistic2[i];divisor1 += Math.pow(statistic1[i], 2);divisor2 += Math.pow(statistic2[i], 2);}return dividend / (Math.sqrt(divisor1) * Math.sqrt(divisor2));}private static int[] statistic(List<String> allWords, List<String> sentWords) {int[] result = new int[allWords.size()];for (int i = 0; i < allWords.size(); i++) {result[i] = Collections.frequency(sentWords, allWords.get(i));}return result;}private static List<String> mergeList(List<String> list1, List<String> list2) {List<String> result = new ArrayList<>();result.addAll(list1);result.addAll(list2);return result.stream().distinct().collect(Collectors.toList());}private static List<String> getSplitWords(String sentence) {// 去除掉 html 标签sentence = Jsoup.parse(sentence.replace(" ","")).body().text();// 标点符号会被单独分为一个 Term ,去除之return HanLP.segment(sentence).stream().map(a -> a.word).filter(s -> !"`~!@#$^&*()=|{}':;',\\[\\].<>/?~ ! @# ¥…… &* ()—— |{} 【】‘;:”“ ' 。,、? ".contains(s)).collect(Collectors.toList());}}

原文链接:http://blog.itpub.net/31524777/viewspace-2636656/

这篇关于Java利用hanlp完成语句相似度分析的方法详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/489248

相关文章

Android 12解决push framework.jar无法开机的方法小结

《Android12解决pushframework.jar无法开机的方法小结》:本文主要介绍在Android12中解决pushframework.jar无法开机的方法,包括编译指令、框架层和s... 目录1. android 编译指令1.1 framework层的编译指令1.2 替换framework.ja

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

在.NET平台使用C#为PDF添加各种类型的表单域的方法

《在.NET平台使用C#为PDF添加各种类型的表单域的方法》在日常办公系统开发中,涉及PDF处理相关的开发时,生成可填写的PDF表单是一种常见需求,与静态PDF不同,带有**表单域的文档支持用户直接在... 目录引言使用 PdfTextBoxField 添加文本输入域使用 PdfComboBoxField

SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法

《SQLyog中DELIMITER执行存储过程时出现前置缩进问题的解决方法》在SQLyog中执行存储过程时出现的前置缩进问题,实际上反映了SQLyog对SQL语句解析的一个特殊行为,本文给大家介绍了详... 目录问题根源正确写法示例永久解决方案为什么命令行不受影响?最佳实践建议问题根源SQLyog的语句分

慢sql提前分析预警和动态sql替换-Mybatis-SQL

《慢sql提前分析预警和动态sql替换-Mybatis-SQL》为防止慢SQL问题而开发的MyBatis组件,该组件能够在开发、测试阶段自动分析SQL语句,并在出现慢SQL问题时通过Ducc配置实现动... 目录背景解决思路开源方案调研设计方案详细设计使用方法1、引入依赖jar包2、配置组件XML3、核心配

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

MySQL数据库约束深入详解

《MySQL数据库约束深入详解》:本文主要介绍MySQL数据库约束,在MySQL数据库中,约束是用来限制进入表中的数据类型的一种技术,通过使用约束,可以确保数据的准确性、完整性和可靠性,需要的朋友... 目录一、数据库约束的概念二、约束类型三、NOT NULL 非空约束四、DEFAULT 默认值约束五、UN

Python使用Matplotlib绘制3D曲面图详解

《Python使用Matplotlib绘制3D曲面图详解》:本文主要介绍Python使用Matplotlib绘制3D曲面图,在Python中,使用Matplotlib库绘制3D曲面图可以通过mpl... 目录准备工作绘制简单的 3D 曲面图绘制 3D 曲面图添加线框和透明度控制图形视角Matplotlib