cmfrec 0.1.5 → 0.1.6
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/CHANGELOG.md +10 -0
- data/README.md +7 -0
- data/lib/cmfrec/recommender.rb +57 -41
- data/lib/cmfrec/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34e8dc08914cbc418470cd7eb3adf3d33013b786319f4510212c80bf3629f3ca
|
4
|
+
data.tar.gz: c1b91a1f77b4b51a5ca4491376f8a02230ea54873f8c1b2b06f4761d6ddd0686
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/lib/cmfrec/recommender.rb
CHANGED
@@ -67,23 +67,10 @@ module Cmfrec
|
|
67
67
|
user = @user_map[user_id]
|
68
68
|
|
69
69
|
if user
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
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
|
-
|
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
|
-
|
451
|
-
|
452
|
-
|
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
|
-
|
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
|
-
|
463
|
-
|
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)
|
data/lib/cmfrec/version.rb
CHANGED
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.
|
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
|
+
date: 2021-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|