recommendable 2.0.0 → 2.0.0.20121011
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,6 +45,7 @@ module Recommendable
|
|
45
45
|
relevant_user_ids = Recommendable.config.ratable_classes.inject([]) do |memo, klass|
|
46
46
|
liked_set = Recommendable::Helpers::RedisKeyMapper.liked_set_for(klass, user_id)
|
47
47
|
disliked_set = Recommendable::Helpers::RedisKeyMapper.disliked_set_for(klass, user_id)
|
48
|
+
|
48
49
|
item_ids = Recommendable.redis.sunion(liked_set, disliked_set)
|
49
50
|
|
50
51
|
unless item_ids.empty?
|
@@ -76,18 +77,37 @@ module Recommendable
|
|
76
77
|
def update_recommendations_for(user_id)
|
77
78
|
nearest_neighbors = Recommendable.config.nearest_neighbors || Recommendable.config.user_class.count
|
78
79
|
Recommendable.config.ratable_classes.each do |klass|
|
79
|
-
|
80
|
+
rated_sets = [
|
81
|
+
Recommendable::Helpers::RedisKeyMapper.liked_set_for(klass, user_id),
|
82
|
+
Recommendable::Helpers::RedisKeyMapper.disliked_set_for(klass, user_id),
|
83
|
+
Recommendable::Helpers::RedisKeyMapper.hidden_set_for(klass, user_id),
|
84
|
+
Recommendable::Helpers::RedisKeyMapper.bookmarked_set_for(klass, user_id)
|
85
|
+
]
|
86
|
+
temp_set = Recommendable::Helpers::RedisKeyMapper.temp_set_for(Recommendable.config.user_class, user_id)
|
87
|
+
similarity_set = Recommendable::Helpers::RedisKeyMapper.similarity_set_for(user_id)
|
80
88
|
recommended_set = Recommendable::Helpers::RedisKeyMapper.recommended_set_for(klass, user_id)
|
81
|
-
|
89
|
+
most_similar_user_ids = Recommendable.redis.zrevrange(similarity_set, 0, nearest_neighbors - 1)
|
90
|
+
least_similar_user_ids = Recommendable.redis.zrange(similarity_set, 0, nearest_neighbors - 1)
|
82
91
|
|
83
|
-
|
92
|
+
# Get likes from the most similar users
|
93
|
+
sets_to_union = most_similar_user_ids.inject([]) do |sets, id|
|
84
94
|
sets << Recommendable::Helpers::RedisKeyMapper.liked_set_for(klass, id)
|
85
95
|
end
|
86
96
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
97
|
+
# Get dislikes from the least similar users
|
98
|
+
least_similar_user_ids.inject(sets_to_union) do |sets, id|
|
99
|
+
sets << Recommendable::Helpers::RedisKeyMapper.disliked_set_for(klass, id)
|
100
|
+
end
|
101
|
+
|
102
|
+
return if sets_to_union.empty?
|
103
|
+
|
104
|
+
# SDIFF rated items so they aren't recommended
|
105
|
+
Recommendable.redis.sunionstore(temp_set, sets_to_union)
|
106
|
+
item_ids = Recommendable.redis.sdiff(temp_set, rated_sets)
|
107
|
+
scores = item_ids.map { |id| [predict_for(user_id, klass, id), id] }
|
108
|
+
scores.each do |s|
|
109
|
+
Recommendable.redis.zadd(recommended_set, s[0], s[1])
|
110
|
+
end
|
91
111
|
end
|
92
112
|
|
93
113
|
true
|
@@ -13,16 +13,20 @@ module Recommendable
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def liked_by_set_for(klass, id)
|
16
|
-
[Recommendable.config.redis_namespace, klass.to_s.tableize, id,
|
16
|
+
[Recommendable.config.redis_namespace, klass.to_s.tableize, id, 'liked_by'].compact.join(':')
|
17
17
|
end
|
18
18
|
|
19
19
|
def disliked_by_set_for(klass, id)
|
20
|
-
[Recommendable.config.redis_namespace, klass.to_s.tableize, id,
|
20
|
+
[Recommendable.config.redis_namespace, klass.to_s.tableize, id, 'disliked_by'].compact.join(':')
|
21
21
|
end
|
22
22
|
|
23
23
|
def score_set_for(klass)
|
24
24
|
[Recommendable.config.redis_namespace, klass.to_s.tableize, 'scores'].join(':')
|
25
25
|
end
|
26
|
+
|
27
|
+
def temp_set_for(klass, id)
|
28
|
+
[Recommendable.config.redis_namespace, klass.to_s.tableize, id, 'temp'].compact.join(':')
|
29
|
+
end
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module Recommendable
|
2
2
|
module Workers
|
3
3
|
class Sidekiq
|
4
|
-
|
5
|
-
|
4
|
+
if defined?(::Sidekiq)
|
5
|
+
include ::Sidekiq::Worker
|
6
|
+
sidekiq_options :unique => true, :queue => :recommendable
|
7
|
+
end
|
6
8
|
|
7
9
|
def perform(user_id)
|
8
10
|
Recommendable::Helpers::Calculations.update_similarities_for(user_id)
|
data/lib/recommendable.rb
CHANGED
@@ -7,6 +7,11 @@ require 'recommendable/helpers'
|
|
7
7
|
require 'recommendable/rater'
|
8
8
|
require 'recommendable/ratable'
|
9
9
|
|
10
|
+
require 'recommendable/workers/sidekiq'
|
11
|
+
require 'recommendable/workers/resque'
|
12
|
+
require 'recommendable/workers/delayed_job'
|
13
|
+
require 'recommendable/workers/rails'
|
14
|
+
|
10
15
|
module Recommendable
|
11
16
|
class << self
|
12
17
|
def redis() config.redis end
|
@@ -21,18 +26,14 @@ module Recommendable
|
|
21
26
|
user_id = user_id.id if user_id.is_a?(Recommendable.config.user_class)
|
22
27
|
|
23
28
|
if defined?(::Sidekiq)
|
24
|
-
require 'recommendable/workers/sidekiq'
|
25
29
|
Recommendable::Workers::Sidekiq.perform_async(user_id)
|
26
30
|
elsif defined?(::Resque)
|
27
|
-
require 'recommendable/workers/resque'
|
28
31
|
Resque.enqueue(Recommendable::Workers::Resque, user_id)
|
29
32
|
elsif defined?(::Delayed::Job)
|
30
|
-
require 'recommendable/workers/delayed_job'
|
31
33
|
Delayed::Job.enqueue(Recommendable::Workers::DelayedJob.new(user_id))
|
32
34
|
elsif defined?(::Rails::Queueing)
|
33
|
-
require 'recommendable/workers/rails'
|
34
35
|
unless Rails.queue.any? { |w| w.user_id == user_id }
|
35
|
-
Rails.queue.push(Recommendable::Workers::Rails.new(
|
36
|
+
Rails.queue.push(Recommendable::Workers::Rails.new(user_id))
|
36
37
|
Rails.application.queue_consumer.start
|
37
38
|
end
|
38
39
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: recommendable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0
|
4
|
+
version: 2.0.0.20121011
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -213,4 +213,3 @@ signing_key:
|
|
213
213
|
specification_version: 3
|
214
214
|
summary: A Like/Dislike recommendation engine for Ruby apps using Redis
|
215
215
|
test_files: []
|
216
|
-
has_rdoc: yard
|