cmfrec 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/CHANGELOG.md +5 -0
- data/README.md +27 -1
- data/lib/cmfrec.rb +3 -0
- data/lib/cmfrec/data.rb +100 -0
- data/lib/cmfrec/ffi.rb +7 -5
- data/lib/cmfrec/recommender.rb +47 -34
- data/lib/cmfrec/version.rb +1 -1
- data/vendor/libcmfrec.dylib +0 -0
- data/vendor/libcmfrec.so +0 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c19c6069b22f666ab280851cdfcaab346c1c08599be2e97043bdc41da552b6f
|
4
|
+
data.tar.gz: 6f0ffb63861b47568119e7014ff1c9d1a71fcf5852c6b1df2a8ca9b16bd239d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15104fb705c8bf1ffe3959846ddacde37a8845ee667c6ab334df6b1aacc7da42af894e2f94f1bfc35739943f8293b3f70e22358f7fc030e814c5dadbce4bb75e
|
7
|
+
data.tar.gz: 8d7806b1500de927ecca3705ade074a2dc197a5e413a3a0e755f3d952aa8916b10a87f635e7958726e315a05376c216c6c5a79b6d33f4a61d723e4bbfbbcd382
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Add this line to your application’s Gemfile:
|
|
16
16
|
gem 'cmfrec'
|
17
17
|
```
|
18
18
|
|
19
|
-
|
19
|
+
For Windows, also follow [these instructions](#windows-installation).
|
20
20
|
|
21
21
|
## Getting Started
|
22
22
|
|
@@ -107,6 +107,24 @@ Get recommendations with only side information
|
|
107
107
|
recommender.new_user_recs([], user_info: {cats: 0, dogs: 2})
|
108
108
|
```
|
109
109
|
|
110
|
+
## Examples
|
111
|
+
|
112
|
+
### MovieLens
|
113
|
+
|
114
|
+
Load the data
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
ratings, user_info, item_info = Cmfrec.load_movielens
|
118
|
+
```
|
119
|
+
|
120
|
+
Create a recommender and get predictions
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
recommender = Cmfrec::Recommender.new(factors: 20)
|
124
|
+
recommender.fit(ratings.first(80000), user_info: user_info, item_info: item_info)
|
125
|
+
recommender.predict(ratings.last(20000))
|
126
|
+
```
|
127
|
+
|
110
128
|
## Options
|
111
129
|
|
112
130
|
Specify the number of factors and epochs
|
@@ -167,6 +185,14 @@ recommender.user_bias
|
|
167
185
|
recommender.item_bias
|
168
186
|
```
|
169
187
|
|
188
|
+
## Windows Installation
|
189
|
+
|
190
|
+
On Windows, build the [cmfrec C shared library](https://github.com/david-cortes/cmfrec#instalation) and set:
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
Cmfrec.ffi_lib = "path/to/cmfrec.dll"
|
194
|
+
```
|
195
|
+
|
170
196
|
## History
|
171
197
|
|
172
198
|
View the [changelog](https://github.com/ankane/cmfrec/blob/master/CHANGELOG.md)
|
data/lib/cmfrec.rb
CHANGED
@@ -3,12 +3,15 @@ require "etc"
|
|
3
3
|
require "fiddle/import"
|
4
4
|
|
5
5
|
# modules
|
6
|
+
require "cmfrec/data"
|
6
7
|
require "cmfrec/recommender"
|
7
8
|
require "cmfrec/version"
|
8
9
|
|
9
10
|
module Cmfrec
|
10
11
|
class Error < StandardError; end
|
11
12
|
|
13
|
+
extend Data
|
14
|
+
|
12
15
|
class << self
|
13
16
|
attr_accessor :ffi_lib
|
14
17
|
end
|
data/lib/cmfrec/data.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
module Cmfrec
|
2
|
+
module Data
|
3
|
+
def load_movielens
|
4
|
+
require "csv"
|
5
|
+
|
6
|
+
data_path = download_file("ml-100k/u.data", "http://files.grouplens.org/datasets/movielens/ml-100k/u.data",
|
7
|
+
file_hash: "06416e597f82b7342361e41163890c81036900f418ad91315590814211dca490")
|
8
|
+
user_path = download_file("ml-100k/u.user", "http://files.grouplens.org/datasets/movielens/ml-100k/u.user",
|
9
|
+
file_hash: "f120e114da2e8cf314fd28f99417c94ae9ddf1cb6db8ce0e4b5995d40e90e62c")
|
10
|
+
item_path = download_file("ml-100k/u.item", "http://files.grouplens.org/datasets/movielens/ml-100k/u.item",
|
11
|
+
file_hash: "553841ebc7de3a0fd0d6b62a204ea30c1e651aacfb2814c7a6584ac52f2c5701")
|
12
|
+
|
13
|
+
# convert u.item to utf-8
|
14
|
+
movies_str = File.read(item_path).encode("UTF-8", "binary", invalid: :replace, undef: :replace, replace: "")
|
15
|
+
|
16
|
+
user_info = []
|
17
|
+
CSV.foreach(user_path, col_sep: "|") do |row|
|
18
|
+
user = {user_id: row[0].to_i}
|
19
|
+
10.times do |i|
|
20
|
+
user[:"region#{i}"] = row[4][0] == i.to_s ? 1 : 0
|
21
|
+
end
|
22
|
+
user_info << user
|
23
|
+
end
|
24
|
+
|
25
|
+
item_info = []
|
26
|
+
movies = {}
|
27
|
+
genres = %w(unknown action adventure animation childrens comedy crime documentary drama fantasy filmnoir horror musical mystery romance scifi thriller war western)
|
28
|
+
CSV.parse(movies_str, col_sep: "|", converters: [:numeric]) do |row|
|
29
|
+
movies[row[0]] = row[1]
|
30
|
+
item = {item_id: row[1], year: row[2] ? Date.parse(row[2]).year : 1970}
|
31
|
+
genres.each_with_index do |genre, i|
|
32
|
+
item[:"genre_#{genre}"] = row[i + 5]
|
33
|
+
end
|
34
|
+
item_info << item
|
35
|
+
end
|
36
|
+
|
37
|
+
data = []
|
38
|
+
CSV.foreach(data_path, col_sep: "\t", converters: [:numeric]) do |row|
|
39
|
+
data << {
|
40
|
+
user_id: row[0],
|
41
|
+
item_id: movies[row[1]],
|
42
|
+
rating: row[2]
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
[data, user_info, item_info]
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def download_file(fname, origin, file_hash:)
|
52
|
+
require "fileutils"
|
53
|
+
|
54
|
+
# TODO handle this better
|
55
|
+
raise "No HOME" unless ENV["HOME"]
|
56
|
+
dest = "#{ENV["HOME"]}/.cmfrec/#{fname}"
|
57
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
58
|
+
|
59
|
+
return dest if File.exist?(dest)
|
60
|
+
|
61
|
+
require "digest"
|
62
|
+
require "net/http"
|
63
|
+
require "tmpdir"
|
64
|
+
|
65
|
+
temp_path = "#{Dir.tmpdir}/cmfrec-#{Time.now.to_f}" # TODO better name
|
66
|
+
|
67
|
+
digest = Digest::SHA2.new
|
68
|
+
|
69
|
+
uri = URI(origin)
|
70
|
+
|
71
|
+
# Net::HTTP automatically adds Accept-Encoding for compression
|
72
|
+
# of response bodies and automatically decompresses gzip
|
73
|
+
# and deflateresponses unless a Range header was sent.
|
74
|
+
# https://ruby-doc.org/stdlib-2.6.4/libdoc/net/http/rdoc/Net/HTTP.html
|
75
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
|
76
|
+
request = Net::HTTP::Get.new(uri)
|
77
|
+
|
78
|
+
puts "Downloading data from #{origin}"
|
79
|
+
File.open(temp_path, "wb") do |f|
|
80
|
+
http.request(request) do |response|
|
81
|
+
response.read_body do |chunk|
|
82
|
+
f.write(chunk)
|
83
|
+
digest.update(chunk)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
if digest.hexdigest != file_hash
|
90
|
+
raise Error, "Bad hash: #{digest.hexdigest}"
|
91
|
+
end
|
92
|
+
|
93
|
+
puts "Hash verified: #{file_hash}"
|
94
|
+
|
95
|
+
FileUtils.mv(temp_path, dest)
|
96
|
+
|
97
|
+
dest
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/cmfrec/ffi.rb
CHANGED
@@ -10,17 +10,19 @@ module Cmfrec
|
|
10
10
|
raise e
|
11
11
|
end
|
12
12
|
|
13
|
+
# https://github.com/david-cortes/cmfrec/blob/master/src/cmfrec.h
|
14
|
+
|
13
15
|
typealias "bool", "char"
|
14
16
|
# determined by CMakeLists.txt
|
15
17
|
typealias "int_t", "int"
|
16
18
|
typealias "real_t", "double"
|
17
19
|
|
18
|
-
extern "int_t fit_collective_explicit_als(real_t *biasA, real_t *biasB, real_t *A, real_t *B, real_t *C, real_t *D, real_t *Ai, real_t *Bi, bool add_implicit_features, bool reset_values, int_t seed, real_t *glob_mean, real_t *U_colmeans, real_t *I_colmeans, int_t m, int_t n, int_t k, int_t
|
19
|
-
extern "int_t fit_collective_implicit_als(real_t *A, real_t *B, real_t *C, real_t *D, bool reset_values, int_t seed, real_t *U_colmeans, real_t *I_colmeans, int_t m, int_t n, int_t k, int_t
|
20
|
-
extern "int_t factors_collective_explicit_single(real_t *a_vec, real_t *a_bias,
|
21
|
-
extern "int_t factors_collective_implicit_single(real_t *a_vec,
|
22
|
-
extern "void predict_multiple(real_t *restrict A, int_t k_user, real_t *restrict B, int_t k_item, real_t *restrict biasA, real_t *restrict biasB, real_t glob_mean, int_t k, int_t k_main, int_t m, int_t n, int_t predA[], int_t predB[], size_t nnz, real_t *restrict outp, int_t nthreads)"
|
20
|
+
extern "int_t fit_collective_explicit_als(real_t *restrict biasA, real_t *restrict biasB, real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, real_t *restrict Ai, real_t *restrict Bi, bool add_implicit_features, bool reset_values, int_t seed, real_t *restrict glob_mean, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t *restrict Xfull, real_t *restrict weight, bool user_bias, bool item_bias, bool center, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, bool scale_lam, bool scale_lam_sideinfo, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_X, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t w_implicit, int_t niter, int_t nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, bool include_all_X, real_t *restrict B_plus_bias, real_t *restrict precomputedBtB, real_t *restrict precomputedTransBtBinvBt, real_t *restrict precomputedBtXbias, real_t *restrict precomputedBeTBeChol, real_t *restrict precomputedBiTBi, real_t *restrict precomputedTransCtCinvCt, real_t *restrict precomputedCtCw)"
|
21
|
+
extern "int_t fit_collective_implicit_als(real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, bool reset_values, int_t seed, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t *restrict w_main_multiplier, real_t alpha, bool adjust_weight, bool apply_log_transf, int_t niter, int_t nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, real_t *restrict precomputedBtB, real_t *restrict precomputedBeTBe, real_t *restrict precomputedBeTBeChol)"
|
22
|
+
extern "int_t factors_collective_explicit_single(real_t *restrict a_vec, real_t *restrict a_bias,real_t *restrict u_vec, int_t p,real_t *restrict u_vec_sp, int_t u_vec_ixB[], size_t nnz_u_vec,real_t *restrict u_bin_vec, int_t pbin,bool NA_as_zero_U, bool NA_as_zero_X,bool nonneg,real_t *restrict C, real_t *restrict Cb,real_t glob_mean, real_t *restrict biasB,real_t *restrict U_colmeans,real_t *restrict Xa, int_t ixB[], size_t nnz,real_t *restrict Xa_dense, int_t n,real_t *restrict weight,real_t *restrict B,real_t *restrict Bi, bool add_implicit_features,int_t k, int_t k_user, int_t k_item, int_t k_main,real_t lam, real_t *restrict lam_unique,real_t l1_lam, real_t *restrict l1_lam_unique,bool scale_lam, bool scale_lam_sideinfo,real_t w_main, real_t w_user, real_t w_implicit,int_t n_max, bool include_all_X,real_t *restrict BtB,real_t *restrict TransBtBinvBt,real_t *restrict BtXbias,real_t *restrict BeTBeChol,real_t *restrict BiTBi,real_t *restrict CtCw,real_t *restrict TransCtCinvCt,real_t *restrict B_plus_bias)"
|
23
|
+
extern "int_t factors_collective_implicit_single(real_t *restrict a_vec,real_t *restrict u_vec, int_t p,real_t *restrict u_vec_sp, int_t u_vec_ixB[], size_t nnz_u_vec,bool NA_as_zero_U,bool nonneg,real_t *restrict U_colmeans,real_t *restrict B, int_t n, real_t *restrict C,real_t *restrict Xa, int_t ixB[], size_t nnz,int_t k, int_t k_user, int_t k_item, int_t k_main,real_t lam, real_t l1_lam, real_t alpha, real_t w_main, real_t w_user,real_t w_main_multiplier,bool apply_log_transf,real_t *restrict BeTBe,real_t *restrict BtB,real_t *restrict BeTBeChol)"
|
23
24
|
extern "int_t predict_X_old_collective_explicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict biasA, real_t *restrict B, real_t *restrict biasB, real_t glob_mean, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n_max, int_t nthreads)"
|
25
|
+
extern "int_t predict_X_old_collective_implicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict B, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n, int_t nthreads)"
|
24
26
|
extern "int_t topN(real_t *restrict a_vec, int_t k_user, real_t *restrict B, int_t k_item, real_t *restrict biasB, real_t glob_mean, real_t biasA, int_t k, int_t k_main, int_t *restrict include_ix, int_t n_include, int_t *restrict exclude_ix, int_t n_exclude, int_t *restrict outp_ix, real_t *restrict outp_score, int_t n_top, int_t n, int_t nthreads)"
|
25
27
|
end
|
26
28
|
end
|
data/lib/cmfrec/recommender.rb
CHANGED
@@ -46,6 +46,8 @@ module Cmfrec
|
|
46
46
|
x_full = nil
|
47
47
|
weight = nil
|
48
48
|
lam_unique = nil
|
49
|
+
l1_lambda = 0
|
50
|
+
l1_lam_unique = nil
|
49
51
|
|
50
52
|
uu = nil
|
51
53
|
ii = nil
|
@@ -92,6 +94,7 @@ module Cmfrec
|
|
92
94
|
@m, @n, @k,
|
93
95
|
x_row, x_col, x, nnz,
|
94
96
|
@lambda_, lam_unique,
|
97
|
+
l1_lambda, l1_lam_unique,
|
95
98
|
uu, @m_u, p_,
|
96
99
|
ii, @n_i, q,
|
97
100
|
u_row, u_col, u_sp, nnz_u,
|
@@ -125,6 +128,10 @@ module Cmfrec
|
|
125
128
|
|
126
129
|
glob_mean = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE)
|
127
130
|
|
131
|
+
center = true
|
132
|
+
scale_lam = false
|
133
|
+
scale_lam_sideinfo = false
|
134
|
+
|
128
135
|
args = [
|
129
136
|
@bias_a, @bias_b,
|
130
137
|
@a, @b,
|
@@ -138,8 +145,10 @@ module Cmfrec
|
|
138
145
|
x_row, x_col, x, nnz,
|
139
146
|
x_full,
|
140
147
|
weight,
|
141
|
-
@user_bias, @item_bias,
|
148
|
+
@user_bias, @item_bias, center,
|
142
149
|
@lambda_, lam_unique,
|
150
|
+
l1_lambda, l1_lam_unique,
|
151
|
+
scale_lam, scale_lam_sideinfo,
|
143
152
|
uu, @m_u, p_,
|
144
153
|
ii, @n_i, q,
|
145
154
|
u_row, u_col, u_sp, nnz_u,
|
@@ -155,6 +164,7 @@ module Cmfrec
|
|
155
164
|
nil, #B_plus_bias,
|
156
165
|
nil, #precomputedBtB,
|
157
166
|
nil, #precomputedTransBtBinvBt,
|
167
|
+
nil, #precomputedBtXbias
|
158
168
|
nil, #precomputedBeTBeChol,
|
159
169
|
nil, #precomputedBiTBi,
|
160
170
|
nil, #precomputedTransCtCinvCt,
|
@@ -177,41 +187,36 @@ module Cmfrec
|
|
177
187
|
|
178
188
|
data = to_dataset(data)
|
179
189
|
|
180
|
-
u = data.map { |v| @user_map[v[:user_id]] ||
|
181
|
-
i = data.map { |v| @item_map[v[:item_id]] ||
|
182
|
-
|
183
|
-
pred_a = int_ptr(u)
|
184
|
-
pred_b = int_ptr(i)
|
185
|
-
nnz = data.size
|
186
|
-
outp = Fiddle::Pointer.malloc(nnz * Fiddle::SIZEOF_DOUBLE)
|
190
|
+
u = data.map { |v| @user_map[v[:user_id]] || @user_map.size }
|
191
|
+
i = data.map { |v| @item_map[v[:item_id]] || @item_map.size }
|
187
192
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
@global_mean,
|
193
|
-
@k, @k_main,
|
194
|
-
@m, @n,
|
195
|
-
pred_a, pred_b, nnz,
|
196
|
-
outp,
|
197
|
-
@nthreads
|
198
|
-
)
|
193
|
+
row = int_ptr(u)
|
194
|
+
col = int_ptr(i)
|
195
|
+
n_predict = data.size
|
196
|
+
predicted = Fiddle::Pointer.malloc(n_predict * Fiddle::SIZEOF_DOUBLE)
|
199
197
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
198
|
+
if @implicit
|
199
|
+
check_status FFI.predict_X_old_collective_implicit(
|
200
|
+
row, col, predicted, n_predict,
|
201
|
+
@a, @b,
|
202
|
+
@k, @k_user, @k_item, @k_main,
|
203
|
+
@m, @n,
|
204
|
+
@nthreads
|
205
|
+
)
|
206
|
+
else
|
207
|
+
check_status FFI.predict_X_old_collective_explicit(
|
208
|
+
row, col, predicted, n_predict,
|
209
|
+
@a, @bias_a,
|
210
|
+
@b, @bias_b,
|
211
|
+
@global_mean,
|
212
|
+
@k, @k_user, @k_item, @k_main,
|
213
|
+
@m, @n,
|
214
|
+
@nthreads
|
215
|
+
)
|
213
216
|
end
|
214
217
|
|
218
|
+
predictions = real_array(predicted)
|
219
|
+
predictions.map! { |v| v.nan? ? @global_mean : v } if @implicit
|
215
220
|
predictions
|
216
221
|
end
|
217
222
|
|
@@ -448,6 +453,8 @@ module Cmfrec
|
|
448
453
|
|
449
454
|
weight = nil
|
450
455
|
lam_unique = nil
|
456
|
+
l1_lambda = 0
|
457
|
+
l1_lam_unique = nil
|
451
458
|
n_max = @n
|
452
459
|
|
453
460
|
if data.any?
|
@@ -476,7 +483,7 @@ module Cmfrec
|
|
476
483
|
@b, @n, @c,
|
477
484
|
xa, x_col, nnz,
|
478
485
|
@k, @k_user, @k_item, @k_main,
|
479
|
-
@lambda_, @alpha,
|
486
|
+
@lambda_, l1_lambda, @alpha,
|
480
487
|
@w_main, @w_user, @w_main_multiplier,
|
481
488
|
@apply_log_transf,
|
482
489
|
nil, #BeTBe,
|
@@ -487,6 +494,9 @@ module Cmfrec
|
|
487
494
|
else
|
488
495
|
cb = nil
|
489
496
|
|
497
|
+
scale_lam = false
|
498
|
+
scale_lam_sideinfo = false
|
499
|
+
|
490
500
|
args = [
|
491
501
|
a_vec, bias_a,
|
492
502
|
u_vec, p_,
|
@@ -501,11 +511,14 @@ module Cmfrec
|
|
501
511
|
@add_implicit_features,
|
502
512
|
@k, @k_user, @k_item, @k_main,
|
503
513
|
@lambda_, lam_unique,
|
514
|
+
l1_lambda, l1_lam_unique,
|
515
|
+
scale_lam, scale_lam_sideinfo,
|
504
516
|
@w_main, @w_user, @w_implicit,
|
505
517
|
n_max,
|
506
518
|
@include_all_x,
|
507
|
-
nil, #TransBtBinvBt,
|
508
519
|
nil, #BtB,
|
520
|
+
nil, #TransBtBinvBt,
|
521
|
+
nil, #BtXbias,
|
509
522
|
nil, #BeTBeChol,
|
510
523
|
nil, #BiTBi,
|
511
524
|
nil, #CtCw,
|
data/lib/cmfrec/version.rb
CHANGED
data/vendor/libcmfrec.dylib
CHANGED
Binary file
|
data/vendor/libcmfrec.so
CHANGED
Binary file
|
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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@chartkick.com
|
@@ -20,6 +20,7 @@ files:
|
|
20
20
|
- LICENSE.txt
|
21
21
|
- README.md
|
22
22
|
- lib/cmfrec.rb
|
23
|
+
- lib/cmfrec/data.rb
|
23
24
|
- lib/cmfrec/ffi.rb
|
24
25
|
- lib/cmfrec/recommender.rb
|
25
26
|
- lib/cmfrec/version.rb
|