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 +4 -4
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +24 -21
- data/README.md +49 -5
- data/lib/libmf/ffi.rb +8 -1
- data/lib/libmf/model.rb +35 -0
- data/lib/libmf/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 510156ab4bccb39a99441002dd80f3540b643934294bc5724dca91987b4effba
|
4
|
+
data.tar.gz: 03a1f04e4679ec60cb2f1d2a96e2add0b9adba03fe5715bc4f10309ab795bcc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb862c0cf91a077ba2e9a0ed3f93491297cdc9801683e3587b91125c7e0b79123d0f942aea6bf3cef42fbbb43f5e8f822758a894f25a7eedf2fd9ee7b5ea4920
|
7
|
+
data.tar.gz: b4d74a6b3d4160f3b1165f90496a9f93c6b59ca99e5f3cc0094f022a0807fc8a34af3d9b0edeeff463264a60c19901ceaa171c3cea944d860103208e2d26dbf2
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,30 +1,33 @@
|
|
1
1
|
BSD 3-Clause License
|
2
2
|
|
3
|
-
Copyright (c) 2014-2015
|
4
|
-
Copyright (c) 2019-
|
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
|
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
|
11
|
-
|
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
|
14
|
-
|
15
|
-
|
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
|
18
|
-
|
19
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
OR
|
30
|
-
|
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
|
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.
|
57
|
+
model.save("model.txt")
|
58
58
|
```
|
59
59
|
|
60
60
|
Load the model from a file
|
61
61
|
|
62
62
|
```ruby
|
63
|
-
model.
|
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:
|
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
|
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
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.
|
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:
|
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.
|
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.
|
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
|