cmfrec 0.1.5 → 0.1.6

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: 7a200b99780aeee83c5a0190e593c3806c4140aa4c096b0ef2c112fd21a858b7
4
- data.tar.gz: 27b354dd491ca1d7a728d4ef2318c72c56d76c691286bc267c74d3b8dafd7c5b
3
+ metadata.gz: 34e8dc08914cbc418470cd7eb3adf3d33013b786319f4510212c80bf3629f3ca
4
+ data.tar.gz: c1b91a1f77b4b51a5ca4491376f8a02230ea54873f8c1b2b06f4761d6ddd0686
5
5
  SHA512:
6
- metadata.gz: 0c1ceefeac9131a804d94b6da78c7a6614f50c15d144841277829e5279ce2583872a681e972e336e21cb82d49466dee9f5f1de6a482fe8a99ab7aa5176ab0e5c
7
- data.tar.gz: 930b20b017b92555071699b38d903230da3ca1fc7b8b91b9e2f96ae3ae4dda9c8c289a47117beaa1e2539e5c9d622fe958d431f5106e8ab7c4809ea17e9fb6e8
6
+ metadata.gz: a3c57734379199196a4e3f51d9ec02b19ef1abac13d57a10ca3c20e9b76c9ee5db4b17d790330d41a9576c2ba28a9eeccafeb5760b54cfdf80a7431368895068
7
+ data.tar.gz: 5a24a77a6665854abb38916a22e8141a6cae637a51f98e3df3762566f2e73cb60b9bd9a25303df0411ea53dec3211bf7534711dc55c510311620341cbe4e4ac3
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 0.1.6 (2021-08-12)
2
+
3
+ - Added `user_ids` and `item_ids` methods
4
+ - Added `user_id` argument to `user_factors`
5
+ - Added `item_id` argument to `item_factors`
6
+ - Added `user_id` argument to `user_bias`
7
+ - Added `item_id` argument to `item_bias`
8
+ - Added `item_ids` argument to `new_user_recs`
9
+ - Fixed order for `user_recs`
10
+
1
11
  ## 0.1.5 (2021-08-10)
2
12
 
3
13
  - Fixed issue with `user_recs` and `new_user_recs` returning rated items
data/README.md CHANGED
@@ -232,6 +232,13 @@ recommender = Marshal.load(bin)
232
232
 
233
233
  ## Reference
234
234
 
235
+ Get ids
236
+
237
+ ```ruby
238
+ recommender.user_ids
239
+ recommender.item_ids
240
+ ```
241
+
235
242
  Get the global mean
236
243
 
