行业资讯 2025年08月6日
0 收藏 0 点赞 967 浏览 4124 个字
摘要 :

文章目录 一、相似度计算到底是什么? 二、Java实现相似度计算的开源库 三、相似度计算算法的Java实现 (一)欧氏距离的实现 (二)余弦相似度的实现 (三)杰卡德相似……




  • 一、相似计算到底是什么?
  • 二、Java实现相似度计算的开源库
  • 三、相似度计算算法的Java实现
    • (一)欧氏距离的实现
    • (二)余弦相似度的实现
    • (三)杰卡德相似度的实现
    • (四)编辑距离的实现
  • 四、总结与选择建议

在Java开发的很多场景里,比如机器学习、自然语言处理、信息检索等,都需要判断两个对象的相似程度,这就涉及到相似度计算。今天这篇文章,就来给大家详细讲讲在Java里如何实现几种常见的相似度计算算法。

一、相似度计算到底是什么?

简单来说,相似度计算就是想办法用一个数值来表示两个对象有多像。打个比方,在文本处理中,判断两篇文章是不是主题相似;在图像识别里,看看两张图片像不像;在数据分析时,衡量两组数据的相似程度。这些场景都离不开相似度计算。常见的相似度度量方法有下面几种:

  • 欧氏距离:想象在一个空间里有两个点,欧氏距离就是这两个点之间的直线距离。在计算向量相似度时,距离越小,说明这两个向量越相似。
  • 余弦相似度:它主要衡量两个向量之间的夹角。夹角越小,余弦值越接近1,也就意味着这两个向量越相似。在文本向量比较方面,比如文档分类或者主题识别,经常会用到它。
  • 杰卡德相似度:这种方法适用于集合。计算两个集合的交集和并集的比值,就能得到它们的相似度。在处理文本的集合表示,像单词集合、标签集合时,它就派上用场了。
  • 编辑距离(Levenshtein Distance):它用来计算把一个字符串变成另一个字符串,最少需要进行多少次插入、删除或者替换字符的操作。拼写检查、字符串匹配场景经常会用到。

二、Java实现相似度计算的开源库

在Java里实现相似度计算,有不少开源库能帮我们大忙:

  • Apache Commons Math:这个库在数学运算方面非常强大,能让我们更高效地完成相似度计算中涉及的各种数学操作。
  • Simmetrics:专门用来计算字符串相似度的库,功能很专业。

关于Simmetrics苦的使用,可以参考一下这篇文章:

Java 使用SimMetrics库实现相似度计算

文章目录 一、SimMetrics库是什么? 二、快速使用SimMetrics库 (一)添加依赖 (二)简单示 […]

接下来,咱们通过代码看看怎么用Java实现这些相似度算法。

三、相似度计算算法的Java实现

(一)欧氏距离的实现

欧氏距离是向量之间很常用的距离度量方式,计算的是空间中两个点的距离。下面是Java实现代码:

