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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d16ab98cb7de22042eaf353a9d41d0b7a4214a631a373c553f73825418c026a
4
- data.tar.gz: 9ab678a9d389b835b4dfd91d14c372d5acfef950bf068ac46d2d879af04f0fcc
3
+ metadata.gz: e6dbbc801e415a4f505ffc436be23ccf066d144da072669e782b88c02e14b0f8
4
+ data.tar.gz: 3851230f0a4dc4be9fbc24fe81681de0758bdbb583803780f8e07b10741f4bd1
5
5
  SHA512:
6
- metadata.gz: 175d3c91056d2e8734af6961471c98be76e4d5f6b85faaecdfd3b39a220efafa70150983e9d74efb1a1211a29e6c867d6b1d7f482cc34c55500268d29b40158c
7
- data.tar.gz: faaed621391ccc7d94f2e6309481b24f7db62fbe86eb6c1bbb35445dde0cabf32c41791af4ebcd25e530bdc1f6319f1b4477b6c4d6ca1bf77353d3a0c4ae8d5c
6
+ metadata.gz: 103c09a7c0e13fca3cb81dc68c667e776fc965a485cf358e0fc8f350a97474b54bdfc0910f4472051020dbe34b8c097908c1024d5fc036ad77d0444372885109
7
+ data.tar.gz: b107b36333f714106d981168f24fda48a2a211f288a2dbe01f570adb607b7d6a5215c18df4c67d159bb367d652f3d10faeb4dbc66688eaf117c5b7a1432ee951
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.2.0 (2022-06-14)
2
+
3
+ - Updated cmfrec to 3.4.2
4
+ - Fixed missing item ids with `load_movielens`
5
+ - Dropped support for Ruby < 2.7
6
+
1
7
  ## 0.1.7 (2022-03-22)
2
8
 
