2010-09-01 65 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

相关问题