2012-02-03 11 views
5

Jestem zainteresowany możliwymi sposobami modelowania algorytmu podobieństwa cosinusów za pomocą Solr. Mam elementy, którym przypisano wektor, na przykład:Czy można modelować podobieństwo cosinus w 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] } 
] 

I wektor wyszukiwania, do którego inne muszą być uszeregowane.

Obecnie modeluję to w rubinach, przeszukując wszystkie pozycje i przypisując im pozycję względem wektora wejściowego. Oto realizacja cosinus podobieństwa Używam:

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 

Następnie, aby uzyskać ranking chciałbym zrobić coś jak następuje:

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 

Nie wystarczy wiedzieć o Solr wiedzieć jak by to było wymodelowane, a nawet gdyby mogło, ale myślałem, że je tam wyrzucę.

+0

http://stackoverflow.com/a/1849270/272861 – Mikos

Odpowiedz

1

Lucene stosuje już model podobieństwa kosinusów, więc prawdziwe pytanie brzmi: czy możesz odwzorować swoje wektory na wektory Lucene? Czy możesz usunąć normowanie itp., Które Lucene robi, czego nie chcesz?

Zawsze możesz napisać własne funkcje oceny i analizy, więc jeśli chcesz napisać kod, odpowiedz brzmi "tak". Może to wymagać więcej pracy, niż chcesz.

Dla opcji, która może Ci trochę przeszkadzać, ale nie wymaga żadnego kodowania: przetłumacz każdy wymiar na słowo "dim_n" i powtórz (lub zwiększ), jednak wiele razy to wielkość wektora w tym wymiarze . Na przykład:

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

Jeśli wektory są w przybliżeniu tej samej wielkości i równomiernie rozłożone wymiarach, to może być bardzo dobrym przybliżeniem.

Jeśli powiesz nam więcej o problemie (np. Czy naprawdę musisz podać wektory Lucene jako dane wejściowe lub czy możesz podać tekst?), Być może będziemy w stanie znaleźć lepsze rozwiązania.

+0

Zdecydowanie potrzebuję dać mu wektory, chociaż potencjalnie mógłbym zobaczyć coś w rodzaju podejścia do tłumaczenia tekstu powyżej. Nie mam nic przeciwko temu, że robię kodowanie, ale jestem na platformie ruby ​​i mam do dyspozycji tylko Solr, więc musi to być coś, co mogę wyrazić przez interfejs API Solr. –

+0

Cóż, spójrz na formułę Lucene'a (http://lucene.apache.org/java/3_0_0/api/core/org/apache/lucene/search/Similarity.html) i zdecyduj, czy metoda tekstowa będzie podejdź wystarczająco blisko. Solr pozwala ci [pisać zapytania funkcji] (http://wiki.apache.org/solr/FunctionQuery) bez zmiany źródła, co jest inną opcją. – Xodarap

Powiązane problemy