disco 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4af4d7df56f884618557fd98f97da2686cecbfaf3ce1f1f52b6ba1a3a9155f5
4
- data.tar.gz: ddbc7551c3534c41284e958042a94d988cdd5c52248f3ca7e4a8d8a72c6b168e
3
+ metadata.gz: 0fb469aae804d8f6ed2fe398b3584e67d1ebf29cd0d0d394eda952d32c0756f9
4
+ data.tar.gz: 295bde072449c13e3da22975efa0bdbe9ea5a1fdbbb787f0b0d63411056e6799
5
5
  SHA512:
6
- metadata.gz: 5f40f125fe4096dcf09eaf1d1295f23e68fef9bbe1e5651a1ecfa1ed06748df7a0f4c9ea048b767b429b67b4d0add1f32663388707616571a6936a55ffd1d6b7
7
- data.tar.gz: baf3caa4deec5422bd85e9372bc717f683d4cbb067f468eb7d4c964556885f7bb273fa0b6339201aef917c8f046346c20356358462fc73103243608a5245ebe6
6
+ metadata.gz: 287c44da295f55d2f95788fb7c0488738c1f70a409bb372461ad37d1786ade8fd0650abb8de62f023805a03bd667f74b509069bbaa9ca4f58a56aa1628d8b7c4
7
+ data.tar.gz: 81bceaa14ffc78918157b25c4cb4a21f0d08d625042867866032fe006a8cbfcd041914dfa19c720a0bc7211d00fe40d14f95fc2e1d769b7a9af59711641dcc78
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.4.0 (2023-01-30)
2
+
3
+ - Fixed issue with `has_recommended` and inheritance with Rails < 6.1
4
+ - Deprecated marshal serialization
5
+ - Dropped support for Ruby < 2.7 and Rails < 6
6
+
7
+ ## 0.3.2 (2022-09-26)
8
+
9
+ - Fixed issue when `fit` is called multiple times
10
+
1
11
  ## 0.3.1 (2022-07-10)
2
12
 
3
13
  - Added support for JSON serialization
data/README.md CHANGED
@@ -176,8 +176,6 @@ user.update_recommended_products_v2(recs)
176
176
  user.recommended_products_v2
177
177
  ```
178
178
 
179
- For Rails < 6, speed up inserts by adding [activerecord-import](https://github.com/zdennis/activerecord-import) to your app.
180
-
181
179
  ## Storing Recommenders
182
180
 
183
181
  If you’d prefer to perform recommendations on-the-fly, store the recommender
@@ -187,9 +185,7 @@ json = recommender.to_json
187
185
  File.write("recommender.json", json)
188
186
  ```
189
187
 
