原理是,将每个句子换算成一个向量,计算向量的余弦相似度,取相似度最大的句子作为匹配结果。本质还是分词处理,词汇出现次数比较。

分词的原理是,将所有句子去重得到总的词库,每个句子分词后与总词库作比较得到该句子的向量。为什么要这么做呢?方便数值计算。

余弦相似度表征两个向量的相似程度,向量的夹角越小余弦相似度越大。

计算公式为
cosθ=a⋅b∣a∣∣b∣cos\theta=\frac{a\cdot b}{|a||b|} cosθ=∣a∣∣b∣a⋅b​

package test;import com.hankcs.hanlp.tokenizer.StandardTokenizer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** 分词处理测试*/
public class Test02 {public static void main(String[] args) {String input = "2020年云南省语文";String s1 = "2019年云南省曲靖市中考语文试题";String s2 ="云南省曲靖市中考数学试题2018年";String s3 ="2020年云南省宣威市中考语文试题";String s4 ="2020年浙江省宣威市中考物理试题";System.out.println(input);System.out.println(s1);System.out.println(s2);System.out.println(s3);System.out.println(s4);List<String> input1 = StandardTokenizer.segment(input).stream().map(a->a.word).collect(Collectors.toList());List<String> words1 = StandardTokenizer.segment(s1).stream().map(a->a.word).collect(Collectors.toList());List<String> words2 = StandardTokenizer.segment(s2).stream().map(a->a.word).collect(Collectors.toList());List<String> words3 = StandardTokenizer.segment(s3).stream().map(a->a.word).collect(Collectors.toList());List<String> words4 = StandardTokenizer.segment(s4).stream().map(a->a.word).collect(Collectors.toList());List<String> words5 = new ArrayList<>();words5.addAll(words1);words5.addAll(words2);words5.addAll(words3);words5.addAll(words4);System.out.println("输入语句分词 "+input1);System.out.println("words1分词 "+words1);System.out.println("words2分词 "+words2);System.out.println("words3分词 "+words3);System.out.println("words4分词 "+words4);System.out.println(words4);words5 = words5.stream().distinct().collect(Collectors.toList());System.out.println("words5去重后的总体词库 "+words5);int[] inputVertex = getVertex(input1,words5);int[] vertex1 = getVertex(words1,words5);int[] vertex2 = getVertex(words2,words5);int[] vertex3 = getVertex(words3,words5);int[] vertex4 = getVertex(words4,words5);System.out.println("输入句子向量 "+ Arrays.toString(inputVertex));System.out.println("句子1向量    "+Arrays.toString(vertex1));System.out.println("句子2向量    "+Arrays.toString(vertex2));System.out.println("句子3向量    "+Arrays.toString(vertex3));System.out.println("句子4向量    "+Arrays.toString(vertex4));double cosTheta1 = cosTheta(inputVertex,vertex1);double cosTheta2 = cosTheta(inputVertex,vertex2);double cosTheta3 = cosTheta(inputVertex,vertex3);double cosTheta4 = cosTheta(inputVertex,vertex4);System.out.println(cosTheta1);System.out.println(cosTheta2);System.out.println(cosTheta3);System.out.println(cosTheta4);}/*** 计算余弦相似度* @param a* @param b* @return*/private static double cosTheta(int[] a,int[] b){try {return aDotB(a,b)/(absoluteA(a)*absoluteA(b));} catch (Exception e) {e.printStackTrace();}return 0;}/*** 根据总词组,统计每个词在句子中的出现次数,获取每个句子的词组向量* @param words* @param totalWords* @return*/private static int[] getVertex(List<String> words,List<String> totalWords){int[] a = new int[totalWords.size()];for (int i = 0; i <totalWords.size() ; i++) {int count = 0;for(String word:words){if(totalWords.get(i).equals(word)){count++;}}a[i]=count;}return a;}/*** 计算向量点乘* @param a* @param b* @return*/private static double aDotB(int[] a,int [] b) throws Exception {if(a.length!=b.length){throw new Exception("要求向量维度一致");}double result = 0;for (int i = 0; i <a.length ; i++) {result+=a[i]*b[i];}return result;}/*** 计算向量的模* @param a* @return*/private static double absoluteA(int[] a){double tmp = 0;for (int i = 0; i <a.length ; i++) {tmp+=a[i]*a[i];}return Math.sqrt(tmp);}
}
2020年云南省语文
2019年云南省曲靖市中考语文试题
云南省曲靖市中考数学试题2018年
2020年云南省宣威市中考语文试题
2020年浙江省宣威市中考物理试题
输入语句分词 [2020, 年, 云南省, 语文]
words1分词 [2019, 年, 云南省, 曲靖市, 中考, 语文, 试题]
words2分词 [云南省, 曲靖市, 中考, 数学, 试题, 2018, 年]
words3分词 [2020, 年, 云南省, 宣威, 市, 中考, 语文, 试题]
words4分词 [2020, 年, 浙江省, 宣威, 市, 中考, 物理, 试题]
[2020, 年, 浙江省, 宣威, 市, 中考, 物理, 试题]
words5去重后的总体词库 [2019, 年, 云南省, 曲靖市, 中考, 语文, 试题, 数学, 2018, 2020, 宣威, 市, 浙江省, 物理]
输入句子向量 [0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]
句子1向量    [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0]
句子2向量    [0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0]
句子3向量    [0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0]
句子4向量    [0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1]
0.5669467095138409
0.3779644730092272
0.7071067811865475
0.35355339059327373

