libffm 0.4.1 → 0.5.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 +5 -0
- data/LICENSE.txt +1 -1
- data/ext/libffm/ext.cpp +61 -35
- data/lib/libffm/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 07323e72497473a0d74016a0f038bf20e3630975d209ff7f5ba35735d4950c70
|
|
4
|
+
data.tar.gz: 28723358a87d007aff3ee1c5e8cd007272c08fbac568a92c9f02855c41e764c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f14d21212c9466cd073f29648e880a085910437b404baaa20534f90b1ff9c6e196978eb55172cae353a5fbe35d08fa2aaf8c63cf1c8e613dbf24f9551efc2375
|
|
7
|
+
data.tar.gz: dece73854d082f55ba1aa8b772a44ede96e62f87af3295d01bf4a8de0039e61021e6eb6bc9b8abc64fae10fe74ed3fd6c7ced28e08513ad6ec027381950e1e66
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
data/ext/libffm/ext.cpp
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
#include <cstdio>
|
|
2
2
|
#include <cstdlib>
|
|
3
3
|
#include <cstring>
|
|
4
|
+
#include <fstream>
|
|
4
5
|
#include <iostream>
|
|
5
6
|
#include <string>
|
|
7
|
+
#include <string_view>
|
|
8
|
+
#include <vector>
|
|
6
9
|
|
|
7
10
|
#include <ffm.h>
|
|
8
11
|
#include <rice/rice.hpp>
|
|
9
|
-
#include <rice/stl.hpp>
|
|
10
12
|
|
|
11
13
|
extern "C"
|
|
12
14
|
void Init_ext() {
|
|
@@ -23,17 +25,17 @@ void Init_ext() {
|
|
|
23
25
|
})
|
|
24
26
|
.define_singleton_function(
|
|
25
27
|
"fit",
|
|
26
|
-
[](
|
|
28
|
+
[](Rice::String tr_path, Rice::String va_path, Rice::String tmp_prefix, ffm::ffm_float eta, ffm::ffm_float lambda, ffm::ffm_int nr_iters, ffm::ffm_int k, bool normalization, bool auto_stop) {
|
|
27
29
|
// quiet
|
|
28
|
-
|
|
30
|
+
std::cout.setstate(std::ios_base::badbit);
|
|
29
31
|
|
|
30
|
-
std::string tr_bin_path = tmp_prefix + "train.bin";
|
|
31
|
-
ffm::ffm_read_problem_to_disk(tr_path, tr_bin_path);
|
|
32
|
+
std::string tr_bin_path = tmp_prefix.str() + "train.bin";
|
|
33
|
+
ffm::ffm_read_problem_to_disk(tr_path.str(), tr_bin_path);
|
|
32
34
|
|
|
33
|
-
std::string va_bin_path
|
|
34
|
-
if (va_path.
|
|
35
|
-
va_bin_path = tmp_prefix + "validation.bin";
|
|
36
|
-
ffm::ffm_read_problem_to_disk(va_path, va_bin_path);
|
|
35
|
+
std::string va_bin_path;
|
|
36
|
+
if (va_path.length() != 0) {
|
|
37
|
+
va_bin_path = tmp_prefix.str() + "validation.bin";
|
|
38
|
+
ffm::ffm_read_problem_to_disk(va_path.str(), va_bin_path);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
ffm::ffm_parameter param;
|
|
@@ -48,51 +50,75 @@ void Init_ext() {
|
|
|
48
50
|
})
|
|
49
51
|
.define_singleton_function(
|
|
50
52
|
"predict",
|
|
51
|
-
[](ffm::ffm_model& model,
|
|
52
|
-
|
|
53
|
+
[](ffm::ffm_model& model, Rice::String test_path) {
|
|
54
|
+
std::ifstream f_in(test_path.str());
|
|
55
|
+
if (!f_in.is_open()) {
|
|
56
|
+
throw std::runtime_error{"Cannot open file"};
|
|
57
|
+
}
|
|
58
|
+
std::string line;
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
Rice::Array ret;
|
|
61
|
+
while (std::getline(f_in, line)) {
|
|
62
|
+
std::vector<ffm::ffm_node> x;
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
ffm::ffm_int i = 0;
|
|
64
|
+
std::string_view line_view{line};
|
|
59
65
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
66
|
+
size_t n = line_view.find_first_of(" \t");
|
|
67
|
+
if (n == std::string_view::npos) {
|
|
68
|
+
throw std::runtime_error{"Invalid line"};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
size_t start = n + 1;
|
|
64
72
|
|
|
65
73
|
while (true) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (field_char == nullptr || *field_char == '\n')
|
|
70
|
-
break;
|
|
74
|
+
n = line_view.find_first_of(" \t", start);
|
|
75
|
+
|
|
76
|
+
std::string_view s = n == std::string_view::npos ? line_view.substr(start) : line_view.substr(start, n - start);
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
size_t n2 = s.find(':');
|
|
79
|
+
if (n2 == std::string_view::npos) {
|
|
80
|
+
throw std::runtime_error{"Invalid line"};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
size_t n3 = s.find(':', n2 + 1);
|
|
84
|
+
if (n3 == std::string_view::npos) {
|
|
85
|
+
throw std::runtime_error{"Invalid line"};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
std::string_view field_char = s.substr(0, n2);
|
|
89
|
+
std::string_view idx_char = s.substr(n2 + 1, n3 - n2 - 1);
|
|
90
|
+
std::string_view value_char = s.substr(n3 + 1);
|
|
91
|
+
|
|
92
|
+
// cannot pass string view to stoi/stof
|
|
93
|
+
ffm::ffm_node N{
|
|
94
|
+
std::stoi(std::string{field_char}),
|
|
95
|
+
std::stoi(std::string{idx_char}),
|
|
96
|
+
std::stof(std::string{value_char})
|
|
97
|
+
};
|
|
76
98
|
|
|
77
99
|
x.push_back(N);
|
|
100
|
+
|
|
101
|
+
if (n == std::string::npos) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
start = n + 1;
|
|
78
106
|
}
|
|
79
107
|
|
|
80
|
-
ffm::ffm_float y_bar = ffm::ffm_predict(x.data(), x.data()+x.size(), model);
|
|
108
|
+
ffm::ffm_float y_bar = ffm::ffm_predict(x.data(), x.data() + x.size(), model);
|
|
81
109
|
ret.push(y_bar, false);
|
|
82
110
|
}
|
|
83
111
|
|
|
84
|
-
std::fclose(f_in);
|
|
85
|
-
|
|
86
112
|
return ret;
|
|
87
113
|
})
|
|
88
114
|
.define_singleton_function(
|
|
89
115
|
"save_model",
|
|
90
|
-
[](ffm::ffm_model& model,
|
|
91
|
-
ffm::ffm_save_model(model, path);
|
|
116
|
+
[](ffm::ffm_model& model, Rice::String path) {
|
|
117
|
+
ffm::ffm_save_model(model, path.str());
|
|
92
118
|
})
|
|
93
119
|
.define_singleton_function(
|
|
94
120
|
"load_model",
|
|
95
|
-
[](
|
|
96
|
-
return ffm::ffm_load_model(path);
|
|
121
|
+
[](Rice::String path) {
|
|
122
|
+
return ffm::ffm_load_model(path.str());
|
|
97
123
|
});
|
|
98
124
|
}
|
data/lib/libffm/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: libffm
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
@@ -58,14 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
58
58
|
requirements:
|
|
59
59
|
- - ">="
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '3.
|
|
61
|
+
version: '3.3'
|
|
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:
|
|
68
|
+
rubygems_version: 4.0.6
|
|
69
69
|
specification_version: 4
|
|
70
70
|
summary: Field-aware factorization machines for Ruby
|
|
71
71
|
test_files: []
|