分享一篇hanlp分词工具使用的小案例,即利用hanlp分词工具分析两个中文语句的相似度的案例。供大家一起学习参考!

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

下面介绍如何使用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());

}

}

---------------------

Java利用hanlp完成语句相似度分析的案例详解的更多相关文章

  1. 《java入门第一季》之面向对象(面向对象案例详解)

    通过几个小案例理重新回顾一下前面所写的内容,对面向对象的理解更加深刻的目的: 案例一: /* 需求: 定义一个员工类,自己分析出几个成员, 然后给出成员变量,构造方法,getXxx()/setXxx( ...

  2. Android Telephony分析(二) ---- RegistrantList详解

    前言 本文主要讲解RegistrantList的原理,以及如何快速分析RegistrantList相关的代码流程.在Telephony模块中,在RIL.Tracker(ServiceStateTrac ...

  3. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  4. 提高Java代码质量的Eclipse插件之Checkstyle的使用详解

    提高Java代码质量的Eclipse插件之Checkstyle的使用详解 CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具.它能够自动化代 ...

  5. 【集合框架】JDK1.8源码分析之ArrayList详解(一)

    [集合框架]JDK1.8源码分析之ArrayList详解(一) 一. 从ArrayList字表面推测 ArrayList类的命名是由Array和List单词组合而成,Array的中文意思是数组,Lis ...

  6. Java集合中List,Set以及Map等集合体系详解

    转载请注明出处:Java集合中List,Set以及Map等集合体系详解(史上最全) 概述: List , Set, Map都是接口,前两个继承至collection接口,Map为独立接口 Set下有H ...

  7. java 日志体系(三)log4j从入门到详解

    java 日志体系(三)log4j从入门到详解 一.Log4j 简介 在应用程序中添加日志记录总的来说基于三个目的: 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作: 跟踪代 ...

  8. 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+SpringMVC项目详解

    http://blog.csdn.net/noaman_wgs/article/details/53893948 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+Spri ...

  9. Android Telephony分析(五) ---- TelephonyRegistry详解

    本文紧接着上一篇文章<Android Telephony分析(四) —- TelephonyManager详解 >的1.4小节.从TelephonyRegistry的大部分方法中: 可以看 ...

随机推荐

  1. 爬虫系列3:scrapy技术进阶(xpath、rules、shell等)

    本文主要介绍与scrapy应用紧密相关的关键技术,不求很深入,但求能够提取要点.内容包括: 1.xpath选择器:选择页面中想要的内容 2.rules规则:定义爬虫要爬取的域 3.scrapy she ...

  2. Eclipse的配置

    1 Eclipse的工作空间和新建工程 1.1: 工作空间 其实就是我们写的源代码所在的目录 1.2: 创建工程(项目) 右键/Package Explore 空白区/new /Java Projec ...

  3. microsoft office如何在菜单里显示“开发工具”

    VBA开发教程: https://www.yiibai.com/vba/vba_excel_macros.html msdn:https://docs.microsoft.com/zh-cn/offi ...

  4. cxf动态调用外部web service 报告异常java.lang.NoSuchFieldErr

    原因:cxf 依赖的xmlschema-core 与axis2-kernel依赖的xmlschema冲突. 解决方法:因为在项目中只用cxf即可,所以删除axis2的依赖.

  5. Spring Boot 揭秘与实战 源码分析 - 工作原理剖析

    文章目录 1. EnableAutoConfiguration 帮助我们做了什么 2. 配置参数类 – FreeMarkerProperties 3. 自动配置类 – FreeMarkerAutoCo ...

  6. 文件系统--fs(读)--fs.read

    var fs = require('fs');var buf=new Buffer(1024);//fs.open(); //fs.open(path,flags,mode,callback);/* ...

  7. ubuntu discuz 该函数需要 PHP 支持 XML。请联系空间商,确定开启了此项功能

    apt-get install php-xml apt-get install php-xml-parser

  8. 变量与算术表达式 - C程序设计语言

    #include <stdio.h> int main() { float fahr,celsius; float lower,upper,step; lower = 0; upper = ...

  9. centos7 启动mysql

    密码无法登录问题: 在my.cnf  中加一句   skip-grant-tables : 重启mysql服务: mysql -uroot -p: USE mysql ; 进入后,修改密码 .UPDA ...

  10. LeetCode - Is Graph Bipartite?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...