cmfrec 0.1.1 → 0.1.2

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