190
- > You can save it to a file, database, or any other storage system. Also, user and item IDs should be integers or strings for this.
191
-
192
- The serialized recommender includes user activity from the training data (to avoid recommending previously rated items), so be sure to protect it.
188
+ The serialized recommender includes user activity from the training data (to avoid recommending previously rated items), so be sure to protect it. You can save it to a file, database, or any other storage system, or use a tool like [Trove](https://github.com/ankane/trove). Also, user and item IDs should be integers or strings for this.
193
189
 
194
190
  Load a recommender
195
191
 
@@ -225,7 +221,7 @@ recommender.fit(data, validation_set: validation_set)
225
221
 
226
222
  ## Cold Start
227
223
 
228
- Collaborative filtering suffers from the [cold start problem](https://www.yuspify.com/blog/cold-start-problem-recommender-systems/). It’s unable to make good recommendations without data on a user or item, which is problematic for new users and items.
224
+ Collaborative filtering suffers from the [cold start problem](https://en.wikipedia.org/wiki/Cold_start_(recommender_systems)). It’s unable to make good recommendations without data on a user or item, which is problematic for new users and items.
229
225
 
230
226
  ```ruby
231
227
  recommender.user_recs(new_user_id) # returns empty array
data/lib/disco/model.rb CHANGED
@@ -1,7 +1,12 @@
1
1
  module Disco
2
2
  module Model
3
3
  def has_recommended(name, class_name: nil)
4
+ if ActiveRecord::VERSION::MAJOR < 6
5
+ raise Disco::Error, "Requires Active Record 6+"
6
+ end
7
+
4
8
  class_name ||= name.to_s.singularize.camelize
9
+ subject_type = model_name.name
5
10
 
6
11
  class_eval do
7
12
  unless reflect_on_association(:recommendations)
@@ -12,21 +17,13 @@ module Disco
12
17
 
13
18
  define_method("update_recommended_#{name}") do |items|
14
19
  now = Time.now
15
- items = items.map { |item| {subject_type: model_name.name, subject_id: id, item_type: class_name, item_id: item.fetch(:item_id), context: name, score: item.fetch(:score), created_at: now, updated_at: now} }
20
+ items = items.map { |item| {subject_type: subject_type, subject_id: id, item_type: class_name, item_id: item.fetch(:item_id), context: name, score: item.fetch(:score), created_at: now, updated_at: now} }
16
21
 
17
22
  self.class.transaction do
18
23
  recommendations.where(context: name).delete_all
19
24
 
20
25
  if items.any?
21
- if recommendations.respond_to?(:insert_all!)
22
- # Rails 6
23
- recommendations.insert_all!(items)
24
- elsif recommendations.respond_to?(:bulk_import!)
25
- # activerecord-import
26
- recommendations.bulk_import!(items, validate: false)
27
- else
28
- recommendations.create!([items])
29
- end
26
+ recommendations.insert_all!(items)
30
27
  end
31
28
  end
32
29
  end
@@ -36,6 +36,8 @@ module Disco
36
36
  end
37
37
  end
38
38
 
39
+ @user_map = {}
40
+ @item_map = {}
39
41
  @rated = Hash.new { |hash, key| hash[key] = {} }
40
42
  input = []
41
43
  train_set.each do |v|
@@ -56,6 +58,9 @@ module Disco
56
58
  # TODO improve performance
57
59
  unless @implicit
58
60
  @min_rating, @max_rating = train_set.minmax_by { |o| o[:rating] }.map { |o| o[:rating] }
61
+ else
62
+ @min_rating = nil
63
+ @max_rating = nil
59
64
  end
60
65
 
61
66
  if @top_items
@@ -425,6 +430,8 @@ module Disco
425
430
  end
426
431
 
427
432
  def marshal_dump
433
+ warn "[disco] Marshal serialization is deprecated - use JSON instead"
434
+
428
435
  obj = {
429
436
  implicit: @implicit,
430
437
  user_map: @user_map,
@@ -452,6 +459,8 @@ module Disco
452
459
  end
453
460
 
454
461
  def marshal_load(obj)
462
+ warn "[disco] Marshal serialization is deprecated - use JSON instead"
463
+
455
464
  @implicit = obj[:implicit]
456
465
  @user_map = obj[:user_map]
457
466
  @item_map = obj[:item_map]
data/lib/disco/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Disco
2
- VERSION = "0.3.1"
2
+ VERSION = "0.4.0"
3
3
  end
data/lib/disco.rb CHANGED
@@ -3,13 +3,13 @@ require "libmf"
3
3
  require "numo/narray"
4
4
 
5
5
  # modules
6
- require "disco/data"
7
- require "disco/metrics"
8
- require "disco/recommender"
9
- require "disco/version"
6
+ require_relative "disco/data"
7
+ require_relative "disco/metrics"
8
+ require_relative "disco/recommender"
9
+ require_relative "disco/version"
10
10
 
11
11
  # integrations
12
- require "disco/engine" if defined?(Rails)
12
+ require_relative "disco/engine" if defined?(Rails)
13
13
 
14
14
  module Disco
15
15
  class Error < StandardError; end
@@ -19,7 +19,7 @@ end
19
19
 
20
20
  if defined?(ActiveSupport.on_load)
21
21
  ActiveSupport.on_load(:active_record) do
22
- require "disco/model"
22
+ require_relative "disco/model"
23
23
  extend Disco::Model
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: disco
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-10 00:00:00.000000000 Z
11
+ date: 2023-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libmf
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.0
19
+ version: '0.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.0
26
+ version: '0.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: numo-narray
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -69,14 +69,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
- version: '2.6'
72
+ version: '2.7'
73
73
  required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  requirements: []
79
- rubygems_version: 3.3.7
79
+ rubygems_version: 3.4.1
80
80
  signing_key:
81
81
  specification_version: 4
82
82
  summary: Recommendations for Ruby and Rails using collaborative filtering