2012-02-03 56 views
5

我對使用Solr建模餘弦相似度算法的可能方法感興趣。例如,我有分配了矢量的項目:Solr/Lucene中可以模擬餘弦相似度嗎?

items = [ 
    { id: 1, vector: [0,0,0,2,3,0,0] }, 
    { id: 2, vector: [0,1,0,1,5,0,0] }, 
    { id: 3, vector: [2,3,0,0,0,1,0] }, 
    { id: 4, vector: [1,2,4,6,5,0,0] } 
] 

並且其他人需要對其進行排名的搜索向量。

目前,我在由紅寶石上運行的所有項目並賦予它們對輸入向量的秩造型這一點。這裏的餘弦相似度的實現我使用:

module SimilarityCalculator 

    def self.get_similarity(vector1, vector2) 
    dp = dot_product(vector1, vector2) 
    nm = normalize(vector1) * normalize(vector2) 
    dp/nm 
    end 

    private 

    def self.dot_product(vector1, vector2) 
    sum = 0.0 
    vector1.each_with_index { |val, i| sum += val * vector2[i] } 
    sum 
    end 

    def self.normalize(vector) 
    Math.sqrt(vector.inject(0.0) { |m,o| m += o**2 }) 
    end 

end 

之後,得到一個排名列表,我會做類似如下:

ranked = [] 
search_vector = [1,0,0,3,5,0,0] 
items.each do |item| 
    rank = SimilarityCalculator.get_similarity(search_vector, item.vector) 
    { id: item.id, rank: rank } 
end 

我不知道有足夠的瞭解Solr的認識這將如何建模或即使可以,但我想我會把它扔在那裏。

+0

http://stackoverflow.com/a/1849270/272861 – Mikos 2012-02-03 03:54:46

回答

1

Lucene的已經使用了餘弦相似模型,所以真正的問題是:你可以映射你的載體爲Lucene的載體?你可以刪除Lucene做的你不想要的規範等嗎?

你總是可以編寫自己的得分和分析功能,所以如果你願意做一些編碼,答案是明確的「是」。儘管如此,這可能需要更多的工作。

對於一個選項,可能會讓你的一部分,但不需要任何編碼:將每個維度翻譯成單詞「dim_n」,並重復它(或提高它),但很多次是向量在該維度。例如:

[1,2,0,1] ==> "dim_1 dim_2 dim_2 dim_4" 

如果你的載體都是大致相同的尺寸和整個尺寸均勻分佈,這可能是一個非常好的近似。

如果你告訴我們更多關於這個問題(如你真的需要給Lucene的向量作爲輸入,或者你可以給它發短信?),我們也許能夠找到更好的解決方案。

+0

我肯定需要給它載體,雖然我可能會看到類似上面的工作文字翻譯方法。我不介意做一些編碼,但是我在一個Ruby平臺上,並且真的只有Solr在我手中,所以它需要通過Solr API表達。 – 2012-02-06 21:32:30

+0

好了,看看Lucene的[計分公式(http://lucene.apache.org/java/3_0_0/api/core/org/apache/lucene/search/Similarity.html),並決定是否文本方法足夠接近。 Solr可以讓你[編寫函數查詢](http://wiki.apache.org/solr/FunctionQuery)而不用改變源代碼,這是另一種選擇。 – Xodarap 2012-02-06 22:50:52