237
244
  ```ruby
@@ -67,23 +67,10 @@ module Cmfrec
67
67
  user = @user_map[user_id]
68
68
 
69
69
  if user
70
- # TODO use top_n for item_ids as well
71
- if item_ids
72
- # remove missing ids
73
- item_ids = item_ids.select { |v| @item_map[v] }
74
-
75
- data = item_ids.map { |v| {user_id: user_id, item_id: v} }
76
- scores = predict(data)
77
-
78
- item_ids.zip(scores).map do |item_id, score|
79
- {item_id: item_id, score: score}
80
- end
81
- else
82
- a_vec = @a[user * @k * Fiddle::SIZEOF_DOUBLE, @k * Fiddle::SIZEOF_DOUBLE]
83
- a_bias = @bias_a ? @bias_a[user * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") : 0
84
- # @rated[user] will be nil for recommenders saved before 0.1.5
85
- top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: (@rated[user] || {}).keys)
86
- end
70
+ a_vec = @a[user * @k * Fiddle::SIZEOF_DOUBLE, @k * Fiddle::SIZEOF_DOUBLE]
71
+ a_bias = @bias_a ? @bias_a[user * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") : 0
72
+ # @rated[user] will be nil for recommenders saved before 0.1.5
73
+ top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: (@rated[user] || {}).keys, item_ids: item_ids)
87
74
  else
88
75
  # no items if user is unknown
89
76
  # TODO maybe most popular items
@@ -91,28 +78,35 @@ module Cmfrec
91
78
  end
92
79
  end
93
80
 
94
- # TODO add item_ids
95
- def new_user_recs(data, count: 5, user_info: nil)
81
+ def new_user_recs(data, count: 5, user_info: nil, item_ids: nil)
96
82
  check_fit
97
83
 
98
84
  a_vec, a_bias, rated = factors_warm(data, user_info: user_info)
99
- top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: rated)
85
+ top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: rated, item_ids: item_ids)
86
+ end
87
+
88
+ def user_ids
89
+ @user_map.keys
90
+ end
91
+
92
+ def item_ids
93
+ @item_map.keys
100
94
  end
101
95
 
102
- def user_factors
103
- read_factors(@a, [@m, @m_u].max, @k_user + @k + @k_main)
96
+ def user_factors(user_id = nil)
97
+ read_factors(@a, [@m, @m_u].max, @k_user + @k + @k_main, user_id, @user_map)
104
98
  end
105
99
 
106
- def item_factors
107
- read_factors(@b, [@n, @n_i].max, @k_item + @k + @k_main)
100
+ def item_factors(item_id = nil)
101
+ read_factors(@b, [@n, @n_i].max, @k_item + @k + @k_main, item_id, @item_map)
108
102
  end
109
103
 
110
- def user_bias
111
- read_bias(@bias_a) if @bias_a
104
+ def user_bias(user_id = nil)
105
+ read_bias(@bias_a, user_id, @user_map) if @bias_a
112
106
  end
113
107
 
114
- def item_bias
115
- read_bias(@bias_b) if @bias_b
108
+ def item_bias(item_id = nil)
109
+ read_bias(@bias_b, item_id, @item_map) if @bias_b
116
110
  end
117
111
 
118
112
  def similar_items(item_id, count: 5)
@@ -443,26 +437,48 @@ module Cmfrec
443
437
  end
444
438
  end
445
439
 
446
- def read_factors(ptr, d1, d2)
447
- arr = []
448
- offset = 0
440
+ def read_factors(ptr, d1, d2, id, map)
449
441
  width = d2 * Fiddle::SIZEOF_DOUBLE
450
- d1.times do |i|
451
- arr << ptr[offset, width].unpack("d*")
452
- offset += width
442
+ if id
443
+ i = map[id]
444
+ ptr[i * width, width].unpack("d*") if i
445
+ else
446
+ arr = []
447
+ offset = 0
448
+ d1.times do |i|
449
+ arr << ptr[offset, width].unpack("d*")
450
+ offset += width
451
+ end
452
+ arr
453
453
  end
454
- arr
455
454
  end
456
455
 
457
- def read_bias(ptr)
458
- real_array(ptr)
456
+ def read_bias(ptr, id, map)
457
+ if id
458
+ i = map[id]
459
+ ptr[i * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") if i
460
+ else
461
+ real_array(ptr)
462
+ end
459
463
  end
460
464
 
461
- def top_n(a_vec:, a_bias:, count:, rated: nil)
462
- include_ix = nil
463
- n_include = 0
465
+ def top_n(a_vec:, a_bias:, count:, rated: nil, item_ids: nil)
466
+ if item_ids
467
+ # remove missing ids
468
+ item_ids = item_ids.map { |v| @item_map[v] }.compact
469
+ return [] if item_ids.empty?
470
+
471
+ include_ix = int_ptr(item_ids)
472
+ n_include = item_ids.size
473
+
474
+ # TODO uncomment in 0.2.0
475
+ count = n_include # if n_include < count
476
+ else
477
+ include_ix = nil
478
+ n_include = 0
479
+ end
464
480
 
465
- if rated
481
+ if rated && !item_ids
466
482
  # assumes rated is unique and all items are known
467
483
  # calling code is responsible for this
468
484
  exclude_ix = int_ptr(rated)
@@ -1,3 +1,3 @@
1
1
  module Cmfrec
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cmfrec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-11 00:00:00.000000000 Z
11
+ date: 2021-08-12 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: andrew@ankane.org