libmf 0.2.6 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 33b8ba1c7cf9de8e19fa9775ecdb445bc0f2f4323401cccbf016ff6a81a04a00
4
- data.tar.gz: 9ff88bdafac8bbfe0c99ccc0c0b7dfb7a9092246de1105c7f99ccade29b9c88b
3
+ metadata.gz: 510156ab4bccb39a99441002dd80f3540b643934294bc5724dca91987b4effba
4
+ data.tar.gz: 03a1f04e4679ec60cb2f1d2a96e2add0b9adba03fe5715bc4f10309ab795bcc1
5
5
  SHA512:
6
- metadata.gz: 021eca76e96ceca2cd484b7f7796a649529f3b20c80d494143cfaf43e617d23ac55ae50bdcd345808e277b31d304ea6e6a53c937b3e9a200f47ae226f27e4f2b
7
- data.tar.gz: 916b78a5e62d19e4d6a9e1433350bb26982d43393029e4e883ed803f89a03f6db766ab10718120a73db1f0ad7ac80607d475a10a7c203d117ca1706e80618345
6
+ metadata.gz: eb862c0cf91a077ba2e9a0ed3f93491297cdc9801683e3587b91125c7e0b79123d0f942aea6bf3cef42fbbb43f5e8f822758a894f25a7eedf2fd9ee7b5ea4920
7
+ data.tar.gz: b4d74a6b3d4160f3b1165f90496a9f93c6b59ca99e5f3cc0094f022a0807fc8a34af3d9b0edeeff463264a60c19901ceaa171c3cea944d860103208e2d26dbf2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.3.0 (2022-08-07)
2
+
3
+ - Added metrics
4
+ - Prefer `save` over `save_model`
5
+ - Prefer `load` over `load_model`
6
+ - Dropped support for Ruby < 2.7
7
+
1
8
  ## 0.2.6 (2021-12-02)
2
9
 
3
10
  - Improved ARM detection
data/LICENSE.txt CHANGED
@@ -1,30 +1,33 @@
1
1
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2014-2015, The LIBMF Project
4
- Copyright (c) 2019-2021, Andrew Kane
3
+ Copyright (c) 2014-2015 The LIBMF Project.
4
+ Copyright (c) 2019-2022 Andrew Kane.
5
5
  All rights reserved.
6
6
 
7
7
  Redistribution and use in source and binary forms, with or without
8
- modification, are permitted provided that the following conditions are met:
8
+ modification, are permitted provided that the following conditions
9
+ are met:
9
10
 
10
- 1. Redistributions of source code must retain the above copyright notice, this
11
- list of conditions and the following disclaimer.
11
+ 1. Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
12
13
 
13
- 2. Redistributions in binary form must reproduce the above copyright notice,
14
- this list of conditions and the following disclaimer in the documentation
15
- and/or other materials provided with the distribution.
14
+ 2. Redistributions in binary form must reproduce the above copyright
15
+ notice, this list of conditions and the following disclaimer in the
16
+ documentation and/or other materials provided with the distribution.
16
17
 
17
- 3. Neither the name of the copyright holder nor the names of its
18
- contributors may be used to endorse or promote products derived from
19
- this software without specific prior written permission.
18
+ 3. Neither name of copyright holders nor the names of its contributors
19
+ may be used to endorse or promote products derived from this software
20
+ without specific prior written permission.
20
21
 