比如输入 ‘云南省语文2020年’ 匹配到句子3 ‘2020年云南省宣威市中考语文试题’
尽管语序不同,但是它们的词库相似度是最大的,也给捞出来了。

小结:此手法解决了sql关键字匹配中,where keyword=xxx 或者 where keyword like '% xxx%‘ 匹配不到的问题

Java分词处理测试相关推荐

  1. 使用μJava进行变异体测试

    一.环境配置 mujava运行的是Java程序,Java的环境配置见Eclipse+JDK配置那点事. 将下载的mujava相关文件放到一个文件夹,文件夹放到C:\muJava 添加mujava环境变 ...

  2. java流行的测试框架调研+市面上书籍调研

    主要是根据51job的右侧来判断 java测试框架名称 51job职位数量 百度词条数量 JUnit 732 48,500,000 REST Assured 3 19,500,000 Selenium ...

  3. tdd java_适用于Idea的面向现代TDD的Java 8 JUnit测试模板(带有Mockito和AssertJ)

    tdd java 使用类似于BDD的语法,Java 8和Mockito-AssertJ二重奏为Idea调整JUnit测试类模板. 本文涵盖的主题似乎很简单. 但是,根据我的培训师经验,我知道(不幸的) ...

  4. Java XMPP负载测试工具

    在本文中,我们将开发用Java编写的XMPP负载测试工具. 目录 1.简介 2. XMPP负载测试工具 3.先决条件 4. LoadXmppTest Java程序 4.1. 创建一个新的Maven项目 ...

  5. 适用于Idea的面向现代TDD的Java 8 JUnit测试模板(带有Mockito和AssertJ)

    使用类似BDD的语法,Java 8和Mockito-AssertJ二重奏为Idea调整JUnit测试类模板. 本文涵盖的主题似乎很简单. 但是,根据我的培训师经验,我知道(不幸的是)这不是常见的做法. ...

  6. Java EE 6测试第I部分– EJB 3.1可嵌入API

    我们从Enterprise JavaBeans开发人员那里听到的最常见的请求之一就是需要改进的单元/集成测试支持. EJB 3.1 Specification引入了EJB 3.1 Embeddable ...

  7. Java EE 6测试第二部分– Arquillian和ShrinkWrap简介

    在Java EE 6测试的第一部分中,我简要介绍了使用Glassfish嵌入式容器的EJB 3.1 Embeddable API,以演示如何启动该容器,如何在项目类路径中查找bean以及运行非常简单的 ...

  8. at java.net.url init,java.net 基本测试

    java.net 基本测试 包 java.net java.net.ssl 类java.net.URL 测试类package com.mozq.boot.kuayu01.demo; import ja ...

  9. 微信公众账号第三方平台全网发布源码(java)- 实战测试通过

    微信公众账号第三方平台全网发布源码(java)- 实战测试通过 (更多资料,关注论坛:www.jeecg.org) 技术交流请加:289709451.287090836 package org.jee ...

  10. 6大中文分词工具测试比较

    中文分词工具比较 6大中文分词器测试(jieba.FoolNLTK.HanLP.THULAC.nlpir.ltp) 哈工大LTP.中科院计算所NLPIR.清华大学THULAC和jieba 个人接触的分 ...

最新文章

  1. 关于行号输出的简单命令
  2. 学习使用TryParse方法
  3. EntityFramework 启用迁移 Enable-Migrations 报异常 No context type was found in the assembly
  4. 爬取IMDBTOP250
  5. LeetCode MySQL 574. 当选者
  6. c语言实现ftp网络应用程序,使用C语言socket实现windows pc与ftp服务器通信---socket实现ftp客户端...
  7. python实践项目(二)
  8. oracle stalestats_深入理解oracle优化器统计数据(Optimizer Statistics)
  9. Graph Theory
  10. Java基础(一):Java集合框架(超详细解析,看完面试不再怕)
  11. Android设置屏幕亮度的两种方式
  12. 关于微信小程序的navigator标签
  13. Java练习10:输入两个正整数m和n,求其最大公约数和最小公倍数
  14. C语言 两种方法优化:输入一个日期的年、月、日,计算并输出这天是该年的第几天。
  15. 盘点最近 火火火 的 7 个 GitHub 项目
  16. 【数模/预测】灰色预测
  17. 扬州大学计算机系导师,胡学龙
  18. 如何让你的电脑声音增大500%
  19. SpringBoot从入门到入土 (6)HelloWorldSpringBoot项目开发实战
  20. 女赛--Girl Love Value (01背包)

热门文章

  1. OS 中的SID(安全标识)
  2. Visualizing and Understanding Convolutional Networks论文解读
  3. decaNLP-一个可以同时处理机器翻译、问答、摘要、文本分类、情感分析等十项自然语言任务的通用模型
  4. HDFS YARN zookeeper HBASE HIVE HIVE hwi的启动
  5. C++--第24课 - 专题四经典问题解析
  6. 数据--第47课 - 查找的概念
  7. Laravel Pipeline解读
  8. Lync 小技巧-39-批量-设置-AD-分机-手机-启用-Lync-设置-Lync-分机
  9. 疯狂ios讲义疯狂连载之图像控件(UIImageView)
  10. css中文本超出部分省略号代替