2009-12-31 82 views
4

我正在使用TF/IDF來計算相似度。例如,如果我有以下兩個文檔。tf idf相似度

Doc A => cat dog 
Doc B => dog sparrow 

這是正常的它的相似性是50%,但是當我計算它的TF/IDF。它是作爲按照

TF值文件甲

dog tf = 0.5 
cat tf = 0.5 

TF爲文件B值

dog tf = 0.5 
sparrow tf = 0.5 
進行DOC

IDF值甲

dog idf = -0.4055 
cat idf = 0 

IDF值文件乙

dog idf = -0.4055 (without +1 formula 0.6931) 
sparrow idf = 0 

TF爲文件/ IDF值A

0.5x-0.4055 + 0.5x0 = -0.20275 

TF/IDF值文件乙

0.5x-0.4055 + 0.5x0 = -0.20275 

現在看起來像有-0.20275相似。是嗎? 或者我錯過了什麼? 或者是下一步的任何一種?請告訴我,我也可以計算出來。

我用TF/IDF公式,維基百科提到

+0

您是否在使用Apache Mahout來計算它?如果是的話,請讓我知道需要採取的步驟。我必須開發一個原型來使用Apache Mahout來計算TF IDF。 junaid_surqyahoo.co.in – 2012-01-04 10:16:44

回答

17

讓我們來看看,如果我得到你的問題: 你要計算這兩個文件之間的TF/IDF相似度:

Doc A: cat dog 

Doc B: dog sparrow 

我認爲這是你的整個語料庫。因此|D| = 2 對於所有單詞,Tfs確實是0.5。 要計算'dog'的IDF,請參考log(|D|/|d:dog in d| = log(2/2) = 0 同樣,'cat'和'sparrow'的IDF是log(2/1) = log(2) =1 (我使用2作爲日誌基礎以使其更容易)。

因此, '狗' 的TF/IDF值將是0.5×0 = 0 '貓' 和 '麻雀' 的TF/IDF值將是0.5×1 = 0.5

爲了測量(貓,麻雀,狗)空間中的矢量之間的餘弦 : (0.5,0,0)和(0,0.5,0)並且獲得結果0.

總結:

  1. 您在IDF CA中有錯誤lculations。
  2. 此錯誤會創建錯誤的TF/IDF值。
  3. 維基百科的文章沒有很好地解釋TF/IDF的相似性。我喜歡Manning, Raghavan & Schütze's explanation好多了。
+0

謝謝Yuval! ! ! 你讓我的生活變得簡單:) 有兩個問題1,我正在使用自然日誌。我無法在Java中找到任何log2函數,但我會解決它。 第二個問題更重要。我無法理解你如何與餘弦相似?當tf/idf表示50%的相似性時,爲什麼餘弦在說0%? – user238384 2009-12-31 21:39:23

+0

不客氣。我相信使用自然對數更好,它使用基2更容易解釋。讓我們澄清餘弦相似度: TF/IDF純粹是一種表示形式:可以將一個字計數向量轉換爲一個TF/IDF值向量。餘弦相似度是兩個歸一化向量之間的標量乘法;載體可以是原始計數或由TF/IDF轉換。在你說明的情況下,標量乘法將爲零,因爲我們要麼只有一個向量出現單詞,要麼出現零分的常見單詞('狗')。 HTH。 – 2010-01-01 10:53:40

+0

謝謝Yuval,如果我使用自然日誌,那麼我的Tf/Idf值與您的不同。如果我使用log2,那麼我認爲我得到正確的結果。你能告訴我LSI和向量空間有什麼區別嗎?對不起,這聽起來啞巴的問題。如果你可以給我一個很好的教程如何實施LSI。這將是很大的幫助 – user238384 2010-01-01 23:31:17

0

我認爲你必須採取ln而不是日誌。

0
def calctfidfvec(tfvec, withidf): 
    tfidfvec = {} 
    veclen = 0.0 

    for token in tfvec: 
     if withidf: 
      tfidf = (1+log10(tfvec[token])) * getidf(token) 
     else: 
      tfidf = (1+log10(tfvec[token])) 
     tfidfvec[token] = tfidf 
     veclen += pow(tfidf,2) 

    if veclen > 0: 
     for token in tfvec: 
      tfidfvec[token] /= sqrt(veclen) 

    return tfidfvec 

def cosinesim(vec1, vec2): 
    commonterms = set(vec1).intersection(vec2) 
    sim = 0.0 
    for token in commonterms: 
     sim += vec1[token]*vec2[token] 

    return sim