我想在Java中使用/實現向量空間模型算法,以基於其關鍵字得到兩個人之間的相似度得分。所以我有以下類:Java中的向量空間模型算法,以獲得兩個人之間的相似度得分
人 - 有一個關鍵字列表;
關鍵字 - String text; 整數分數;
關鍵字分數是提到該人對該關鍵字作出的次數。
關於如何在Java中實現這一點的任何建議?
Regards
我想在Java中使用/實現向量空間模型算法,以基於其關鍵字得到兩個人之間的相似度得分。所以我有以下類:Java中的向量空間模型算法,以獲得兩個人之間的相似度得分
人 - 有一個關鍵字列表;
關鍵字 - String text; 整數分數;
關鍵字分數是提到該人對該關鍵字作出的次數。
關於如何在Java中實現這一點的任何建議?
Regards
它很容易。
所以,現在真正的代碼:
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);
}
此外,'both.removeAll'應該是'both.retainAll',因爲我們想要找到兩個集合v1和v2的交集 – stepthom 2013-03-21 13:25:46
我認爲這是在上面的示例代碼中的錯誤。正確的代碼如下。
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);
}
實際上,yura是正確的。當計算'norm1'和'norm2'時,你需要分別循環每個映射。這樣,我們可以考慮到兩個字符串之間的不匹配。否則,相似性只會計算在共享單詞上,並且sim分數將被錯誤地誇大。 – stepthom 2013-03-21 13:27:18
是否有任何特殊原因需要您自己實現Java中的VSM?就我個人而言,我會用WEKA來做這樣的事情。 – adam 2010-09-01 21:10:31
作業,對吧? – 2010-09-01 23:22:46
重做輪子的原因比作業還要多。我不認爲這個問題完全是不合理的。 – 2010-09-02 02:46:44