cmfrec 0.1.7 → 0.2.0
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 +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
|