recommengine 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +115 -0
- data/lib/{calculator.rb → recommengine/calculator.rb} +0 -0
- data/lib/{euclidean_calculator.rb → recommengine/euclidean_calculator.rb} +0 -0
- data/lib/{flipper.rb → recommengine/flipper.rb} +0 -0
- data/lib/{matcher.rb → recommengine/matcher.rb} +0 -0
- data/lib/{pearson_calculator.rb → recommengine/pearson_calculator.rb} +0 -0
- data/lib/{recommender.rb → recommengine/recommender.rb} +0 -0
- data/lib/recommengine.rb +12 -1
- data/recommengine.gemspec +4 -2
- metadata +9 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 496f46662c16632ef87c39362da42b9bd87ee70b
|
|
4
|
+
data.tar.gz: 7f8b0dbafa5eedca41292a3fdc07b1ed857b7c4a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b21579175a273f54b84053b0a512c30c0ff63cbf0bc6f60e6708da970c491ed78a536f7c49bfdb63a18ba13a5e09fa159308d409c774807c8704a85572e6c3e1
|
|
7
|
+
data.tar.gz: 17a40493de4d89b42adcfb84425b7eabb3079682bfd6a41a78762324fc565e0b0630550c507b36f6e5d57caef7eaf2ee30d9b1589c545e94f70614a7b1698b90
|
data/README.md
CHANGED
|
@@ -1,2 +1,117 @@
|
|
|
1
1
|
# RecommEngine
|
|
2
2
|
A plug-and-play recommendation engine gem supporting multiple similarity algorithms. Use to recommend products for people, or people for products.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
Simply `gem install recommengine` or if using bundler, add recommengine to your Gemfile thusly
|
|
6
|
+
```ruby
|
|
7
|
+
require 'recommengine'
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Methodology
|
|
11
|
+
RecommEngine uses a weighted scoring system in conjunction with a similarity algorithm (of either the Pearson or Euclidean variety) to suggest 'products' to users based on their prior behavior in accordance with the principle of collaborative filtering. In order to utilize this gem, you must have users, products, and some kind of numerical scoring system that describes a user's interaction with a given product.
|
|
12
|
+
Products need not be physical items, as this gem has applications outside the ecommerce realm. Products can be things like movies or web links as well. Similarly, scores aren't limited to only to ratings -- they only need to be a numerical representation that describes a user's behavior. For example:
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|(Score)| Physical Goods | Movies | Web Habits |
|
|
16
|
+
--------|:--------------:|:------:|-------------:|
|
|
17
|
+
| 0 | No Interaction | < * | Didn't Click |
|
|
18
|
+
| 1 | Browsed | * | Clicked |
|
|
19
|
+
| 2 | Searched For | ** | Searched for |
|
|
20
|
+
| 3 | Bought | *** | N/A |
|
|
21
|
+
| 4 | Bought > 1x | **** | N/A |
|
|
22
|
+
|
|
23
|
+
### Euclidean Algorithm
|
|
24
|
+
|
|
25
|
+
The Euclidean distance algorithm is a simplistic similarity measure that determines how close two points are when plotted in [Cartesian coordinates](https://en.wikipedia.org/wiki/Cartesian_coordinate_system). Read more about Euclidean distance on [wikipedia](https://en.wikipedia.org/wiki/Euclidean_distance).
|
|
26
|
+
|
|
27
|
+
### Pearson Algorithm
|
|
28
|
+
|
|
29
|
+
The Pearson similarity score adds a bit more complexity. Feel free to read up on it on [wikipedia](https://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient). The Pearson method is the default similarity algorithm in RecommEngine, primarily because it compensates for grade inflation when determining similarity.
|
|
30
|
+
|
|
31
|
+
### How Recommendations Work
|
|
32
|
+
|
|
33
|
+
When passing 'data' and 'subject' arguments to the recommendations method, RecommEngine will compare the similarity between all members of the data hash and the subject using the specified similarity algorithm, and determine a weighted predicted score for each product based upon each user's similarity to the subject. Only 'products' that the subject has not yet rated will be returned. The products are sorted by score in descending order.
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
The RecommEngine module can be safely mixed in to your own classes, but in many cases the simplest solution is to call the module function and pass your data, subject, and preferred algorithm (optional) in.
|
|
38
|
+
|
|
39
|
+
Data must be in the form of a nested hash. Example:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
books = {
|
|
43
|
+
alice: {"War and Peace" => 2.5, "Crime and Punishment" => 3.5},
|
|
44
|
+
bob: {"War of the Worlds" => 5.0, "War and Peace" => 1.5, "The Great Gatsby" => 4.0},
|
|
45
|
+
cindy: {"War and Peace" => 5.0, "The Great Gatsby" => 4.5, "War of the Worlds" => 3.0, "Twenty Thousand Leagues Under the Sea" => 3.0},
|
|
46
|
+
don: {"War of the Worlds" => 4.0, "The Great Gatsby" => 2.5, "Twenty Thousand Leagues Under the Sea" => 5.0, "Crime and Punishment" => 4.5, "War and Peace" => 3.0},
|
|
47
|
+
erica: {"War of the Worlds" => 3.0, "The Great Gatsby" => 4.5, "Twenty Thousand Leagues Under the Sea" => 4.0, "Crime and Punishment" => 4.5, "War and Peace" => 3.5}}
|
|
48
|
+
```
|
|
49
|
+
### Recommendations
|
|
50
|
+
|
|
51
|
+
With the above 'data' in place, we can then call
|
|
52
|
+
|
|
53
|
+
```ruby
|
|
54
|
+
RecommEngine.recs(data: books, subject: :alice)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
...which will return:
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
[["Twenty Thousand Leagues Under the Sea", 4.5],
|
|
61
|
+
["The Great Gatsby", 3.5],
|
|
62
|
+
["War of the Worlds", 3.5]]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Only products the subject has not rated will be returned. The second element in each array is the predicted score the subject will give to the product, based upon the weighted average that similar users to alice have rated the product. Since no similarity algorithm was specified, the Pearson score is used by default.
|
|
66
|
+
|
|
67
|
+
Alternatively, we could specify the use of the Euclidean algorithm as follows.
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
RecommEngine(data: books, subject: :alice, similarity: 'Euclidean')
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Which returns a similar, though subtly different set of results:
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
[["Twenty Thousand Leagues Under the Sea", 4.182787296581158],
|
|
77
|
+
["War of the Worlds", 3.8959601003790714],
|
|
78
|
+
["The Great Gatsby", 3.7736808311188366]]
|
|
79
|
+
```
|
|
80
|
+
### Top Matches
|
|
81
|
+
|
|
82
|
+
RecommEngine includes a utility to find similar users to a subject. This can be done by calling:
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
RecommEngine.top_matches(data: books, subject: :bob)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
which returns:
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
[[:don, 0.4539206495016016], [:alice, 0], [:erica, -0.09078412990032045]]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You'll notice a reasonably strong positive correlation with Don (meaning Don and Bob have similar taste), a neutral correlation with Alice, and a slightly negative correlation with Erica.
|
|
95
|
+
|
|
96
|
+
By default, the Pearson algorithm is used, and only 3 results are returned. These parameters can be defined explicitly when calling the method, by passing for example `num: 5` and/or `similarity: 'Euclidean'`.
|
|
97
|
+
|
|
98
|
+
### Flipper
|
|
99
|
+
|
|
100
|
+
RecommEngine also provides a handy means to 'flip' your data -- transposing products and users. This can be handy when attempting direct marketing campaigns for instance. Products are compared by similarity, and users are recommended for each products. It can lead to some interesting results. For example
|
|
101
|
+
|
|
102
|
+
```ruby
|
|
103
|
+
RecommEngine.recs(data: RecommEngine.flip(books), subject: 'Crime and Punishment')
|
|
104
|
+
```
|
|
105
|
+
returns
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
[[:cindy, 5.0], [:bob, 1.5]]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Contributing
|
|
112
|
+
|
|
113
|
+
Contributions are welcome; feel encouraged to fork the repo and submit PRs! Current priorities include adding additional similarity algorithms and working more closely in conjunction with ActiveRecord to form our 'data' objects rather than explicitly declaring hashes. Please ensure all specs pass before submitting a pull request is submitted, and be sure to add test coverage for any additional features.
|
|
114
|
+
|
|
115
|
+
## Questions?
|
|
116
|
+
|
|
117
|
+
codyknauer@gmail.com
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/recommengine.rb
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
Dir['
|
|
1
|
+
# Dir['recommengine/*.rb'].each { |f| require f.gsub('.rb', ''); puts f }
|
|
2
|
+
|
|
3
|
+
# require 'calculator'
|
|
4
|
+
# require 'euclidean_calculator'
|
|
5
|
+
# require 'flipper'
|
|
6
|
+
# require 'pearson_calculator'
|
|
7
|
+
# require 'matcher'
|
|
8
|
+
# require 'recommender'
|
|
9
|
+
|
|
10
|
+
files = %w[calculator euclidean_calculator flipper matcher pearson_calculator recommender]
|
|
11
|
+
files.each { |f| require f}
|
|
12
|
+
|
|
2
13
|
|
|
3
14
|
module RecommEngine
|
|
4
15
|
DEFAULT_ALGORITHM = 'Pearson'
|
data/recommengine.gemspec
CHANGED
|
@@ -2,8 +2,8 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = 'recommengine'
|
|
5
|
-
s.version = '0.1.
|
|
6
|
-
s.date = '2015-
|
|
5
|
+
s.version = '0.1.2'
|
|
6
|
+
s.date = '2015-09-12'
|
|
7
7
|
s.summary = "A flexible recommendation engine."
|
|
8
8
|
s.description = "A flexible recommendation engine supporting multiple similarity algorithms for use in ecommerce sites, marketplaces, social sharing apps, and more."
|
|
9
9
|
s.authors = ["Cody Knauer"]
|
|
@@ -14,5 +14,7 @@ Gem::Specification.new do |s|
|
|
|
14
14
|
s.license = 'MIT'
|
|
15
15
|
s.require_paths = ["lib"]
|
|
16
16
|
|
|
17
|
+
s.required_ruby_version = '>= 2.1.0'
|
|
18
|
+
|
|
17
19
|
s.add_development_dependency 'rspec', '~> 3.1'
|
|
18
20
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: recommengine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cody Knauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-09-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rspec
|
|
@@ -35,13 +35,13 @@ files:
|
|
|
35
35
|
- ".rspec"
|
|
36
36
|
- LICENSE
|
|
37
37
|
- README.md
|
|
38
|
-
- lib/calculator.rb
|
|
39
|
-
- lib/euclidean_calculator.rb
|
|
40
|
-
- lib/flipper.rb
|
|
41
|
-
- lib/matcher.rb
|
|
42
|
-
- lib/pearson_calculator.rb
|
|
43
|
-
- lib/recommender.rb
|
|
44
38
|
- lib/recommengine.rb
|
|
39
|
+
- lib/recommengine/calculator.rb
|
|
40
|
+
- lib/recommengine/euclidean_calculator.rb
|
|
41
|
+
- lib/recommengine/flipper.rb
|
|
42
|
+
- lib/recommengine/matcher.rb
|
|
43
|
+
- lib/recommengine/pearson_calculator.rb
|
|
44
|
+
- lib/recommengine/recommender.rb
|
|
45
45
|
- recommengine.gemspec
|
|
46
46
|
- spec/lib/euclidean_calculator_spec.rb
|
|
47
47
|
- spec/lib/flipper_spec.rb
|
|
@@ -62,7 +62,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
62
62
|
requirements:
|
|
63
63
|
- - ">="
|
|
64
64
|
- !ruby/object:Gem::Version
|
|
65
|
-
version:
|
|
65
|
+
version: 2.1.0
|
|
66
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
67
|
requirements:
|
|
68
68
|
- - ">="
|