5

Solr を使用してコサイン類似度アルゴリズムをモデル化する方法に興味があります。ベクトルが割り当てられたアイテムがあります。たとえば、次のようになります。

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] }
]

そして、他のものをランク付けする必要がある検索ベクトル。

現在、すべてのアイテムを実行し、入力ベクトルに対してランクを割り当てることにより、これを Ruby でモデル化しています。私が使用しているコサイン類似度の実装は次のとおりです。

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 については、これがどのようにモデル化されるのか、あるいはそれが可能かどうかを知るのに十分な知識はありませんが、そこに放り出そうと思いました。

4

1 に答える 1

1

Lucene は既にコサイン類似度モデルを使用しているため、実際の問題は、ベクターを Lucene のベクターにマッピングできるかどうかです。そして、あなたが望まないLuceneのノームなどを削除できますか?

独自のスコアリング関数と分析関数をいつでも作成できるため、コーディングを行う意思がある場合、答えは明確に「はい」です。ただし、これには必要以上の作業が必要になる場合があります。

方法の一部を取得する可能性がありますが、コーディングを必要としないオプションの場合: 各次元を単語 "dim_n" に変換し、それを繰り返します (またはブーストします)。ただし、その次元でのベクトルの大きさは何回でもあります。例えば:

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

ベクトルがすべてほぼ同じサイズで、次元全体に均等に分散されている場合、これは非常に適切な近似値である可能性があります。

問題について詳しく教えていただければ (たとえば、本当に Lucene ベクトルを入力として与える必要がありますか、それともテキストを与えることができますか?)、より良い解決策を見つけることができるかもしれません。

于 2012-02-03T18:09:43.817 に答える