Java程式碼實現餘弦相似度演算法比較兩字串相似度
阿新 • • 發佈:2018-12-19
因工作需要比較兩個兩個字串的相似度比較,由於最短編輯距離演算法不符合需求,就又找其他演算法,在網上看到了另一個演算法:餘弦相似度演算法。於是學習了一下,並寫篇部落格儲存,以便學習以及日後用到。
程式碼如下:
import java.util.HashMap import java.util.Map; import java.util.Set; /* * 計算兩個字串(英文字元)的相似度,簡單的餘弦計算,未添權重 */ public class AnotherCompare { Map<Character, int[]> vectorMap = new HashMap<Character, int[]>(); int[] tempArray = null; public AnotherCompare(String string1, String string2) { for (Character character1 : string1.toCharArray()) { //拆解為向量 if (vectorMap.containsKey(character1)) { //該字元是否已經存在map中 vectorMap.get(character1)[0]++; //key對應的值是一個數組,第一個字串的字元出現次數儲存在陣列第一個位置 } else { tempArray = new int[2]; tempArray[0] = 1; //如果字元沒有出現過,就新增到map中,陣列第一個位置設為1 tempArray[1] = 0; vectorMap.put(character1, tempArray); } } for (Character character2 : string2.toCharArray()) { //拆解為向量 if (vectorMap.containsKey(character2)) { vectorMap.get(character2)[1]++; } else { tempArray = new int[2]; tempArray[0] = 0; tempArray[1] = 1; //第二個字串的字元出現次數儲存在陣列的第二個位置 vectorMap.put(character2, tempArray); } } /* * 到最後,map裡的key對應的陣列,第一個位置儲存的是第一個字串字元對應的向量,第二個位置儲存的是第二個字串字元對應的向量。 */ } // 求餘弦相似度 public double sim() { //分子分母相除 double result = 0; result = pointMulti(vectorMap) / sqrtMulti(vectorMap); return result; //餘弦度結果返回,因為是餘弦,返回結果越大,夾角越小,兩個向量方向越接近,即兩個字串越相似 } //求平方根 private double sqrtMulti(Map<Character, int[]> paramMap) { double result = 0; result = squares(paramMap); //先求平方和 result = Math.sqrt(result); //再開根號,就是求模 return result; } // 求平方和,分母上,向量求模的平方 private double squares(Map<Character, int[]> paramMap) { double result1 = 0; double result2 = 0; Set<Character> keySet = paramMap.keySet(); for (Character character : keySet) { int temp[] = paramMap.get(character); //獲取key對應的值--陣列 result1 += (temp[0] * temp[0]); //temp[0]儲存的是第一個字串對應的向量 result2 += (temp[1] * temp[1]); //temp[1]儲存的是第二個字串對應的向量 } return result1 * result2; } // 點乘法,在分子上,向量相乘 private double pointMulti(Map<Character, int[]> paramMap) { double result = 0; Set<Character> keySet = paramMap.keySet(); //返回map中所有key值的列表,這裡的set,也可以用list代替吧 for (Character character : keySet) { //儲存的key值都是不重複的 int temp[] = paramMap.get(character); //獲取key對應的值 result += (temp[0] * temp[1]); } return resul }
原理網上都有,這個程式碼也是網上的程式碼,我只是學習,加上了自己理解的註釋。如有不足,請多指教。