cmfrec 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -2
- data/lib/cmfrec/data.rb +2 -1
- data/lib/cmfrec/ffi.rb +8 -7
- data/lib/cmfrec/recommender.rb +202 -156
- data/lib/cmfrec/version.rb +1 -1
- data/lib/cmfrec.rb +6 -6
- data/vendor/arm64-darwin/COPYRIGHTS +57 -0
- data/vendor/arm64-darwin/LICENSE +23 -0
- data/vendor/arm64-darwin/libcmfrec.dylib +0 -0
- data/vendor/x86_64-darwin/COPYRIGHTS +57 -0
- data/vendor/x86_64-darwin/LICENSE +23 -0
- data/vendor/x86_64-darwin/libcmfrec.dylib +0 -0
- data/vendor/x86_64-linux/COPYRIGHTS +57 -0
- data/vendor/x86_64-linux/LICENSE +23 -0
- data/vendor/x86_64-linux/libcmfrec.so +0 -0
- metadata +12 -7
- data/vendor/LICENSE.txt +0 -74
- data/vendor/libcmfrec.arm64.dylib +0 -0
- data/vendor/libcmfrec.dylib +0 -0
- data/vendor/libcmfrec.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e6dbbc801e415a4f505ffc436be23ccf066d144da072669e782b88c02e14b0f8
|
4
|
+
data.tar.gz: 3851230f0a4dc4be9fbc24fe81681de0758bdbb583803780f8e07b10741f4bd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 103c09a7c0e13fca3cb81dc68c667e776fc965a485cf358e0fc8f350a97474b54bdfc0910f4472051020dbe34b8c097908c1024d5fc036ad77d0444372885109
|
7
|
+
data.tar.gz: b107b36333f714106d981168f24fda48a2a211f288a2dbe01f570adb607b7d6a5215c18df4c67d159bb367d652f3d10faeb4dbc66688eaf117c5b7a1432ee951
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
Add this line to your application’s Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem
|
16
|
+
gem "cmfrec"
|
17
17
|
```
|
18
18
|
|
19
19
|
For Windows, also follow [these instructions](#windows-installation).
|
@@ -112,7 +112,7 @@ recommender.new_user_recs([], user_info: {cats: 0, dogs: 2})
|
|
112
112
|
Add this line to your application’s Gemfile:
|
113
113
|
|
114
114
|
```ruby
|
115
|
-
gem
|
115
|
+
gem "ngt"
|
116
116
|
```
|
117
117
|
|
118
118
|
Get similar users
|
data/lib/cmfrec/data.rb
CHANGED
@@ -27,11 +27,12 @@ module Cmfrec
|
|
27
27
|
movie_names = {}
|
28
28
|
genres = %w(unknown action adventure animation childrens comedy crime documentary drama fantasy filmnoir horror musical mystery romance scifi thriller war western)
|
29
29
|
CSV.parse(movies_str, col_sep: "|", converters: [:numeric]) do |row|
|
30
|
+
movies[row[0]] = row[1]
|
31
|
+
|
30
32
|
# filter duplicates
|
31
33
|
next if movie_names[row[1]]
|
32
34
|
movie_names[row[1]] = true
|
33
35
|
|
34
|
-
movies[row[0]] = row[1]
|
35
36
|
item = {item_id: row[1], year: row[2] ? Date.parse(row[2]).year : 1970}
|
36
37
|
genres.each_with_index do |genre, i|
|
37
38
|
item[:"genre_#{genre}"] = row[i + 5]
|
data/lib/cmfrec/ffi.rb
CHANGED
@@ -17,12 +17,13 @@ module Cmfrec
|
|
17
17
|
typealias "int_t", "int"
|
18
18
|
typealias "real_t", "double"
|
19
19
|
|
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,
|
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,
|
22
|
-
extern "int_t
|
23
|
-
extern "int_t
|
24
|
-
extern "int_t
|
25
|
-
extern "int_t
|
26
|
-
extern "int_t
|
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, bool scale_bias_const, real_t *scaling_biasA, real_t *scaling_biasB, 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 nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool precondition_cg, 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, real_t *precomputedCtUbias)"
|
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 nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool precondition_cg, 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, real_t *precomputedCtUbias)"
|
22
|
+
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 nthreads)"
|
23
|
+
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 nthreads)"
|
24
|
+
extern "int_t topN_old_collective_explicit(real_t *a_vec, real_t a_bias, real_t *A, real_t *biasA, int_t row_index, real_t *B, real_t *biasB, real_t glob_mean, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int_t n, int_t n_max, bool include_all_X, int nthreads)"
|
25
|
+
extern "int_t topN_old_collective_implicit(real_t *a_vec, real_t *A, int_t row_index, real_t *B, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int_t n, int nthreads)"
|
26
|
+
extern "int_t topN_new_collective_explicit(bool user_bias, real_t *u_vec, int_t p, real_t *u_vec_sp, int_t u_vec_X_col[], size_t nnz_u_vec, real_t *u_bin_vec, int_t pbin, bool NA_as_zero_U, bool NA_as_zero_X, bool nonneg, real_t *C, real_t *Cb, real_t glob_mean, real_t *biasB, real_t *U_colmeans, real_t *Xa, int_t X_col[], size_t nnz, real_t *Xa_dense, int_t n, real_t *weight, real_t *B, real_t *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 *lam_unique, real_t l1_lam, real_t *l1_lam_unique, bool scale_lam, bool scale_lam_sideinfo, bool scale_bias_const, real_t scaling_biasA, real_t w_main, real_t w_user, real_t w_implicit, int_t n_max, bool include_all_X, real_t *BtB, real_t *TransBtBinvBt, real_t *BtXbias, real_t *BeTBeChol, real_t *BiTBi, real_t *CtCw, real_t *TransCtCinvCt, real_t *CtUbias, real_t *B_plus_bias, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int nthreads)"
|
27
|
+
extern "int_t topN_new_collective_implicit(int_t n, real_t *u_vec, int_t p, real_t *u_vec_sp, int_t u_vec_X_col[], size_t nnz_u_vec, bool NA_as_zero_U, bool nonneg, real_t *U_colmeans, real_t *B, real_t *C, real_t *Xa, int_t X_col[], 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 *BeTBe, real_t *BtB, real_t *BeTBeChol, real_t *CtUbias, int_t *include_ix, int_t n_include, int_t *exclude_ix, int_t n_exclude, int_t *outp_ix, real_t *outp_score, int_t n_top, int nthreads)"
|
27
28
|
end
|
28
29
|
end
|
data/lib/cmfrec/recommender.rb
CHANGED
@@ -70,7 +70,7 @@ module Cmfrec
|
|
70
70
|
a_vec = @a[user * @k * Fiddle::SIZEOF_DOUBLE, @k * Fiddle::SIZEOF_DOUBLE]
|
71
71
|
a_bias = @bias_a ? @bias_a[user * Fiddle::SIZEOF_DOUBLE, Fiddle::SIZEOF_DOUBLE].unpack1("d") : 0
|
72
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)
|
73
|
+
top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: (@rated[user] || {}).keys, item_ids: item_ids, row_index: user)
|
74
74
|
else
|
75
75
|
# no items if user is unknown
|
76
76
|
# TODO maybe most popular items
|
@@ -81,8 +81,137 @@ module Cmfrec
|
|
81
81
|
def new_user_recs(data, count: 5, user_info: nil, item_ids: nil)
|
82
82
|
check_fit
|
83
83
|
|
84
|
-
|
85
|
-
|
84
|
+
data = to_dataset(data)
|
85
|
+
user_info = to_dataset(user_info) if user_info
|
86
|
+
|
87
|
+
# remove unknown items
|
88
|
+
data, unknown_data = data.partition { |d| @item_map[d[:item_id]] }
|
89
|
+
|
90
|
+
if unknown_data.any?
|
91
|
+
# TODO warn for unknown items?
|
92
|
+
# warn "[cmfrec] Unknown items: #{unknown_data.map { |d| d[:item_id] }.join(", ")}"
|
93
|
+
end
|
94
|
+
|
95
|
+
rated_ids = data.map { |d| @item_map[d[:item_id]] }
|
96
|
+
|
97
|
+
nnz = data.size
|
98
|
+
|
99
|
+
u_vec_sp = []
|
100
|
+
u_vec_x_col = []
|
101
|
+
if user_info
|
102
|
+
user_info.each do |k, v|
|
103
|
+
next if k == :user_id
|
104
|
+
|
105
|
+
uc = @user_info_map[k]
|
106
|
+
raise "Bad key: #{k}" unless uc
|
107
|
+
|
108
|
+
u_vec_x_col << uc
|
109
|
+
u_vec_sp << v
|
110
|
+
end
|
111
|
+
end
|
112
|
+
p_ = @user_info_map.size
|
113
|
+
nnz_u_vec = u_vec_sp.size
|
114
|
+
u_vec_x_col = int_ptr(u_vec_x_col)
|
115
|
+
u_vec_sp = real_ptr(u_vec_sp)
|
116
|
+
|
117
|
+
u_vec = nil
|
118
|
+
u_bin_vec = nil
|
119
|
+
pbin = 0
|
120
|
+
|
121
|
+
weight = nil
|
122
|
+
lam_unique = nil
|
123
|
+
l1_lam_unique = nil
|
124
|
+
n_max = @n
|
125
|
+
|
126
|
+
if data.any?
|
127
|
+
if @implicit
|
128
|
+
ratings = data.map { |d| d[:value] || 1 }
|
129
|
+
else
|
130
|
+
ratings = data.map { |d| d[:rating] }
|
131
|
+
check_ratings(ratings)
|
132
|
+
end
|
133
|
+
xa = real_ptr(ratings)
|
134
|
+
x_col = int_ptr(rated_ids)
|
135
|
+
else
|
136
|
+
xa = nil
|
137
|
+
x_col = nil
|
138
|
+
end
|
139
|
+
xa_dense = nil
|
140
|
+
|
141
|
+
rated = rated_ids.uniq
|
142
|
+
|
143
|
+
prep = prepare_top_n(count: count, rated: rated, item_ids: item_ids)
|
144
|
+
return [] if prep.empty?
|
145
|
+
include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count = prep
|
146
|
+
|
147
|
+
if @implicit
|
148
|
+
args = [
|
149
|
+
@n,
|
150
|
+
u_vec, p_,
|
151
|
+
u_vec_sp, u_vec_x_col, nnz_u_vec,
|
152
|
+
@na_as_zero_user,
|
153
|
+
@nonneg,
|
154
|
+
@u_colmeans,
|
155
|
+
@b, @c,
|
156
|
+
xa, x_col, nnz,
|
157
|
+
@k, @k_user, @k_item, @k_main,
|
158
|
+
@lambda_, @l1_lambda, @alpha, @w_main, @w_user,
|
159
|
+
@w_main_multiplier,
|
160
|
+
@apply_log_transf,
|
161
|
+
nil, #BeTBe,
|
162
|
+
nil, #BtB,
|
163
|
+
nil, #BeTBeChol,
|
164
|
+
nil, #CtUbias,
|
165
|
+
include_ix, n_include,
|
166
|
+
exclude_ix, n_exclude,
|
167
|
+
outp_ix, outp_score,
|
168
|
+
count, @nthreads
|
169
|
+
]
|
170
|
+
check_status FFI.topN_new_collective_implicit(*fiddle_args(args))
|
171
|
+
else
|
172
|
+
cb = nil
|
173
|
+
scaling_bias_a = 0
|
174
|
+
|
175
|
+
args = [
|
176
|
+
@user_bias,
|
177
|
+
u_vec, p_,
|
178
|
+
u_vec_sp, u_vec_x_col, nnz_u_vec,
|
179
|
+
u_bin_vec, pbin,
|
180
|
+
@na_as_zero_user, @na_as_zero,
|
181
|
+
@nonneg,
|
182
|
+
@c, cb,
|
183
|
+
@global_mean, @bias_b,
|
184
|
+
@u_colmeans,
|
185
|
+
xa, x_col, nnz,
|
186
|
+
xa_dense, @n,
|
187
|
+
weight,
|
188
|
+
@b,
|
189
|
+
@bi, @add_implicit_features,
|
190
|
+
@k, @k_user, @k_item, @k_main,
|
191
|
+
@lambda_, lam_unique,
|
192
|
+
@l1_lambda, l1_lam_unique,
|
193
|
+
@scale_lam, @scale_lam_sideinfo,
|
194
|
+
@scale_bias_const, scaling_bias_a,
|
195
|
+
@w_main, @w_user, @w_implicit,
|
196
|
+
n_max, @include_all_x,
|
197
|
+
nil, #BtB,
|
198
|
+
nil, #TransBtBinvBt,
|
199
|
+
nil, #BtXbias,
|
200
|
+
nil, #BeTBeChol,
|
201
|
+
nil, #BiTBi,
|
202
|
+
nil, #CtCw,
|
203
|
+
nil, #TransCtCinvCt,
|
204
|
+
nil, #CtUbias,
|
205
|
+
nil, #B_plus_bias,
|
206
|
+
include_ix, n_include,
|
207
|
+
exclude_ix, n_exclude,
|
208
|
+
outp_ix, outp_score,
|
209
|
+
count, @nthreads
|
210
|
+
]
|
211
|
+
check_status FFI.topN_new_collective_explicit(*fiddle_args(args))
|
212
|
+
end
|
213
|
+
|
214
|
+
top_n_output(outp_ix, outp_score)
|
86
215
|
end
|
87
216
|
|
88
217
|
def user_ids
|
@@ -210,7 +339,6 @@ module Cmfrec
|
|
210
339
|
x_full = nil
|
211
340
|
weight = nil
|
212
341
|
lam_unique = nil
|
213
|
-
l1_lambda = 0
|
214
342
|
l1_lam_unique = nil
|
215
343
|
|
216
344
|
uu = nil
|
@@ -247,7 +375,7 @@ module Cmfrec
|
|
247
375
|
@m, @n, @k,
|
248
376
|
x_row, x_col, x, nnz,
|
249
377
|
@lambda_, lam_unique,
|
250
|
-
l1_lambda, l1_lam_unique,
|
378
|
+
@l1_lambda, l1_lam_unique,
|
251
379
|
uu, @m_u, p_,
|
252
380
|
ii, @n_i, q,
|
253
381
|
u_row, u_col, u_sp, nnz_u,
|
@@ -257,12 +385,13 @@ module Cmfrec
|
|
257
385
|
@w_main, @w_user, @w_item, real_ptr([@w_main_multiplier]),
|
258
386
|
@alpha, @adjust_weight, @apply_log_transf,
|
259
387
|
@niter, @nthreads, @verbose, @handle_interrupt,
|
260
|
-
@use_cg, @max_cg_steps, @finalize_chol,
|
388
|
+
@use_cg, @max_cg_steps, @precondition_cg, @finalize_chol,
|
261
389
|
@nonneg, @max_cd_steps, @nonneg_c, @nonneg_d,
|
262
390
|
@precompute_for_predictions,
|
263
391
|
nil, #precomputedBtB,
|
264
392
|
nil, #precomputedBeTBe,
|
265
|
-
nil
|
393
|
+
nil, #precomputedBeTBeChol
|
394
|
+
nil #precomputedCtUbias
|
266
395
|
]
|
267
396
|
check_status FFI.fit_collective_implicit_als(*fiddle_args(args))
|
268
397
|
|
@@ -281,9 +410,9 @@ module Cmfrec
|
|
281
410
|
|
282
411
|
glob_mean = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE)
|
283
412
|
|
284
|
-
|
285
|
-
|
286
|
-
|
413
|
+
# TODO add
|
414
|
+
scaling_bias_a = nil
|
415
|
+
scaling_bias_b = nil
|
287
416
|
|
288
417
|
args = [
|
289
418
|
@bias_a, @bias_b,
|
@@ -298,10 +427,11 @@ module Cmfrec
|
|
298
427
|
x_row, x_col, x, nnz,
|
299
428
|
x_full,
|
300
429
|
weight,
|
301
|
-
@user_bias, @item_bias, center,
|
430
|
+
@user_bias, @item_bias, @center,
|
302
431
|
@lambda_, lam_unique,
|
303
|
-
l1_lambda, l1_lam_unique,
|
304
|
-
scale_lam, scale_lam_sideinfo,
|
432
|
+
@l1_lambda, l1_lam_unique,
|
433
|
+
@scale_lam, @scale_lam_sideinfo,
|
434
|
+
@scale_bias_const, scaling_bias_a, scaling_bias_b,
|
305
435
|
uu, @m_u, p_,
|
306
436
|
ii, @n_i, q,
|
307
437
|
u_row, u_col, u_sp, nnz_u,
|
@@ -310,7 +440,7 @@ module Cmfrec
|
|
310
440
|
@k_main, @k_user, @k_item,
|
311
441
|
@w_main, @w_user, @w_item, @w_implicit,
|
312
442
|
@niter, @nthreads, @verbose, @handle_interrupt,
|
313
|
-
@use_cg, @max_cg_steps, @finalize_chol,
|
443
|
+
@use_cg, @max_cg_steps, @precondition_cg, @finalize_chol,
|
314
444
|
@nonneg, @max_cd_steps, @nonneg_c, @nonneg_d,
|
315
445
|
@precompute_for_predictions,
|
316
446
|
@include_all_x,
|
@@ -321,7 +451,8 @@ module Cmfrec
|
|
321
451
|
nil, #precomputedBeTBeChol,
|
322
452
|
nil, #precomputedBiTBi,
|
323
453
|
nil, #precomputedTransCtCinvCt,
|
324
|
-
nil
|
454
|
+
nil, #precomputedCtCw
|
455
|
+
nil, #precomputedCtUbias
|
325
456
|
]
|
326
457
|
check_status FFI.fit_collective_explicit_als(*fiddle_args(args))
|
327
458
|
|
@@ -336,21 +467,20 @@ module Cmfrec
|
|
336
467
|
end
|
337
468
|
|
338
469
|
def set_params(
|
339
|
-
k: 40, lambda_:
|
340
|
-
item_bias: true, add_implicit_features: false,
|
470
|
+
k: 40, lambda_: 10.0, method: "als", use_cg: true,
|
471
|
+
user_bias: true, item_bias: true, center: true, add_implicit_features: false,
|
472
|
+
scale_lam: false, scale_lam_sideinfo: false, scale_bias_const: false,
|
341
473
|
k_user: 0, k_item: 0, k_main: 0,
|
342
474
|
w_main: 1.0, w_user: 1.0, w_item: 1.0, w_implicit: 0.5,
|
475
|
+
l1_lambda: 0.0, center_u: true, center_i: true,
|
343
476
|
maxiter: 800, niter: 10, parallelize: "separate", corr_pairs: 4,
|
344
|
-
max_cg_steps: 3, finalize_chol: true,
|
477
|
+
max_cg_steps: 3, precondition_cg: false, finalize_chol: true,
|
345
478
|
na_as_zero: false, na_as_zero_user: false, na_as_zero_item: false,
|
346
479
|
nonneg: false, nonneg_c: false, nonneg_d: false, max_cd_steps: 100,
|
347
480
|
precompute_for_predictions: true, include_all_x: true,
|
348
|
-
use_float:
|
349
|
-
|
350
|
-
handle_interrupt: true, produce_dicts: false,
|
351
|
-
copy_data: true, nthreads: -1
|
481
|
+
use_float: true, random_state: 1, verbose: true, print_every: 10,
|
482
|
+
handle_interrupt: true, produce_dicts: false, nthreads: -1
|
352
483
|
)
|
353
|
-
|
354
484
|
@k = k
|
355
485
|
@k_user = k_user
|
356
486
|
@k_item = k_item
|
@@ -386,9 +516,17 @@ module Cmfrec
|
|
386
516
|
@random_state = random_state.to_i
|
387
517
|
@produce_dicts = !!produce_dicts
|
388
518
|
@handle_interrupt = !!handle_interrupt
|
389
|
-
@copy_data = !!copy_data
|
390
519
|
nthreads = Etc.nprocessors if nthreads < 0
|
391
520
|
@nthreads = nthreads
|
521
|
+
|
522
|
+
@center = center
|
523
|
+
@scale_lam = scale_lam
|
524
|
+
@scale_lam_sideinfo = scale_lam_sideinfo
|
525
|
+
@scale_bias_const = scale_bias_const
|
526
|
+
@l1_lambda = l1_lambda
|
527
|
+
@precondition_cg = precondition_cg
|
528
|
+
|
529
|
+
# TODO center_u, center_i
|
392
530
|
end
|
393
531
|
|
394
532
|
def update_maps(train_set)
|
@@ -462,7 +600,7 @@ module Cmfrec
|
|
462
600
|
end
|
463
601
|
end
|
464
602
|
|
465
|
-
def
|
603
|
+
def prepare_top_n(count: nil, rated: nil, item_ids: nil)
|
466
604
|
if item_ids
|
467
605
|
# remove missing ids
|
468
606
|
item_ids = item_ids.map { |v| @item_map[v] }.compact
|
@@ -471,8 +609,7 @@ module Cmfrec
|
|
471
609
|
include_ix = int_ptr(item_ids)
|
472
610
|
n_include = item_ids.size
|
473
611
|
|
474
|
-
|
475
|
-
count = n_include # if n_include < count
|
612
|
+
count = n_include if n_include < count
|
476
613
|
else
|
477
614
|
include_ix = nil
|
478
615
|
n_include = 0
|
@@ -494,145 +631,54 @@ module Cmfrec
|
|
494
631
|
outp_ix = Fiddle::Pointer.malloc(count * Fiddle::SIZEOF_INT)
|
495
632
|
outp_score = Fiddle::Pointer.malloc(count * Fiddle::SIZEOF_DOUBLE)
|
496
633
|
|
497
|
-
|
498
|
-
a_vec, @k_user,
|
499
|
-
@b, @k_item,
|
500
|
-
@bias_b, @global_mean, a_bias,
|
501
|
-
@k, @k_main,
|
502
|
-
include_ix, n_include,
|
503
|
-
exclude_ix, n_exclude,
|
504
|
-
outp_ix, outp_score,
|
505
|
-
count, @n,
|
506
|
-
@nthreads
|
507
|
-
)
|
508
|
-
|
509
|
-
imap = @item_map.map(&:reverse).to_h
|
510
|
-
item_ids = int_array(outp_ix).map { |v| imap[v] }
|
511
|
-
scores = real_array(outp_score)
|
512
|
-
|
513
|
-
item_ids.zip(scores).map do |item_id, score|
|
514
|
-
{item_id: item_id, score: score}
|
515
|
-
end
|
634
|
+
[include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count]
|
516
635
|
end
|
517
636
|
|
518
|
-
def
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
# remove unknown items
|
523
|
-
data, unknown_data = data.partition { |d| @item_map[d[:item_id]] }
|
524
|
-
|
525
|
-
if unknown_data.any?
|
526
|
-
# TODO warn for unknown items?
|
527
|
-
# warn "[cmfrec] Unknown items: #{unknown_data.map { |d| d[:item_id] }.join(", ")}"
|
528
|
-
end
|
529
|
-
|
530
|
-
item_ids = data.map { |d| @item_map[d[:item_id]] }
|
531
|
-
|
532
|
-
nnz = data.size
|
533
|
-
a_vec = Fiddle::Pointer.malloc((@k_user + @k + @k_main) * Fiddle::SIZEOF_DOUBLE)
|
534
|
-
bias_a = Fiddle::Pointer.malloc(Fiddle::SIZEOF_DOUBLE)
|
535
|
-
|
536
|
-
u_vec_sp = []
|
537
|
-
u_vec_x_col = []
|
538
|
-
if user_info
|
539
|
-
user_info.each do |k, v|
|
540
|
-
next if k == :user_id
|
541
|
-
|
542
|
-
uc = @user_info_map[k]
|
543
|
-
raise "Bad key: #{k}" unless uc
|
544
|
-
|
545
|
-
u_vec_x_col << uc
|
546
|
-
u_vec_sp << v
|
547
|
-
end
|
548
|
-
end
|
549
|
-
p_ = @user_info_map.size
|
550
|
-
nnz_u_vec = u_vec_sp.size
|
551
|
-
u_vec_x_col = int_ptr(u_vec_x_col)
|
552
|
-
u_vec_sp = real_ptr(u_vec_sp)
|
553
|
-
|
554
|
-
u_vec = nil
|
555
|
-
u_bin_vec = nil
|
556
|
-
pbin = 0
|
557
|
-
|
558
|
-
weight = nil
|
559
|
-
lam_unique = nil
|
560
|
-
l1_lambda = 0
|
561
|
-
l1_lam_unique = nil
|
562
|
-
n_max = @n
|
563
|
-
|
564
|
-
if data.any?
|
565
|
-
if @implicit
|
566
|
-
ratings = data.map { |d| d[:value] || 1 }
|
567
|
-
else
|
568
|
-
ratings = data.map { |d| d[:rating] }
|
569
|
-
check_ratings(ratings)
|
570
|
-
end
|
571
|
-
xa = real_ptr(ratings)
|
572
|
-
x_col = int_ptr(item_ids)
|
573
|
-
else
|
574
|
-
xa = nil
|
575
|
-
x_col = nil
|
576
|
-
end
|
577
|
-
xa_dense = nil
|
637
|
+
def top_n(a_vec:, a_bias:, count:, rated: nil, item_ids: nil, row_index:)
|
638
|
+
prep = prepare_top_n(count: count, rated: rated, item_ids: item_ids)
|
639
|
+
return [] if prep.empty?
|
640
|
+
include_ix, n_include, exclude_ix, n_exclude, outp_ix, outp_score, count = prep
|
578
641
|
|
579
642
|
if @implicit
|
580
|
-
|
643
|
+
check_status FFI.topN_old_collective_implicit(
|
581
644
|
a_vec,
|
582
|
-
|
583
|
-
|
584
|
-
@na_as_zero_user,
|
585
|
-
@nonneg,
|
586
|
-
@u_colmeans,
|
587
|
-
@b, @n, @c,
|
588
|
-
xa, x_col, nnz,
|
645
|
+
@a, row_index,
|
646
|
+
@b,
|
589
647
|
@k, @k_user, @k_item, @k_main,
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
nil #BeTBeChol
|
596
|
-
]
|
597
|
-
check_status FFI.factors_collective_implicit_single(*fiddle_args(args))
|
648
|
+
include_ix, n_include,
|
649
|
+
exclude_ix, n_exclude,
|
650
|
+
outp_ix, outp_score,
|
651
|
+
count, @n, @nthreads
|
652
|
+
)
|
598
653
|
else
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
u_bin_vec, pbin,
|
609
|
-
@na_as_zero_user, @na_as_zero,
|
610
|
-
@nonneg,
|
611
|
-
@c, cb,
|
612
|
-
@global_mean, @bias_b, @u_colmeans,
|
613
|
-
xa, x_col, nnz, xa_dense,
|
614
|
-
@n, weight, @b, @bi,
|
615
|
-
@add_implicit_features,
|
654
|
+
# TODO add param
|
655
|
+
n_max = @n
|
656
|
+
|
657
|
+
check_status FFI.topN_old_collective_explicit(
|
658
|
+
a_vec, a_bias,
|
659
|
+
@a, @bias_a, row_index,
|
660
|
+
@b,
|
661
|
+
@bias_b,
|
662
|
+
@global_mean,
|
616
663
|
@k, @k_user, @k_item, @k_main,
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
@
|
621
|
-
|
622
|
-
@include_all_x,
|
623
|
-
nil, #BtB,
|
624
|
-
nil, #TransBtBinvBt,
|
625
|
-
nil, #BtXbias,
|
626
|
-
nil, #BeTBeChol,
|
627
|
-
nil, #BiTBi,
|
628
|
-
nil, #CtCw,
|
629
|
-
nil, #TransCtCinvCt,
|
630
|
-
nil #B_plus_bias
|
631
|
-
]
|
632
|
-
check_status FFI.factors_collective_explicit_single(*fiddle_args(args))
|
664
|
+
include_ix, n_include,
|
665
|
+
exclude_ix, n_exclude,
|
666
|
+
outp_ix, outp_score,
|
667
|
+
count, @n, n_max, @include_all_x ? 1 : 0, @nthreads
|
668
|
+
)
|
633
669
|
end
|
634
670
|
|
635
|
-
|
671
|
+
top_n_output(outp_ix, outp_score)
|
672
|
+
end
|
673
|
+
|
674
|
+
def top_n_output(outp_ix, outp_score)
|
675
|
+
imap = @item_map.map(&:reverse).to_h
|
676
|
+
item_ids = int_array(outp_ix).map { |v| imap[v] }
|
677
|
+
scores = real_array(outp_score)
|
678
|
+
|
679
|
+
item_ids.zip(scores).map do |item_id, score|
|
680
|
+
{item_id: item_id, score: score}
|
681
|
+
end
|
636
682
|
end
|
637
683
|
|
638
684
|
# convert boolean to int
|
data/lib/cmfrec/version.rb
CHANGED
data/lib/cmfrec.rb
CHANGED
@@ -15,19 +15,19 @@ module Cmfrec
|
|
15
15
|
class << self
|
16
16
|
attr_accessor :ffi_lib
|
17
17
|
end
|
18
|
-
|
18
|
+
lib_path =
|
19
19
|
if Gem.win_platform?
|
20
|
-
"cmfrec.dll"
|
20
|
+
"x64-mingw/cmfrec.dll"
|
21
21
|
elsif RbConfig::CONFIG["host_os"] =~ /darwin/i
|
22
22
|
if RbConfig::CONFIG["host_cpu"] =~ /arm|aarch64/i
|
23
|
-
"libcmfrec.
|
23
|
+
"arm64-darwin/libcmfrec.dylib"
|
24
24
|
else
|
25
|
-
"libcmfrec.dylib"
|
25
|
+
"x86_64-darwin/libcmfrec.dylib"
|
26
26
|
end
|
27
27
|
else
|
28
|
-
"libcmfrec.so"
|
28
|
+
"x86_64-linux/libcmfrec.so"
|
29
29
|
end
|
30
|
-
vendor_lib = File.expand_path("../vendor/#{
|
30
|
+
vendor_lib = File.expand_path("../vendor/#{lib_path}", __dir__)
|
31
31
|
self.ffi_lib = [vendor_lib]
|
32
32
|
|
33
33
|
# friendlier error message
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
For the included LFBGS library (files "lbfgs.h", "lbfgs.c", "arithmetic_ansi.h"):
|
2
|
+
|
3
|
+
The MIT License
|
4
|
+
|
5
|
+
Copyright (c) 1990 Jorge Nocedal
|
6
|
+
Copyright (c) 2007-2010 Naoaki Okazaki
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
9
|
+
copy of this software and associated documentation files (the "Software"),
|
10
|
+
to deal in the Software without restriction, including without limitation
|
11
|
+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
12
|
+
and/or sell copies of the Software, and to permit persons to whom the
|
13
|
+
Software is furnished to do so, subject to the following conditions:
|
14
|
+
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
16
|
+
all copies or substantial portions of the Software.
|
17
|
+
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
24
|
+
THE SOFTWARE.
|
25
|
+
|
26
|
+
For the included ziggurat tables (file "ziggurat.h"):
|
27
|
+
|
28
|
+
Copyright (c) 2005-2022, NumPy Developers.
|
29
|
+
All rights reserved.
|
30
|
+
|
31
|
+
Redistribution and use in source and binary forms, with or without
|
32
|
+
modification, are permitted provided that the following conditions are
|
33
|
+
met:
|
34
|
+
|
35
|
+
* Redistributions of source code must retain the above copyright
|
36
|
+
notice, this list of conditions and the following disclaimer.
|
37
|
+
|
38
|
+
* Redistributions in binary form must reproduce the above
|
39
|
+
copyright notice, this list of conditions and the following
|
40
|
+
disclaimer in the documentation and/or other materials provided
|
41
|
+
with the distribution.
|
42
|
+
|
43
|
+
* Neither the name of the NumPy Developers nor the names of any
|
44
|
+
contributors may be used to endorse or promote products derived
|
45
|
+
from this software without specific prior written permission.
|
46
|
+
|
47
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
48
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
49
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
50
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
51
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
52
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
53
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
54
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
55
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
56
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
57
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020-2022 David Cortes
|
4
|
+
|
5
|
+
All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to
|
9
|
+
deal in the Software without restriction, including without limitation the
|
10
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
+
IN THE SOFTWARE.
|
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.
|
4
|
+
version: 0.2.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-
|
11
|
+
date: 2022-06-15 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|
@@ -24,10 +24,15 @@ files:
|
|
24
24
|
- lib/cmfrec/ffi.rb
|
25
25
|
- lib/cmfrec/recommender.rb
|
26
26
|
- lib/cmfrec/version.rb
|
27
|
-
- vendor/
|
28
|
-
- vendor/
|
29
|
-
- vendor/libcmfrec.dylib
|
30
|
-
- vendor/
|
27
|
+
- vendor/arm64-darwin/COPYRIGHTS
|
28
|
+
- vendor/arm64-darwin/LICENSE
|
29
|
+
- vendor/arm64-darwin/libcmfrec.dylib
|
30
|
+
- vendor/x86_64-darwin/COPYRIGHTS
|
31
|
+
- vendor/x86_64-darwin/LICENSE
|
32
|
+
- vendor/x86_64-darwin/libcmfrec.dylib
|
33
|
+
- vendor/x86_64-linux/COPYRIGHTS
|
34
|
+
- vendor/x86_64-linux/LICENSE
|
35
|
+
- vendor/x86_64-linux/libcmfrec.so
|
31
36
|
homepage: https://github.com/ankane/cmfrec-ruby
|
32
37
|
licenses:
|
33
38
|
- MIT
|
@@ -40,7 +45,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
45
|
requirements:
|
41
46
|
- - ">="
|
42
47
|
- !ruby/object:Gem::Version
|
43
|
-
version: '2.
|
48
|
+
version: '2.7'
|
44
49
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
50
|
requirements:
|
46
51
|
- - ">="
|
data/vendor/LICENSE.txt
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
MIT License
|
2
|
-
|
3
|
-
Copyright (c) 2020 David Cortes
|
4
|
-
|
5
|
-
All rights reserved.
|
6
|
-
|
7
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
of this software and associated documentation files (the "Software"), to
|
9
|
-
deal in the Software without restriction, including without limitation the
|
10
|
-
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
11
|
-
sell copies of the Software, and to permit persons to whom the Software is
|
12
|
-
furnished to do so, subject to the following conditions:
|
13
|
-
|
14
|
-
The above copyright notice and this permission notice shall be included in
|
15
|
-
all copies or substantial portions of the Software.
|
16
|
-
|
17
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
22
|
-
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
23
|
-
IN THE SOFTWARE.
|
24
|
-
|
25
|
-
---
|
26
|
-
|
27
|
-
ANSI C implementation of vector operations.
|
28
|
-
|
29
|
-
Copyright (c) 2007-2010 Naoaki Okazaki
|
30
|
-
All rights reserved.
|
31
|
-
|
32
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
33
|
-
of this software and associated documentation files (the "Software"), to deal
|
34
|
-
in the Software without restriction, including without limitation the rights
|
35
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
36
|
-
copies of the Software, and to permit persons to whom the Software is
|
37
|
-
furnished to do so, subject to the following conditions:
|
38
|
-
|
39
|
-
The above copyright notice and this permission notice shall be included in
|
40
|
-
all copies or substantial portions of the Software.
|
41
|
-
|
42
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
43
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
44
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
45
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
46
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
47
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
48
|
-
THE SOFTWARE.
|
49
|
-
|
50
|
-
---
|
51
|
-
|
52
|
-
C library of Limited memory BFGS (L-BFGS).
|
53
|
-
|
54
|
-
Copyright (c) 1990, Jorge Nocedal
|
55
|
-
Copyright (c) 2007-2010 Naoaki Okazaki
|
56
|
-
All rights reserved.
|
57
|
-
|
58
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
59
|
-
of this software and associated documentation files (the "Software"), to deal
|
60
|
-
in the Software without restriction, including without limitation the rights
|
61
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
62
|
-
copies of the Software, and to permit persons to whom the Software is
|
63
|
-
furnished to do so, subject to the following conditions:
|
64
|
-
|
65
|
-
The above copyright notice and this permission notice shall be included in
|
66
|
-
all copies or substantial portions of the Software.
|
67
|
-
|
68
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
69
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
70
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
71
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
72
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
73
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
74
|
-
THE SOFTWARE.
|
Binary file
|
data/vendor/libcmfrec.dylib
DELETED
Binary file
|
data/vendor/libcmfrec.so
DELETED
Binary file
|