当前位置: 首页 > article >正文

java实现文本相似度计算

需求

**文本推荐:**有多个文本字符串,如何设计一个简单的统计方法(从词频的角度设计),来计算出多个文本字符串两两之间的相似度,并输出大于指定相似度阈值的文本

分析理解

使用Java实现文本相似度计算的一种方法是通过构建词频向量并计算余弦相似度,具体介绍如下,简单易懂
在这里插入图片描述
在这里插入图片描述

代码实现

复杂粘贴可以直接运行

        <!--  使用HanLP进行分词  -->
        <dependency>
            <groupId>com.hankcs</groupId>
            <artifactId>hanlp</artifactId>
            <version>portable-1.8.4</version>
        </dependency>
import com.hankcs.hanlp.tokenizer.StandardTokenizer;
import java.util.*;
import java.util.stream.Collectors;

public class ChineseTextRecommender {

    // 使用HanLP进行中文分词
    // 构建词频向量
    // 假设我们有两个文本文档,我们想衡量它们的主题相似性。每个文档可以被表示为一个向量,其中包含词频(TF)或TF-IDF值。
    // 文档A: "the cat sat on the mat on the mat"
    // 文档B: "the cat and the dog played"
    // 我们选择几个关键词:"the", "cat", "sat", "on", "mat", "and", "dog", "played"。每个词在文档中出现的次数(词频)可以构成一个向量。
    // 向量A: [2, 1, 1, 1, 2, 0, 0, 0]("the", "cat", "sat", "on", "mat", "and", "dog", "played")
    // 向量B: [1, 1, 0, 0, 0, 1, 1, 1]
    public static Map<String, Integer> buildTermVector(String text) {
        List<String> words = StandardTokenizer.segment(text).stream()
                .map(term -> term.word)
                .collect(Collectors.toList());
        Map<String, Integer> termVector = new HashMap<>();
        for (String word : words) {
            termVector.put(word, termVector.getOrDefault(word, 0) + 1);
        }
        return termVector;
    }

    // 计算余弦相似度
    public static double cosineSimilarity(Map<String, Integer> vectorA, Map<String, Integer> vectorB) {
        double dotProduct = 0.0;
        double normA = 0.0;
        double normB = 0.0;

        for (String key : vectorA.keySet()) {
            dotProduct += vectorA.get(key) * (vectorB.getOrDefault(key, 0));
            normA += Math.pow(vectorA.get(key), 2);
        }

        for (String key : vectorB.keySet()) {
            normB += Math.pow(vectorB.get(key), 2);
        }

        if (normA == 0 || normB == 0) {
            return 0.0;
        }

        return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
    }

    // 推荐与指定文本相似度高的文本 texts为待判断文本列表
    public static List<String> recommendTexts(List<String> texts, String targetText, double threshold) {
        Map<String, Double> similarityScores = new HashMap<>();
        Map<String, Integer> targetVector = buildTermVector(targetText);

        for (String text : texts) {
            Map<String, Integer> textVector = buildTermVector(text);
            double similarity = cosineSimilarity(targetVector, textVector);
            similarityScores.put(text, similarity);
            System.out.println(text + " ----Similarity: " + similarity);
        }

        return similarityScores.entrySet().stream()
                .filter(entry -> entry.getValue() >= threshold)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    public static void main(String[] args) {
        // 相似度分别为0.91 0.59 0.54 0.799 0.791
        List<String> texts = Arrays.asList("这是一个测试文档吗", "这是第二个文档", "这是第三个文档","这是一个文档吗","这是第一个测试文档吧哈哈");
        String targetText = "这是一个测试文档";
        double threshold = 0.8; // 理论上,阈值在0.5左右都可以接受

        List<String> recommendedTexts = recommendTexts(texts, targetText, threshold);

        System.out.println("推荐文本:");
        recommendedTexts.forEach(System.out::println);
    }
}

输出结果

在这里插入图片描述


http://www.kler.cn/a/298962.html

相关文章:

  • 【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget
  • JavaScript 中的 `parseInt()` 函数详解
  • 拆解一个微型气泵了解工作原理
  • 强基计划之编程:开启科研精英培养新路径
  • spring学习(spring-DI(setter注入、构造器注入、自动装配方式))
  • (OCPP服务器)SteVe编译搭建全过程
  • 基于C#的UDP协议消息传输
  • sql中索引查看是否生效
  • 计算机网络 --- 【1】欢迎来到计算机网络/计算机网络基本概念/计算机网络、互连网、互联网的区别
  • Springcould -第一个Eureka应用 --- day02
  • Apache POI用法
  • [网鼎杯 2020 朱雀组]Nmap 历程记录
  • Java 远程执行服务器上的命令
  • HP电脑如何启动硬件检测
  • 数据结构应用实例(六)——最短路径
  • CCF刷题计划——坐标变换(其二)(前缀和)
  • Dubbo 与 Zookeeper 在项目中的应用:原理与实现详解
  • 深入理解Java虚拟机:Jvm总结-垃圾收集器与内存分配策略
  • 【C++】list的使用与简单模拟实现
  • 通过Python调用Excel VBA宏:扩展自动化能力的深度探索
  • 深入理解java并发编程之aqs框架
  • ABB机器人教程:外部调用例行程序功能介绍与使用方法
  • 流媒体之HLS协议(其三)
  • 动态规划-最长回文子序列
  • Android自动化1️⃣环境搭建【基于Appium】-基于python
  • 在执行django定时任务中,遇到的celery woker生命周期问题