21
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
+
23
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
27
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md CHANGED
@@ -11,7 +11,7 @@ Check out [Disco](https://github.com/ankane/disco) for higher-level collaborativ
11
11
  Add this line to your application’s Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'libmf'
14
+ gem "libmf"
15
15
  ```
16
16
 
17
17
  ## Getting Started
@@ -54,13 +54,13 @@ model.bias
54
54
  Save the model to a file
55
55
 
56
56
  ```ruby
57
- model.save_model("model.txt")
57
+ model.save("model.txt")
58
58
  ```
59
59
 
60
60
  Load the model from a file
61
61
 
62
62
  ```ruby
63
- model.load_model("model.txt")
63
+ model = Libmf::Model.load("model.txt")
64
64
  ```
65
65
 
66
66
  Pass a validation set
@@ -99,7 +99,7 @@ Libmf::Model.new(
99
99
  lambda_q1: 0, # coefficient of L1-norm regularization on Q
100
100
  lambda_q2: 0.1, # coefficient of L2-norm regularization on Q
101
101
  learning_rate: 0.1, # learning rate
102
- alpha: 0.1, # importance of negative entries
102
+ alpha: 1, # importance of negative entries
103
103
  c: 0.0001, # desired value of negative entries
104
104
  nmf: false, # perform non-negative MF (NMF)
105
105
  quiet: false # no outputs to stdout
@@ -126,6 +126,50 @@ For one-class matrix factorization
126
126
  - `:one_class_col` - column-oriented pair-wise logarithmic loss
127
127
  - `:one_class_l2` - squared error (L2-norm)
128
128
 
129
+ ## Metrics
130
+
131
+ Calculate RMSE (for real-valued MF)
132
+
133
+ ```ruby
134
+ model.rmse(data)
135
+ ```
136
+
137
+ Calculate MAE (for real-valued MF)
138
+
139
+ ```ruby
140
+ model.mae(data)
141
+ ```
142
+
143
+ Calculate generalized KL-divergence (for non-negative real-valued MF)
144
+
145
+ ```ruby
146
+ model.gkl(data)
147
+ ```
148
+
149
+ Calculate logarithmic loss (for binary MF)
150
+
151
+ ```ruby
152
+ model.logloss(data)
153
+ ```
154
+
155
+ Calculate accuracy (for binary MF)
156
+
157
+ ```ruby
158
+ model.accuracy(data)
159
+ ```
160
+
161
+ Calculate MPR (for one-class MF)
162
+
163
+ ```ruby
164
+ model.mpr(data, transpose)
165
+ ```
166
+
167
+ Calculate AUC (for one-class MF)
168
+
169
+ ```ruby
170
+ model.auc(data, transpose)
171
+ ```
172
+
129
173
  ## Performance
130
174
 
131
175
  For performance, read data directly from files
@@ -172,7 +216,7 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
172
216
  To get started with development:
173
217
 
174
218
  ```sh
175
- git clone --recursive https://github.com/ankane/libmf-ruby.git
219
+ git clone https://github.com/ankane/libmf-ruby.git
176
220
  cd libmf-ruby
177
221
  bundle install
178
222
  bundle exec rake vendor:all
data/lib/libmf/ffi.rb CHANGED
@@ -59,7 +59,14 @@ module Libmf
59
59
  attach_function :mf_destroy_model, [:pointer], :void
60
60
  attach_function :mf_train, [Problem.by_ref, Parameter.by_value], Model.auto_ptr
61
61
  attach_function :mf_train_with_validation, [Problem.by_ref, Problem.by_ref, Parameter.by_value], Model.auto_ptr
62
- attach_function :mf_predict, [Model.by_ref, :int, :int], :float
63
62
  attach_function :mf_cross_validation, [Problem.by_ref, :int, Parameter.by_value], :double
63
+ attach_function :mf_predict, [Model.by_ref, :int, :int], :float
64
+ attach_function :calc_rmse, [Problem.by_ref, Model.by_ref], :double
65
+ attach_function :calc_mae, [Problem.by_ref, Model.by_ref], :double
66
+ attach_function :calc_gkl, [Problem.by_ref, Model.by_ref], :double
67
+ attach_function :calc_logloss, [Problem.by_ref, Model.by_ref], :double
68
+ attach_function :calc_accuracy, [Problem.by_ref, Model.by_ref], :double
69
+ attach_function :calc_mpr, [Problem.by_ref, Model.by_ref, :bool], :double
70
+ attach_function :calc_auc, [Problem.by_ref, Model.by_ref, :bool], :double
64
71
  end
65
72
  end
data/lib/libmf/model.rb CHANGED
@@ -35,6 +35,13 @@ module Libmf
35
35
  status = FFI.mf_save_model(model, path)
36
36
  raise Error, "Cannot save model" if status != 0
37
37
  end
38
+ alias_method :save, :save_model
39
+
40
+ def self.load(path)
41
+ model = Model.new
42
+ model.load_model(path)
43
+ model
44
+ end
38
45
 
39
46
  def load_model(path)
40
47
  @model = FFI.mf_load_model(path)
@@ -65,6 +72,34 @@ module Libmf
65
72
  _factors(model[:q], columns, format)
66
73
  end
67
74
 
75
+ def rmse(data)
76
+ FFI.calc_rmse(create_problem(data), model)
77
+ end
78
+
79
+ def mae(data)
80
+ FFI.calc_mae(create_problem(data), model)
81
+ end
82
+
83
+ def gkl(data)
84
+ FFI.calc_gkl(create_problem(data), model)
85
+ end
86
+
87
+ def logloss(data)
88
+ FFI.calc_logloss(create_problem(data), model)
89
+ end
90
+
91
+ def accuracy(data)
92
+ FFI.calc_accuracy(create_problem(data), model)
93
+ end
94
+
95
+ def mpr(data, transpose)
96
+ FFI.calc_mpr(create_problem(data), model, transpose)
97
+ end
98
+
99
+ def auc(data, transpose)
100
+ FFI.calc_auc(create_problem(data), model, transpose)
101
+ end
102
+
68
103
  private
69
104
 
70
105
  def _factors(ptr, n, format)
data/lib/libmf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Libmf
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libmf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.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: 2021-12-02 00:00:00.000000000 Z
11
+ date: 2022-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -58,14 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '2.4'
61
+ version: '2.7'
62
62
  required_rubygems_version: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - ">="
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
67
  requirements: []
68
- rubygems_version: 3.2.32
68
+ rubygems_version: 3.3.7
69
69
  signing_key:
70
70
  specification_version: 4
71
71
  summary: Large-scale sparse matrix factorization for Ruby