相似度算法——余弦相似度(附带Java现实)

余弦相似度


概述

     用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似。

一、实现思路

  1. 分词:对需要比较的文本进行分词,获得词和词频(key/num)。
  2. 统计:统计所有的词(去重),作为向量的维度。
  3. 构建:以词作为维度,词频作为当前维度的值,构建向量。没有的以0填充。
  4. 计算:在这里插入图片描述

二、实现流程

举个简单的例子:

  1. 准备比较文本

    文本一:黑灰化肥灰会挥发发灰黑讳为黑灰花会飞

    文本二:灰黑化肥会会挥发发黑灰为讳飞花化为灰

  2. 分词并统计词频

    文本一:“灰”:4,“挥发”:1,“黑”:3,“发”:1,“讳”:1,“化肥”:1,“花会”:1,“会”:1,“为”:1,“飞”:1

    文本二:“灰”:3,“挥发”:1,“飞花”:1,“黑”:2,“发”:1,“讳”:1,“化肥”:1,“会”:2,“为”:1,“化为”:1

  3. 统计所有词

    所有词:“灰”,“挥发”,“飞花”,“黑”,“发”,“讳”,“化肥”,“花会”,“会”,“为”,“飞”,“化为”

    文本一:(4,1,0,3,1,0,1,1,1,1,0,1,0)

    文本二:(3,1,1,2,1,1,1,2,1,0,1,1,1)

  4. 计算

x = 4 ⋅ 3 + 1 ⋅ 1 + 0 ⋅ 1 + … … + 0 ⋅ 1 + 1 ⋅ 1 + 0 ⋅ 1 4 2 + 1 2 + 0 2 + … … + 0 2 + 1 2 + 0 2 − 3 2 + 1 2 + 1 2 + … … + 1 2 + 1 2 + 1 2 = 0.888336318148377 x = \frac{4\cdot3+1\cdot1+0\cdot1+……+0\cdot1+1\cdot1+0\cdot1}{\sqrt{4^2+1^2+0^2+……+0^2+1^2+0^2}-\sqrt{3^2+1^2+1^2+……+1^2+1^2+1^2}} = 0.888336318148377 x=42+12+02++02+12+02 32+12+12++12+12+12 43+11+01++01+11+01=0.888336318148377

三、代码实现

代码如下(java):

public class CosAlgorithm {
    public static void main(String[] args) {
        String str1 = "黑灰化肥灰会挥发发灰黑讳为黑灰花会飞";
        String str2 = "灰黑化肥会会挥发发黑灰为讳飞花化为灰";
        StopRecognition filter = new StopRecognition();
        //过滤掉标点
        filter.insertStopNatures("w");
        //分词-统计词频
        Map<String,Integer> map1= new HashMap<>();
        ToAnalysis.parse(str1).recognition(filter).forEach(item -> {
            //没有则赋初始值,有则+1
            if (map1.get(item.getName()) == null){
                map1.put(item.getName(),1);
            }else {
                map1.put(item.getName(),map1.get(item.getName())+1);
            }
        });
        Map<String,Integer> map2 = new HashMap<>();
        ToAnalysis.parse(str2).recognition(filter).forEach(item -> {
            //没有则赋初始值,有则+1
            if (map2.get(item.getName()) == null){
                map2.put(item.getName(),1);
            }else {
                map2.put(item.getName(),map2.get(item.getName())+1);
            }
        });
        System.out.println("map1="+ JSON.toJSONString(map1));
        System.out.println("map2="+ JSON.toJSONString(map2));
        Set<String> set1 = map1.keySet();
        Set<String> set2 = map2.keySet();
        Set<String> setAll = new HashSet<>();
        setAll.addAll(set1);
        setAll.addAll(set2);
        System.out.println("all="+JSON.toJSONString(setAll));
        List<Integer> list1 = new ArrayList<>(setAll.size());
        List<Integer> list2 = new ArrayList<>(setAll.size());
        //构建向量
        setAll.forEach(item ->{
            if (set1.contains(item)){
                list1.add(map1.get(item));
            }else {
                list1.add(0);
            }

            if (set2.contains(item)){
                list2.add(map2.get(item));
            }else {
                list2.add(0);
            }
        });
        //计算余弦相似度
        int sum =0;
        long sq1 = 0;
        long sq2 = 0;
        double result = 0;
        for (int i =0;i<setAll.size();i++){
            sum +=list1.get(i)*list2.get(i);
            sq1 += list1.get(i)*list1.get(i);
            sq2 += list2.get(i)*list2.get(i);
        }
        result = sum/(Math.sqrt(sq1)*Math.sqrt(sq2));
        System.out.println("余弦相似度="+result);
       
    }
}

总结

结合样例,然后运行代码,你就会了~

参考:https://blog.csdn.net/u012160689/article/details/15341303

  • 1
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Levenshtein Distance算法是一种常见的字符串相似度算法,也被称为编辑距离算法。其主要思想是通过计算两个字符串之间的编辑距离来确定它们的相似程度。 编辑距离指的是将一个字符串转换成另一个字符串所需的最少操作次数,其中每次操作可以是插入、删除或替换一个字符。例如,将字符串“kitten”转换成字符串“sitting”需要进行3次操作,即将“k”替换为“s”,将“e”替换为“i”,将“n”替换为“g”。 Levenshtein Distance算法的实现一般使用动态规划的方法,通过填充一个二维矩阵来计算两个字符串之间的编辑距离。具体实现过程可以参考以下伪代码: ``` function LevenshteinDistance(s1, s2): m = length(s1) n = length(s2) d = new matrix(m+1, n+1) for i from 0 to m: d[i, 0] = i for j from 0 to n: d[0, j] = j for j from 1 to n: for i from 1 to m: if s1[i] == s2[j]: cost = 0 else: cost = 1 d[i, j] = min(d[i-1, j]+1, d[i, j-1]+1, d[i-1, j-1]+cost) return d[m, n] ``` 在以上代码中,变量s1和s2分别表示两个待比较的字符串,m和n分别表示它们的长度,矩阵d用于存储编辑距离的计算结果。首先,将矩阵d的第一行和第一列分别初始化为0到n和0到m的整数。然后,对于每个(i, j)位置,如果s1[i]等于s2[j],则将cost设为0,否则设为1。最后,根据递推公式d[i, j] = min(d[i-1, j]+1, d[i, j-1]+1, d[i-1, j-1]+cost)来填充矩阵d,并返回d[m, n]作为编辑距离的结果。 Levenshtein Distance算法的时间复杂度为O(m*n),其中m和n分别为两个字符串的长度。在实际应用中,该算法可用于拼写检查、数据去重等场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值