|
- namespace :post_similarity do
- desc '関聯投稿テーブル作成'
- task calc: :environment do
- dot = -> a, b { (a.keys & b.keys).sum { |k| a[k] * b[k] } }
- norm = -> v { Math.sqrt(v.values.sum { |e| e * e }) }
- cos = -> a, b do
- na = norm.(a)
- nb = norm.(b)
- if na.zero? || nb.zero?
- 0.0
- else
- dot.(a, b) / na / nb
- end
- end
-
- posts = Post.includes(:tags).to_a
- posts.each_with_index do |post, i|
- existence_of_tags = post.tags.index_with(1)
- ((i + 1)...posts.size).each do |j|
- target_post = posts[j]
- existence_of_target_tags = target_post.tags.index_with(1)
- PostSimilarity.find_or_initialize_by(post:, target_post:).tap { |ps|
- ps.cos = cos.(existence_of_tags, existence_of_target_tags)
- }.save!
- end
- end
- end
- end
|