package hi;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Created by bee on 17/4/10.
*/
public class Vsm {
//用余弦系数计算相似度的方法,方法传了两个键值对,String是字符串,Double是浮点型数据
//键值对就是是一个键对应一个值,就像一把钥匙对应一扇门,钥匙就是键,门里面的东西就是值
public static double calCosSim(Map<String, Double> v1, Map<String, Double>
v2) {
//分别声明了内积,v1对象权值平方的代数和,v2对象权值平方的代数和,余弦系数
double sclar = 0.0,norm1=0.0,norm2=0.0,similarity=0.0;
//
Set<String> v1Keys = v1.keySet();
Set<String> v2Keys = v2.keySet();
Set<String> both= new HashSet<>();
both.addAll(v1Keys);
both.retainAll(v2Keys);
//找出相同的字符,并打印在控制台
System.out.println(both);
//计算内积,就是相同的字符权值积的代数和
for (String str1 : both) {
sclar += v1.get(str1) * v2.get(str1);
}
//计算对象v1里面字符的权值平方的代数和
for (String str1:v1.keySet()){
norm1+=Math.pow(v1.get(str1),2);
}
//计算对象v2里面字符的权值平方的代数和
for (String str2:v2.keySet()){
norm2+=Math.pow(v2.get(str2),2);
}
//内积除以两对象字符权值平方的代数和的积开发后的值,计算出了余弦系数
//系数越大相似度越高
similarity=sclar/Math.sqrt(norm1*norm2);
//把内积打印在控制台
System.out.println("sclar:"+sclar);
//打印对象v1里面字符的权值平方的代数和
System.out.println("norm1:"+norm1);
//打印对象v2里面字符的权值平方的代数和
System.out.println("norm2:"+norm2);
//打印余弦系数
System.out.println("similarity:"+similarity);
//把余弦系数返回给该方法的调用者
return similarity;
}
public static void main(String[] args) {
//上述方法中的v1对象
Map<String, Double> m1 = new HashMap<>();
//前面的hello是字符,1.0是权值,下面也是
m1.put("Hello", 1.0);
m1.put("css", 2.0);
m1.put("Lucene", 3.0);
//上述方法中的v2对象
Map<String, Double> m2 = new HashMap<>();
m2.put("Hello", 1.0);
m2.put("Word", 2.0);
m2.put("Hadoop", 3.0);
m2.put("java", 4.0);
m2.put("html", 1.0);
m2.put("css", 2.0);
//调用计算余弦系数的方法,similarity就是余弦系数
double similarity = calCosSim(m1, m2);
}
}