私はInstagramハッシュタグに関する問題に取り組んでいます。ユーザーは、画像を投稿するときにコピーして貼り付けるハッシュタグの「バンドル」を持つことがよくあります。異なるトピックの異なるバンドル。サイズと頻度で複数の配列の共通の共有サブ配列をランク付けする効率的な方法は何ですか?
私は、「庭」、「beautifullawns」、「treesoutside」、「greenlondon」などの「庭からのもの」バンドルを持っているかもしれません。彼らはしばしば20から30のアイテムです。
場合によっては、さまざまなものを保持するためにこれらのいくつかがある場合があります。
私がしたいことは、投稿した過去の画像を見て、使用するタグの束を推薦することです。
は、私は、彼らが以前に使用しているタグの複数のアレイを持っているだろうと実行します。x = ["a", "b", "c", "d", "e"]
y = ["a", "b", "d", "e", "f", "g"]
z = ["a", "c", "d", "e", "f", "h"]
...
私は、これらの配列のエントリの最大の共通サブセットを見つけるしたいと思います。
この場合、最大のサブセットは、これらの3つの中で["a"、 "d"、 "e"]になります。これは、x & y & z
のようなものを使って簡単に達成できます。
[
{bundle: ["a","d","e"], frequency: 3, size: 3},
{bundle: ["e","f"], frequency: 2, size: 2},
{bundle: ["a","b"], frequency: 2, size: 2},
{bundle: ["b","d"], frequency: 2, size: 2},
...
]
:
しかし、私は、タグの最も一般的に使用されるバンドルを表示できるように、検討中のすべてのアレイ内での大きさと頻度に基づいてこれらのサブセットのランキングを作成したいのですが
おそらく、これらのバンドルの最小サイズに制限があり、たとえば2つのアイテムがあります。
私はインデックス作成にElasticsearchを使用していますが、集計でこれを行おうとするのは難しいことが分かりました。そのため、イメージをRubyに引き出してそこでリストを作成しています。
最初のパスとして、これらの配列のすべてをループし、MD5ハッシュキーを一意の識別子として使用して、他の配列のすべてのサブセットを見つけました。しかし、これは結果を制限します。さらにパスを追加すると、このアプローチは非常に非効率的になります。
require 'digest'
x = ["a", "b", "c", "d", "e"]
y = ["a", "b", "d", "e", "f", "g"]
z = ["a", "c", "d", "e", "f", "h"]
def bundle_report arrays
arrays = arrays.collect(&:sort)
working = {}
arrays.each do |array|
arrays.each do |comparison|
next if array == comparison
subset = array & comparison
key = Digest::MD5.hexdigest(subset.join(""))
working[key] ||= {subset: subset, frequency: 0}
working[key][:frequency] += 1
working[key][:size] = subset.length
end
end
working
end
puts bundle_report([x, y, z])
=> {"bb4a3fb7097e63a27a649769248433f1"=>{:subset=>["a", "b", "d", "e"], :frequency=>2, :size=>4}, "b6fdd30ed956762a88ef4f7e8dcc1cae"=>{:subset=>["a", "c", "d", "e"], :frequency=>2, :size=>4}, "ddf4a04e121344a6e7ee2acf71145a99"=>{:subset=>["a", "d", "e", "f"], :frequency=>2, :size=>4}}
第二のパスを追加すると、これが良い結果になる:
def bundle_report arrays
arrays = arrays.collect(&:sort)
working = {}
arrays.each do |array|
arrays.each do |comparison|
next if array == comparison
subset = array & comparison
key = Digest::MD5.hexdigest(subset.join(""))
working[key] ||= {subset: subset, frequency: 0}
working[key][:frequency] += 1
working[key][:size] = subset.length
end
end
original_working = working.dup
original_working.each do |key, item|
original_working.each do |comparison_key, comparison|
next if item == comparison
subset = item[:subset] & comparison[:subset]
key = Digest::MD5.hexdigest(subset.join(""))
working[key] ||= {subset: subset, frequency: 0}
working[key][:frequency] += 1
working[key][:size] = subset.length
end
end
working
end
puts bundle_report([x, y, z])
=> {"bb4a3fb7097e63a27a649769248433f1"=>{:subset=>["a", "b", "d", "e"], :frequency=>2, :size=>4}, "b6fdd30ed956762a88ef4f7e8dcc1cae"=>{:subset=>["a", "c", "d", "e"], :frequency=>2, :size=>4}, "ddf4a04e121344a6e7ee2acf71145a99"=>{:subset=>["a", "d", "e", "f"], :frequency=>2, :size=>4}, "a562cfa07c2b1213b3a5c99b756fc206"=>{:subset=>["a", "d", "e"], :frequency=>6, :size=>3}}
はあなたが大規模なサブセットの順位を確立するための効率的な方法を提案することはできますか?
ありがとうフランキー!私は思考を持っていると私は返信します。本当にありがとうございます。 – stef