2010-09-01 45 views
1

我想在Java中使用/實現向量空間模型算法,以基於其關鍵字得到兩個人之間的相似度得分。所以我有以下類:Java中的向量空間模型算法,以獲得兩個人之間的相似度得分

人 - 有一個關鍵字列表;

關鍵字 - String text; 整數分數;

關鍵字分數是提到該人對該關鍵字作出的次數。

關於如何在Java中實現這一點的任何建議?

Regards

+2

是否有任何特殊原因需要您自己實現Java中的VSM?就我個人而言,我會用WEKA來做這樣的事情。 – adam 2010-09-01 21:10:31

+1

作業,對吧? – 2010-09-01 23:22:46

+0

重做輪子的原因比作業還要多。我不認爲這個問題完全是不合理的。 – 2010-09-02 02:46:44

回答

4

它很容易。

  1. 首先,您應該爲代表關鍵字的每個人創建矢量表示,示例Map。我想推薦http://en.wikipedia.org/wiki/Cosine_similarity

所以,現在真正的代碼:

static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) { 
      Set<String> both = Sets.newHashSet(v1.keySet()); 
      both.retainAll(v2.keySet()); 
      double sclar = 0, norm1 = 0, norm2 = 0; 
      for (String k : both) sclar += v1.get(k) * v2.get(k); 
      for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k); 
      for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k); 
      return sclar/Math.sqrt(norm1 * norm2); 
    } 
+1

此外,'both.removeAll'應該是'both.retainAll',因爲我們想要找到兩個集合v1和v2的交集 – stepthom 2013-03-21 13:25:46

0

我認爲這是在上面的示例代碼中的錯誤。正確的代碼如下。

static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) { 
     Set<String> both = Sets.newHashSet(v1.keySet()); 
     both.removeAll(v2.keySet()); 

     double sclar = 0, norm1 = 0, norm2 = 0; 

     /* We need to perform cosine similarity only on words that 
     * exist in both lists */ 
     for (String k : both) { 
      sclar += v1.get(k) * v2.get(k); 
      norm1 += v1.get(k) * v1.get(k); 
      norm2 += v2.get(k) * v2.get(k); 
     } 
     return sclar/Math.sqrt(norm1 * norm2); 
} 
+1

實際上,yura是正確的。當計算'norm1'和'norm2'時,你需要分別循環每個映射。這樣,我們可以考慮到兩個字符串之間的不匹配。否則,相似性只會計算在共享單詞上,並且sim分數將被錯誤地誇大。 – stepthom 2013-03-21 13:27:18

相關問題