3
9
  - Improved ARM detection
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 'cmfrec'
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 'ngt'
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, int_t nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, bool include_all_X, real_t *restrict B_plus_bias, real_t *restrict precomputedBtB, real_t *restrict precomputedTransBtBinvBt, real_t *restrict precomputedBtXbias, real_t *restrict precomputedBeTBeChol, real_t *restrict precomputedBiTBi, real_t *restrict precomputedTransCtCinvCt, real_t *restrict precomputedCtCw)"
21
- extern "int_t fit_collective_implicit_als(real_t *restrict A, real_t *restrict B, real_t *restrict C, real_t *restrict D, bool reset_values, int_t seed, real_t *restrict U_colmeans, real_t *restrict I_colmeans, int_t m, int_t n, int_t k, int_t ixA[], int_t ixB[], real_t *restrict X, size_t nnz, real_t lam, real_t *restrict lam_unique, real_t l1_lam, real_t *restrict l1_lam_unique, real_t *restrict U, int_t m_u, int_t p, real_t *restrict II, int_t n_i, int_t q, int_t U_row[], int_t U_col[], real_t *restrict U_sp, size_t nnz_U, int_t I_row[], int_t I_col[], real_t *restrict I_sp, size_t nnz_I, bool NA_as_zero_U, bool NA_as_zero_I, int_t k_main, int_t k_user, int_t k_item, real_t w_main, real_t w_user, real_t w_item, real_t *restrict w_main_multiplier, real_t alpha, bool adjust_weight, bool apply_log_transf, int_t niter, int_t nthreads, bool verbose, bool handle_interrupt, bool use_cg, int_t max_cg_steps, bool finalize_chol, bool nonneg, int_t max_cd_steps, bool nonneg_C, bool nonneg_D, bool precompute_for_predictions, real_t *restrict precomputedBtB, real_t *restrict precomputedBeTBe, real_t *restrict precomputedBeTBeChol)"
22
- extern "int_t factors_collective_explicit_single(real_t *restrict a_vec, real_t *restrict a_bias,real_t *restrict u_vec, int_t p,real_t *restrict u_vec_sp, int_t u_vec_ixB[], size_t nnz_u_vec,real_t *restrict u_bin_vec, int_t pbin,bool NA_as_zero_U, bool NA_as_zero_X,bool nonneg,real_t *restrict C, real_t *restrict Cb,real_t glob_mean, real_t *restrict biasB,real_t *restrict U_colmeans,real_t *restrict Xa, int_t ixB[], size_t nnz,real_t *restrict Xa_dense, int_t n,real_t *restrict weight,real_t *restrict B,real_t *restrict Bi, bool add_implicit_features,int_t k, int_t k_user, int_t k_item, int_t k_main,real_t lam, real_t *restrict lam_unique,real_t l1_lam, real_t *restrict l1_lam_unique,bool scale_lam, bool scale_lam_sideinfo,real_t w_main, real_t w_user, real_t w_implicit,int_t n_max, bool include_all_X,real_t *restrict BtB,real_t *restrict TransBtBinvBt,real_t *restrict BtXbias,real_t *restrict BeTBeChol,real_t *restrict BiTBi,real_t *restrict CtCw,real_t *restrict TransCtCinvCt,real_t *restrict B_plus_bias)"
23
- extern "int_t factors_collective_implicit_single(real_t *restrict a_vec,real_t *restrict u_vec, int_t p,real_t *restrict u_vec_sp, int_t u_vec_ixB[], size_t nnz_u_vec,bool NA_as_zero_U,bool nonneg,real_t *restrict U_colmeans,real_t *restrict B, int_t n, real_t *restrict C,real_t *restrict Xa, int_t ixB[], size_t nnz,int_t k, int_t k_user, int_t k_item, int_t k_main,real_t lam, real_t l1_lam, real_t alpha, real_t w_main, real_t w_user,real_t w_main_multiplier,bool apply_log_transf,real_t *restrict BeTBe,real_t *restrict BtB,real_t *restrict BeTBeChol)"
24
- extern "int_t predict_X_old_collective_explicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict biasA, real_t *restrict B, real_t *restrict biasB, real_t glob_mean, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n_max, int_t nthreads)"
25
- extern "int_t predict_X_old_collective_implicit(int_t row[], int_t col[], real_t *restrict predicted, size_t n_predict, real_t *restrict A, real_t *restrict B, int_t k, int_t k_user, int_t k_item, int_t k_main, int_t m, int_t n, int_t nthreads)"
26
- extern "int_t topN(real_t *restrict a_vec, int_t k_user, real_t *restrict B, int_t k_item, real_t *restrict biasB, real_t glob_mean, real_t biasA, int_t k, int_t k_main, int_t *restrict include_ix, int_t n_include, int_t *restrict exclude_ix, int_t n_exclude, int_t *restrict outp_ix, real_t *restrict outp_score, int_t n_top, int_t n, int_t nthreads)"
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
@@ -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
- a_vec, a_bias, rated = factors_warm(data, user_info: user_info)
85
- top_n(a_vec: a_vec, a_bias: a_bias, count: count, rated: rated, item_ids: item_ids)
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 #precomputedBeTBeChol
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
- center = true
285
- scale_lam = false
286
- scale_lam_sideinfo = false
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 #precomputedCtCw
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_: 1e+1, method: "als", use_cg: true, user_bias: true,
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: false,
349
- random_state: 1, verbose: true, print_every: 10,
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 top_n(a_vec:, a_bias:, count:, rated: nil, item_ids: nil)
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
- # TODO uncomment in 0.2.0
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
- check_status FFI.topN(
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 factors_warm(data, user_info: nil)
519
- data = to_dataset(data)
520
- user_info = to_dataset(user_info) if user_info
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
- args = [
643
+ check_status FFI.topN_old_collective_implicit(
581
644
  a_vec,
582
- u_vec, p_,
583
- u_vec_sp, u_vec_x_col, nnz_u_vec,
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
- @lambda_, l1_lambda, @alpha,
591
- @w_main, @w_user, @w_main_multiplier,
592
- @apply_log_transf,
593
- nil, #BeTBe,
594
- nil, #BtB
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
- cb = nil
600
-
601
- scale_lam = false
602
- scale_lam_sideinfo = false
603
-
604
- args = [
605
- a_vec, bias_a,
606
- u_vec, p_,
607
- u_vec_sp, u_vec_x_col, nnz_u_vec,
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
- @lambda_, lam_unique,
618
- l1_lambda, l1_lam_unique,
619
- scale_lam, scale_lam_sideinfo,
620
- @w_main, @w_user, @w_implicit,
621
- n_max,
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
- [a_vec, real_array(bias_a).first, item_ids.uniq]
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
@@ -1,3 +1,3 @@
1
1
  module Cmfrec
2
- VERSION = "0.1.7"
2
+ VERSION = "0.2.0"
3
3
  end
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
- lib_name =
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.arm64.dylib"
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/#{lib_name}", __dir__)
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.
@@ -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.1.7
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-03-22 00:00:00.000000000 Z
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/LICENSE.txt
28
- - vendor/libcmfrec.arm64.dylib
29
- - vendor/libcmfrec.dylib
30
- - vendor/libcmfrec.so
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.5'
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
Binary file
data/vendor/libcmfrec.so DELETED
Binary file