我開發了一些基於TF * IDF的java程序來計算餘弦相似度。它工作得很好。但有一個問題.... :(java餘弦相似度問題
例如: 如果我有以下兩個矩陣,我要計算餘弦相似度它不起作用爲行長度不
doc 1
1 2 3
4 5 6
doc 2
1 2 3 4 5 6
7 8 5 2 4 9
相同如果行和colums的長度是相同的,然後我的程序工作得很好,但它沒有,如果行和列不在相同的長度。
任何提示???
我開發了一些基於TF * IDF的java程序來計算餘弦相似度。它工作得很好。但有一個問題.... :(java餘弦相似度問題
例如: 如果我有以下兩個矩陣,我要計算餘弦相似度它不起作用爲行長度不
doc 1
1 2 3
4 5 6
doc 2
1 2 3 4 5 6
7 8 5 2 4 9
相同如果行和colums的長度是相同的,然後我的程序工作得很好,但它沒有,如果行和列不在相同的長度。
任何提示???
我不知道你的實現,但cosine distance的兩個向量等於這些向量的歸一化點積。
兩個矩陣的點積可以表示爲a。 b = a T b。因此,如果矩陣具有不同的長度,則不能用點積來標識餘弦。
現在使用標準的TF * IDF方法時,矩陣中的術語應該由term, document
索引,因此任何未出現在文檔中的術語在矩陣中應顯示爲零。
現在你的設置方式似乎表明你的兩個文檔有兩個不同的矩陣。我不確定這是否是您的意圖,但似乎不正確。
另一方面,如果你的矩陣之一應該是你的查詢,那麼它應該是一個向量而不是矩陣,以便轉置產生正確的結果。
TF-IDF的完整解釋如下:
好吧,在經典的TF-IDF你構建一個術語文檔矩陣a
。矩陣a
中的每個值的特徵爲 i,j其中i
是該術語並且j
是該文件。該值是本地,全局和歸一化權重的組合(儘管如果您規範化文檔,則歸一化權重應爲1)。因此,一個 I,J = F I,J * d/d 我,其中f I,J是字i
在DOC j
頻率,D
是文檔尺寸,和d 我是其中包含術語i
的文檔的數量。
您的查詢是指定爲0的術語的向量。對於您的查詢中的每個術語b i,q參考查詢q
的術語i
。 b i,q = f i,q其中f i,q是查詢q
中的術語i
的頻率。在這種情況下,每個查詢都是一個向量,多個查詢形成一個矩陣。
然後,我們可以計算每個單位向量,以便當我們取得點積時,它將產生正確的餘弦。爲了實現單位矢量,我們將矩陣a
和查詢b
除以它們的Frobenius norm。
最後,我們可以通過對給定查詢採用向量b
的轉置來執行餘弦距離。因此每個計算一個查詢(或向量)。這表示爲b T a。最終結果是一個向量,每個術語的得分越高,得分越高表示文檔等級越高。
簡單的java餘弦相似
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;
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);
}
謝謝您的回答。是的,我的第一個矩陣是查詢。什麼是差異。查詢和向量之間?它們不是幾乎一樣嗎?我使用一個文檔作爲查詢,第二個作爲目標。這就是我分別爲目標計算tf * idf和爲查詢計算tf * idf的原因。我不能使用transponse因爲我不知道確切的列和行數。這只是一個例子:)問題。你能解釋一下我該怎麼解決我的問題?我應該爲查詢和目標創建一個tf * idf嗎?如果是,那麼我將如何計算餘弦? – user238384 2010-02-23 04:12:18
我會嘗試添加到我的答案 – tzenes 2010-02-23 04:49:56
@agazerboy是否足夠或您需要更多的解釋? – tzenes 2010-02-27 21:31:41