public class EuclideanDistance {
    // 计算两个向量之间欧氏距离的方法
    public static double calculate(double[] vec1, double[] vec2) {
        // 检查两个向量长度是否相等,如果不相等则抛出异常
        if (vec1.length != vec2.length) {
            throw new IllegalArgumentException(\"向量长度必须相等\");
        }

        double sum = 0.0;
        // 遍历向量的每个维度
        for (int i = 0; i < vec1.length; i++) {
            // 计算每个维度上两个向量元素差值的平方,并累加到sum中
            sum += Math.pow(vec1[i] - vec2[i], 2);
        }
        // 对累加的结果取平方根,得到欧氏距离
        return Math.sqrt(sum);
    }

    public static void main(String[] args) {
        // 定义两个向量
        double[] vec1 = {1.0, 2.0, 3.0};
        double[] vec2 = {4.0, 5.0, 6.0};

        // 计算并输出这两个向量的欧氏距离
        double distance = calculate(vec1, vec2);
        System.out.println(\"欧氏距离: \" + distance);
    }
}

在这段代码里,calculate方法通过循环计算每个维度上的差值平方和,最后取平方根得到欧氏距离。

(二)余弦相似度的实现

余弦相似度通过衡量两个向量的夹角来判断它们的相似程度,值越接近1,向量越相似。代码如下:

public class CosineSimilarity {
    // 计算两个向量之间余弦相似度的方法
    public static double calculate(double[] vec1, double[] vec2) {
        // 检查向量长度是否相等,不相等则抛出异常
        if (vec1.length != vec2.length) {
            throw new IllegalArgumentException(\"向量长度必须相等\");
        }

        double dotProduct = 0.0;
        double normVec1 = 0.0;
        double normVec2 = 0.0;

        // 遍历向量的每个维度
        for (int i = 0; i < vec1.length; i++) {
            // 计算向量的点积
            dotProduct += vec1[i] * vec2[i];
            // 计算向量vec1的模的平方
            normVec1 += Math.pow(vec1[i], 2);
            // 计算向量vec2的模的平方
            normVec2 += Math.pow(vec2[i], 2);
        }

        // 通过点积除以两个向量模的乘积,得到余弦相似度
        return dotProduct / (Math.sqrt(normVec1) * Math.sqrt(normVec2));
    }

    public static void main(String[] args) {
        // 定义两个向量
        double[] vec1 = {1.0, 2.0, 3.0};
        double[] vec2 = {4.0, 5.0, 6.0};

        // 计算并输出这两个向量的余弦相似度
        double similarity = calculate(vec1, vec2);
        System.out.println(\"余弦相似度: \" + similarity);
    }
}

calculate方法先计算点积和向量的模,再通过点积除以两个向量模的乘积得到余弦相似度,结果在 -1 到 1 之间。

(三)杰卡德相似度的实现

杰卡德相似度主要用于衡量两个集合的相似度,通过计算交集和并集的比值来确定。代码如下:

import java.util.HashSet;
import java.util.Set;

public class JaccardSimilarity {
    // 计算两个集合之间杰卡德相似度的方法
    public static double calculate(Set<String> set1, Set<String> set2) {
        // 求两个集合的交集
        Set<String> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);  

        // 求两个集合的并集
        Set<String> union = new HashSet<>(set1);
        union.addAll(set2);  

        // 通过交集大小除以并集大小,得到杰卡德相似度
        return (double) intersection.size() / union.size();
    }

    public static void main(String[] args) {
        // 定义两个集合
        Set<String> set1 = new HashSet<>();
        set1.add(\"a\");
        set1.add(\"b\");
        set1.add(\"c\");

        Set<String> set2 = new HashSet<>();
        set2.add(\"b\");
        set2.add(\"c\");
        set2.add(\"d\");

        // 计算并输出这两个集合的杰卡德相似度
        double similarity = calculate(set1, set2);
        System.out.println(\"杰卡德相似度: \" + similarity);
    }
}

calculate方法里,先求出两个集合的交集和并集,再用交集大小除以并集大小,得到杰卡德相似度。

(四)编辑距离的实现

编辑距离衡量两个字符串的差异,计算把一个字符串变成另一个字符串最少需要的编辑操作次数。代码如下:

public class LevenshteinDistance {
    // 计算两个字符串之间编辑距离的方法
    public static int calculate(String s1, String s2) {
        // 创建一个二维数组dp,用于存储中间计算结果
        int[][] dp = new int[s1.length() + 1][s2.length() + 1];

        // 初始化第一行和第一列
        for (int i = 0; i <= s1.length(); i++) {
            for (int j = 0; j <= s2.length(); j++) {
                if (i == 0) {
                    dp[i][j] = j;
                } else if (j == 0) {
                    dp[i][j] = i;
                } else if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j], dp[i][j - 1]));
                }
            }
        }
        // 返回最终计算得到的编辑距离
        return dp[s1.length()][s2.length()];
    }

    public static void main(String[] args) {
        // 定义两个字符串
        String s1 = \"kitten\";
        String s2 = \"sitting\";

        // 计算并输出这两个字符串的编辑距离
        int distance = calculate(s1, s2);
        System.out.println(\"编辑距离: \" + distance);
    }
}

calculate方法使用动态规划算法,通过填充二维数组dp来计算编辑距离,最后返回最右下角的值作为结果。

四、总结与选择建议

这篇文章给大家介绍了欧氏距离、余弦相似度、杰卡德相似度和编辑距离这几种常见的相似度计算算法,还给出了Java实现代码。不同的算法适用于不同的场景,比如做文本向量比较,余弦相似度可能更合适;处理集合相似度,杰卡德相似度是个好选择;而字符串匹配的话,编辑距离就派上用场了。大家在实际开发中,可以根据具体需求选择最合适的算法。要是在使用过程中有问题,欢迎一起交流探讨。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10285.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号