2015-09-07 64 views
1

據我所知,Lucene是一個反向索引系統,它的強大之處在於它只會將查詢與僅與至少匹配令牌的文檔進行比較。餘弦與Lucene的相似度僅適用於匹配的文檔

與查詢與每個文檔進行比較(即使那些沒有提及查詢中存在的任何標記)的樸素方法相比,這是一個很大的好處。

例如,如果我有索引的文件:

D1: "Hello world said the guy" 
D2: "Hello, what a beautiful world" 
D3: "random text" 

當我看到它,搜索查詢:「世界,你好」,只會看入索引的文檔D1和D2和跳過D3,這可以節省時間。

這是正確的嗎?

現在,我試圖計算文件之間的餘弦相似度。輸入的查詢將是一個文檔,輸出應該是餘弦分數。這是一個介於0和1之間的數字。

我已經閱讀了一些計算餘弦相似度的方法,但他們都通過比較每個文檔的術語向量來做到這一點。例如this博客中提到以下幾點:

如果你確實需要的文檔之間的餘弦相似,你必須 啓用源字段項向量,並利用它們來計算 角度。問題是,這不能很好地擴展,你會 需要與幾乎所有其他文件計算角度。

SO answers似乎說是相同的:

  • 迭代所有文檔IDS,0至maxDoc();
  • 是不是有沒有辦法只計算匹配查詢,讓這個回報比分爲文檔文件的餘弦相似?

    作爲一個附註, 我確實讀到TFIDFSimilarity接近,我相信VSM部分正是我所需要的,但是這部分似乎已經在Lucene實用評分函數中消失了。我不知道如何才能「變換」這個相似性類,最後只剩下純餘弦相似性。

    所以我的問題的概括:

    1. 是我的逆指標如何節省時間,正確的認知?

    2. 是否有辦法只計算 實際上與其中一個令牌匹配的文檔的餘弦相似度,而不是所有文檔?

    3. 我可以使用/變換TFIDFSimilarity類來結束 純餘弦相似度嗎?

    回答

    0
    1. 這很大程度上取決於您如何制定查詢。如果您制定了一個布爾查詢,您可以指定查詢的哪些條款必須位於返回的文檔中。這是通過使用BoolenClause.Occur.MUST完成的。

    2. 您可以通過擴展TFIDFSimilarity來編寫自己的相似度,但您可能會注意到Lucene的實際評分基於餘弦相似度。在該公式中,queryNorm(q)和norm(t,d)形成餘弦相似度的分母,並且求和是查詢向量和文檔向量的點積。

    提示:您可以形成示例查詢並使用explain()來查看評分的詳細信息。

    +0

    與(2)相關,請問這個查詢會在每個索引的文檔中查找並計算得分,還是隻考慮實際上具有該特定詞的文檔。我的問題是針對Lucene的性能。與(3)相關我注意到TFIDFSimilarity基於餘弦sim,但似乎只有queryNorm(q)是餘弦sim的一部分(https://lucene.apache.org/core/4_0_0/core/org/ apache/lucene/search/similarities/TFIDFSimilarity.html)所以人們必須擺脫規範和coord()部分? 另外(3),術語向量如何與此評分相關? – DJanssens

    +0

    我對性能不太確定,但事實是返回的答案肯定包含關鍵字(如果您正確地制定了您的查詢),所以查看確實包含該術語的文檔是合理的。 queryNorm是餘弦相似度的分母,tf * idf是分子。我再次強烈建議你使用explain()。我有一個非常類似的問題,並解釋()幫助了我很多。嘗試形成一個簡單的查詢並調用解釋。你會看到coord()的值爲1. – vahid

    +0

    我沒有得到你所說的術語向量的含義。在餘弦相似性中,您有一個查詢向量和一個文檔向量。這些向量中的每一個都由術語的權重組成。術語的權重基於術語的tf和idf來計算 – vahid