文本求相似度

最长公共字符子序列

package demo;

public class LCS {

    private final static int maxn=50;

    public static double getSimilarity(String a,String b){
        int m=a.length(),n=b.length();
        int c[][]=new int[maxn][maxn];
        for(int i=1;i<=m;i++) {
            for(int j=1;j<=n;j++) {
                if(a.charAt(i-1)==b.charAt(j-1)) {
                    c[i][j]=c[i-1][j-1]+1;
                }
                else if(c[i-1][j]>=c[i][j-1]) {
                    c[i][j]=c[i-1][j];
                }
                else {
                    c[i][j]=c[i][j-1];
                }
            }
        }
        return 2.0*c[m][n]/(m+n);
    }
}

最小编辑距离


package demo;

public class Levenshtein {

    private final static int maxn=50;

    public static double getSimilarity(String a,String b){
        int[][] dp=new int[maxn][maxn];
        int cost=0;
        int len1=a.length(),len2=b.length();
        for(int i=0;i<=len1;i++)
            dp[i][0]=i;
        for(int i=0;i<=len2;i++)
            dp[0][i]=i;
        for(int i=1;i<=len1;i++)
        {
            for(int j=1;j<=len2;j++)
            {
               if(a.charAt(i-1)==b.charAt(j-1))
                   cost=0;
               else
                   cost=1;
               dp[i][j]=Math.min(dp[i-1][j]+1,Math.min(dp[i][j-1]+1,dp[i-1][j-1]+cost));
            }
        }
        return 1-(dp[len1][len2]*1.0/Math.max(len1,len2));
    }
}

余弦向量求相似度

我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, …])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为0度,意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

余弦值越接近1,就表明夹角越接近0度,也就是两个向量越相似,这就叫”余弦相似性”。所以,上面的句子A和句子B是很相似的,事实上它们的夹角大约为20.3度。
由此,我们就得到了”找出相似文章”的一种算法:
1. 使用TF-IDF算法,找出两篇文章的关键词
2. 每篇文章各取出若干个关键词(比如20个),合并成一个集合,计算每篇文章对于这个集合中的词的词频(为了避免文章长度的差异,可以使用相对词频);
3. 生成两篇文章各自的词频向量;
4. 计算两个向量的余弦相似度,值越大就表示越相似。

package demo;

import java.util.Map;
import java.util.Map.Entry;

public class CalculateSimilarity {

    public static double getSimilarity(Map a,Map b){
        init(a,b);
        double x=0.0,y=0.0,z=0.0;
        Object[] arr1=a.values().toArray(),arr2=b.values().toArray();
        int len=arr1.length;
        for(int i=0;idouble sim=x/(Math.sqrt(y)*Math.sqrt(z));
        return sim;

    }

    public static void init(Map a,Map b){
        for(Entry e:a.entrySet()){
            Character key=e.getKey();
            if(b.containsKey(key)==true){
                continue;
            }
            else{
                b.put(key, 0.0);
            }
        }
        for(Entry e:b.entrySet()){
            Character key=e.getKey();
            if(a.containsKey(key)==true){
                continue;
            }
            else{
                a.put(key, 0.0);
            }
        }
    }

}
package demo;

import java.util.Map;
import java.util.TreeMap;

public class SimilarityOfContent {

    public static Map transToWordVector(String content){
        content=FilterTools.keepChinese(content);
        Map m=new TreeMap();
        int len=content.length();
        for(int i=0;iif(m.containsKey(ch)==false){
                m.put(ch, 1.0);
            }
            else{
                Double num=m.get(ch);
                m.put(ch,num+1);
            }
        }
        return m;
    }
}

你可能感兴趣的:(算法基础,阿里)