commendo 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/commendo/content_set.rb +3 -9
- data/lib/commendo/tag_set.rb +5 -0
- data/lib/commendo/version.rb +1 -1
- data/lib/commendo/weighted_group.rb +17 -6
- data/test/tag_set_test.rb +21 -0
- data/test/weighted_group_test.rb +122 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f16a2f22f2afbdf32e7242ee821fca56ba8c690
|
4
|
+
data.tar.gz: c77c52106e8df36b855f41eb2c6bbd0d0f82bbbe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86cd12a3d567df7dc14bc77767d4297fca094fa4d0987bd8eb6674103c77455afc383a2933a2fa947e75b2ede3b07dd244379bf1b8ce5530b6d0e662c9830868
|
7
|
+
data.tar.gz: e327b49f232971ecb94c1e8bbec2e1ebf06673cdc596e2bc1a8722238fbc0316d24d84582d30a39769224288119e764cd473252c73184ee4d1b4fe190b62aea1
|
data/CHANGELOG.md
CHANGED
data/lib/commendo/content_set.rb
CHANGED
@@ -86,17 +86,12 @@ module Commendo
|
|
86
86
|
|
87
87
|
def filtered_similar_to(resource, options = {})
|
88
88
|
similar = similar_to(resource)
|
89
|
-
return similar if options[:include].nil? && options[:exclude].nil?
|
90
|
-
similar.delete_if { |s| !options[:exclude].nil? &&
|
91
|
-
similar.delete_if { |s| !options[:include].nil? &&
|
89
|
+
return similar if @tag_set.nil? || options[:include].nil? && options[:exclude].nil?
|
90
|
+
similar.delete_if { |s| !options[:exclude].nil? && @tag_set.matches(s[:resource], *options[:exclude]) }
|
91
|
+
similar.delete_if { |s| !options[:include].nil? && !@tag_set.matches(s[:resource], *options[:include]) }
|
92
92
|
similar
|
93
93
|
end
|
94
94
|
|
95
|
-
def tags_match(resource, tags)
|
96
|
-
resource_tags = tag_set.get(resource)
|
97
|
-
(resource_tags & tags).length > 0
|
98
|
-
end
|
99
|
-
|
100
95
|
def similarity_key(resource)
|
101
96
|
"#{similar_key_base}:#{resource}"
|
102
97
|
end
|
@@ -137,7 +132,6 @@ module Commendo
|
|
137
132
|
"#{key_base}:groups"
|
138
133
|
end
|
139
134
|
|
140
|
-
|
141
135
|
def group_key(group)
|
142
136
|
"#{group_key_base}:#{group}"
|
143
137
|
end
|
data/lib/commendo/tag_set.rb
CHANGED
data/lib/commendo/version.rb
CHANGED
@@ -2,18 +2,21 @@ module Commendo
|
|
2
2
|
|
3
3
|
class WeightedGroup
|
4
4
|
|
5
|
-
attr_accessor :content_sets, :redis, :key_base
|
5
|
+
attr_accessor :content_sets, :redis, :key_base, :tag_set
|
6
6
|
|
7
7
|
def initialize(redis, key_base, *content_sets)
|
8
8
|
@content_sets, @redis, @key_base = content_sets, redis, key_base
|
9
9
|
end
|
10
10
|
|
11
11
|
def similar_to(resource)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
resources = resource.kind_of?(Array) ? resource : [resource]
|
13
|
+
keys = []
|
14
|
+
weights = []
|
15
|
+
content_sets.each do |cs|
|
16
|
+
resources.each do |resource|
|
17
|
+
keys << cs[:cs].similarity_key(resource)
|
18
|
+
weights << cs[:weight]
|
19
|
+
end
|
17
20
|
end
|
18
21
|
tmp_key = "#{key_base}:tmp:#{SecureRandom.uuid}"
|
19
22
|
redis.zunionstore(tmp_key, keys, weights: weights)
|
@@ -26,6 +29,14 @@ module Commendo
|
|
26
29
|
|
27
30
|
end
|
28
31
|
|
32
|
+
def filtered_similar_to(resource, options = {})
|
33
|
+
similar = similar_to(resource)
|
34
|
+
return similar if @tag_set.nil? || options[:include].nil? && options[:exclude].nil?
|
35
|
+
similar.delete_if { |s| !options[:exclude].nil? && @tag_set.matches(s[:resource], *options[:exclude]) }
|
36
|
+
similar.delete_if { |s| !options[:include].nil? && !@tag_set.matches(s[:resource], *options[:include]) }
|
37
|
+
similar
|
38
|
+
end
|
39
|
+
|
29
40
|
end
|
30
41
|
|
31
42
|
end
|
data/test/tag_set_test.rb
CHANGED
@@ -44,5 +44,26 @@ module Commendo
|
|
44
44
|
assert_equal ['qip', 'qux'], ts.get(2)
|
45
45
|
end
|
46
46
|
|
47
|
+
def test_matches_tags
|
48
|
+
redis = Redis.new(db: 15)
|
49
|
+
redis.flushdb
|
50
|
+
ts = TagSet.new(redis, 'TagSetTest')
|
51
|
+
ts.set(1, 'foo', 'bar', 'baz')
|
52
|
+
ts.set(2, 'qux', 'qip')
|
53
|
+
|
54
|
+
assert ts.matches(1, 'foo')
|
55
|
+
assert ts.matches(1, 'bar', 'baz')
|
56
|
+
assert ts.matches(1, 'bar', 'baz', 'foo')
|
57
|
+
refute ts.matches(1, 'qux')
|
58
|
+
refute ts.matches(1, 'qip')
|
59
|
+
|
60
|
+
refute ts.matches(2, 'foo')
|
61
|
+
refute ts.matches(2, 'bar', 'baz')
|
62
|
+
refute ts.matches(2, 'bar', 'baz', 'foo')
|
63
|
+
assert ts.matches(2, 'qux', 'qip')
|
64
|
+
assert ts.matches(2, 'qux')
|
65
|
+
assert ts.matches(2, 'qip')
|
66
|
+
end
|
67
|
+
|
47
68
|
end
|
48
69
|
end
|
data/test/weighted_group_test.rb
CHANGED
@@ -9,21 +9,36 @@ module Commendo
|
|
9
9
|
|
10
10
|
class WeightedGroupTest < Minitest::Test
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
redis.
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
@redis ||= Redis.new(db: 15)
|
15
|
+
@redis.flushdb
|
16
|
+
@tag_set = TagSet.new(@redis, 'CommendoTests:Tags')
|
17
|
+
@cs1 = ContentSet.new(@redis, 'CommendoTests:ContentSet1', @tag_set)
|
18
|
+
@cs2 = ContentSet.new(@redis, 'CommendoTests:ContentSet2', @tag_set)
|
19
|
+
@cs3 = ContentSet.new(@redis, 'CommendoTests:ContentSet3', @tag_set)
|
18
20
|
(3..23).each do |group|
|
19
21
|
(3..23).each do |res|
|
20
|
-
cs1.add_by_group(group, res) if (res % group == 0) && (res % 2 == 0)
|
21
|
-
cs2.add_by_group(group, res) if (res % group == 0) && (res % 3 == 0)
|
22
|
-
cs3.add_by_group(group, res) if (res % group == 0) && (res % 6 == 0)
|
22
|
+
@cs1.add_by_group(group, res) if (res % group == 0) && (res % 2 == 0)
|
23
|
+
@cs2.add_by_group(group, res) if (res % group == 0) && (res % 3 == 0)
|
24
|
+
@cs3.add_by_group(group, res) if (res % group == 0) && (res % 6 == 0)
|
25
|
+
@tag_set.add(res, 'mod3') if res.modulo(3).zero?
|
26
|
+
@tag_set.add(res, 'mod4') if res.modulo(4).zero?
|
27
|
+
@tag_set.add(res, 'mod5') if res.modulo(5).zero?
|
28
|
+
@tag_set.add(res, 'mod7') if res.modulo(7).zero?
|
23
29
|
end
|
24
30
|
end
|
25
|
-
[cs1, cs2, cs3].each { |cs| cs.calculate_similarity }
|
26
|
-
|
31
|
+
[@cs1, @cs2, @cs3].each { |cs| cs.calculate_similarity }
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_calls_each_content_set
|
35
|
+
weighted_group = WeightedGroup.new(
|
36
|
+
@redis,
|
37
|
+
'CommendoTests:WeightedGroup',
|
38
|
+
{cs: @cs1, weight: 1.0},
|
39
|
+
{cs: @cs2, weight: 10.0},
|
40
|
+
{cs: @cs3, weight: 100.0}
|
41
|
+
)
|
27
42
|
expected = [
|
28
43
|
{resource: '6', similarity: 55.5},
|
29
44
|
{resource: '12', similarity: 36.963},
|
@@ -35,12 +50,107 @@ module Commendo
|
|
35
50
|
assert_equal expected, weighted_group.similar_to(18)
|
36
51
|
end
|
37
52
|
|
53
|
+
def test_filters_include_recommendations
|
54
|
+
weighted_group = WeightedGroup.new(
|
55
|
+
@redis,
|
56
|
+
'CommendoTests:WeightedGroup',
|
57
|
+
{cs: @cs1, weight: 1.0},
|
58
|
+
{cs: @cs2, weight: 10.0},
|
59
|
+
{cs: @cs3, weight: 100.0}
|
60
|
+
)
|
61
|
+
expected = [{resource: '15', similarity: 1.67}]
|
62
|
+
weighted_group.tag_set = @tag_set
|
63
|
+
assert_equal expected, weighted_group.filtered_similar_to(18, include: ['mod5'])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_filters_exclude_recommendations
|
67
|
+
weighted_group = WeightedGroup.new(
|
68
|
+
@redis,
|
69
|
+
'CommendoTests:WeightedGroup',
|
70
|
+
{cs: @cs1, weight: 1.0},
|
71
|
+
{cs: @cs2, weight: 10.0},
|
72
|
+
{cs: @cs3, weight: 100.0}
|
73
|
+
)
|
74
|
+
expected = [
|
75
|
+
{resource: '6', similarity: 55.5},
|
76
|
+
{resource: '12', similarity: 36.963},
|
77
|
+
{resource: '9', similarity: 5.0},
|
78
|
+
{resource: '3', similarity: 2.5}
|
79
|
+
]
|
80
|
+
weighted_group.tag_set = @tag_set
|
81
|
+
assert_equal expected, weighted_group.filtered_similar_to(18, exclude: ['mod5', 'mod7'])
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_filters_include_and_exclude_recommendations
|
85
|
+
weighted_group = WeightedGroup.new(
|
86
|
+
@redis,
|
87
|
+
'CommendoTests:WeightedGroup',
|
88
|
+
{cs: @cs1, weight: 100.0},
|
89
|
+
{cs: @cs2, weight: 10.0},
|
90
|
+
{cs: @cs3, weight: 1.0}
|
91
|
+
)
|
92
|
+
expected = [
|
93
|
+
{resource: '16', similarity: 66.7},
|
94
|
+
{resource: '4', similarity: 50.0},
|
95
|
+
{resource: '12', similarity: 20.0}
|
96
|
+
]
|
97
|
+
weighted_group.tag_set = @tag_set
|
98
|
+
assert_equal expected, weighted_group.filtered_similar_to(8, include: ['mod4'], exclude: ['mod5'])
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_similar_to_mutliple_items
|
102
|
+
weighted_group = WeightedGroup.new(
|
103
|
+
@redis,
|
104
|
+
'CommendoTests:WeightedGroup',
|
105
|
+
{cs: @cs1, weight: 100.0},
|
106
|
+
{cs: @cs2, weight: 10.0},
|
107
|
+
{cs: @cs3, weight: 1.0}
|
108
|
+
)
|
109
|
+
expected = [
|
110
|
+
{resource: '12', similarity: 83.0},
|
111
|
+
{resource: '18', similarity: 58.0},
|
112
|
+
{resource: '8', similarity: 50.0},
|
113
|
+
{resource: '16', similarity: 33.3},
|
114
|
+
{resource: '20', similarity: 25.0},
|
115
|
+
{resource: '9', similarity: 8.33},
|
116
|
+
{resource: '21', similarity: 5.83},
|
117
|
+
{resource: '15', similarity: 5.83},
|
118
|
+
{resource: '6', similarity: 5.0},
|
119
|
+
{resource: '3', similarity: 5.0}
|
120
|
+
]
|
121
|
+
weighted_group.tag_set = @tag_set
|
122
|
+
assert_equal expected, weighted_group.similar_to([3,4,5,6,7])
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_filtered_similar_to_mutliple_items
|
126
|
+
weighted_group = WeightedGroup.new(
|
127
|
+
@redis,
|
128
|
+
'CommendoTests:WeightedGroup',
|
129
|
+
{cs: @cs1, weight: 100.0},
|
130
|
+
{cs: @cs2, weight: 10.0},
|
131
|
+
{cs: @cs3, weight: 1.0}
|
132
|
+
)
|
133
|
+
expected = [
|
134
|
+
{resource: '12', similarity: 83.0},
|
135
|
+
#{resource: '18', similarity: 58.0},
|
136
|
+
{resource: '8', similarity: 50.0},
|
137
|
+
{resource: '16', similarity: 33.3},
|
138
|
+
#{resource: '20', similarity: 25.0},
|
139
|
+
#{resource: '9', similarity: 8.33},
|
140
|
+
#{resource: '21', similarity: 5.83},
|
141
|
+
#{resource: '15', similarity: 5.83},
|
142
|
+
#{resource: '6', similarity: 5.0},
|
143
|
+
#{resource: '3', similarity: 5.0}
|
144
|
+
]
|
145
|
+
weighted_group.tag_set = @tag_set
|
146
|
+
assert_equal expected, weighted_group.filtered_similar_to([3,4,5,6,7], include: ['mod4'], exclude: ['mod5'])
|
147
|
+
end
|
148
|
+
|
38
149
|
def test_precalculates
|
39
150
|
skip
|
40
151
|
end
|
41
152
|
|
42
153
|
|
43
|
-
|
44
154
|
end
|
45
155
|
|
46
156
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: commendo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob Styles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|