代码改变世界

计算两组标签相似度算法——levenshtein distance 编辑距离算法

2020-02-17 23:34  默默不语  阅读(929)  评论(0编辑  收藏  举报

  标签在数据分析中起到很重要的作用,给用户打标签,给商品打标签,给新闻打标签,好的标签可以为我们后期分析数据时提供很大的便利。有时我们需要计算两个对象之间标签的相似度。目前学习的算法是levenshtein distance 编辑距离算法。

  代码示例:

//标签相似度
    public static double levenshtein(String s1, String s2) {
        
        System.out.println("levenshtein    str1:"+s1+"    str2:"+s2);
        DecimalFormat df=new DecimalFormat("0.00");//java保留两位小数s
        String[] str1 = s1.split("\\|");
        String[] str2 = s2.split("\\|");
        // 计算两个字符串的长度。
        int len1 = str1.length;
        int len2 = str2.length;
        // 建立上面说的数组,比字符长度大一个空间
        int[][] dif = new int[len1 + 1][len2 + 1];
        // 赋初值,步骤B。
        for (int a = 0; a <= len1; a++) {
            dif[a][0] = a;
        }
        for (int a = 0; a <= len2; a++) {
            dif[0][a] = a;
        }
        // 计算两个字符是否一样,计算左上的值
        int temp;
        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                if (str1[i - 1] == str2[j - 1]) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                // 取三个值中最小的
                dif[i][j] = min(dif[i - 1][j - 1] + temp, dif[i][j - 1] + 1, dif[i - 1][j] + 1);

            }
        }
        // 取数组右下角的值,同样不同位置代表不同字符串的比较
        // System.out.println("差异步骤:" + dif[len1][len2]);
        // 计算相似度
        double similarity = 1 - (double) dif[len1][len2] / Math.max(str1.length, str2.length);

        similarity = Double.parseDouble(df.format(similarity));
        
        return similarity;
    }
    
    private static int min(int a, int b, int c) {
        int min = a < b ? a : b;
        return min < c ? min : c;
    }