numo-libsvm 0.4.0 → 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 +3 -0
- data/ext/numo/libsvm/converter.c +49 -15
- data/ext/numo/libsvm/converter.h +2 -1
- data/ext/numo/libsvm/libsvmext.c +10 -33
- data/ext/numo/libsvm/svm_problem.c +35 -6
- data/lib/numo/libsvm/version.rb +1 -1
- data/numo-libsvm.gemspec +6 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4366bf85268dddd0d9717790646f16ba73bfcc5f
|
4
|
+
data.tar.gz: 8bb7e4a8a79b86f4f60c73f7087af628e3d9751f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3beb968e572a1750522d85081feddd124464b4961e03578635b68afab00e69c9003323f5d7e1f983865ceb14842ec733bbe082b3f58fc630b45812a6b4a81692
|
7
|
+
data.tar.gz: a07ff40e86e815fbe11445a7919c8350dd51471e152dcc783e0e71cb641635e8d7dd9e6476c40ee8a60acfe85adfc1125731359b3bf72d7a4222d9dd8ee1def9
|
data/CHANGELOG.md
CHANGED
data/ext/numo/libsvm/converter.c
CHANGED
@@ -132,31 +132,65 @@ VALUE svm_nodes_to_nary(struct svm_node** const support_vecs, const int n_suppor
|
|
132
132
|
return v;
|
133
133
|
}
|
134
134
|
|
135
|
-
struct svm_node** nary_to_svm_nodes(VALUE
|
135
|
+
struct svm_node** nary_to_svm_nodes(VALUE nary_val)
|
136
136
|
{
|
137
|
-
int i, j;
|
138
|
-
int n_rows, n_cols;
|
139
|
-
narray_t*
|
140
|
-
double*
|
137
|
+
int i, j, k;
|
138
|
+
int n_rows, n_cols, n_nonzero_cols;
|
139
|
+
narray_t* nary;
|
140
|
+
double* nary_pt;
|
141
141
|
struct svm_node** support_vecs;
|
142
142
|
|
143
|
-
if (
|
143
|
+
if (nary_val == Qnil) return NULL;
|
144
144
|
|
145
|
-
GetNArray(
|
146
|
-
n_rows = (int)NA_SHAPE(
|
147
|
-
n_cols = (int)NA_SHAPE(
|
145
|
+
GetNArray(nary_val, nary);
|
146
|
+
n_rows = (int)NA_SHAPE(nary)[0];
|
147
|
+
n_cols = (int)NA_SHAPE(nary)[1];
|
148
148
|
|
149
|
-
|
149
|
+
nary_pt = (double*)na_get_pointer_for_read(nary_val);
|
150
150
|
support_vecs = ALLOC_N(struct svm_node*, n_rows);
|
151
151
|
for (i = 0; i < n_rows; i++) {
|
152
|
-
|
152
|
+
n_nonzero_cols = 0;
|
153
153
|
for (j = 0; j < n_cols; j++) {
|
154
|
-
|
155
|
-
|
154
|
+
if (nary_pt[i * n_cols + j] != 0) {
|
155
|
+
n_nonzero_cols++;
|
156
|
+
}
|
157
|
+
}
|
158
|
+
support_vecs[i] = ALLOC_N(struct svm_node, n_nonzero_cols + 1);
|
159
|
+
for (j = 0, k = 0; j < n_cols; j++) {
|
160
|
+
if (nary_pt[i * n_cols + j] != 0) {
|
161
|
+
support_vecs[i][k].index = j + 1;
|
162
|
+
support_vecs[i][k].value = nary_pt[i * n_cols + j];
|
163
|
+
k++;
|
164
|
+
}
|
156
165
|
}
|
157
|
-
support_vecs[i][
|
158
|
-
support_vecs[i][
|
166
|
+
support_vecs[i][n_nonzero_cols].index = -1;
|
167
|
+
support_vecs[i][n_nonzero_cols].value = 0.0;
|
159
168
|
}
|
160
169
|
|
161
170
|
return support_vecs;
|
162
171
|
}
|
172
|
+
|
173
|
+
struct svm_node* dbl_vec_to_svm_node(double* const arr, int const size)
|
174
|
+
{
|
175
|
+
int i, j;
|
176
|
+
int n_nonzero_elements;
|
177
|
+
struct svm_node* node;
|
178
|
+
|
179
|
+
n_nonzero_elements = 0;
|
180
|
+
for (i = 0; i < size; i++) {
|
181
|
+
if (arr[i] != 0.0) n_nonzero_elements++;
|
182
|
+
}
|
183
|
+
|
184
|
+
node = ALLOC_N(struct svm_node, n_nonzero_elements + 1);
|
185
|
+
for (i = 0, j = 0; i < size; i++) {
|
186
|
+
if (arr[i] != 0.0) {
|
187
|
+
node[j].index = i + 1;
|
188
|
+
node[j].value = arr[i];
|
189
|
+
j++;
|
190
|
+
}
|
191
|
+
}
|
192
|
+
node[n_nonzero_elements].index = -1;
|
193
|
+
node[n_nonzero_elements].value = 0.0;
|
194
|
+
|
195
|
+
return node;
|
196
|
+
}
|
data/ext/numo/libsvm/converter.h
CHANGED
@@ -14,6 +14,7 @@ double* nary_to_dbl_vec(VALUE vec_val);
|
|
14
14
|
VALUE dbl_mat_to_nary(double** const mat, int const n_rows, int const n_cols);
|
15
15
|
double** nary_to_dbl_mat(VALUE mat_val);
|
16
16
|
VALUE svm_nodes_to_nary(struct svm_node** const support_vecs, const int n_support_vecs);
|
17
|
-
struct svm_node** nary_to_svm_nodes(VALUE
|
17
|
+
struct svm_node** nary_to_svm_nodes(VALUE nary_val);
|
18
|
+
struct svm_node* dbl_vec_to_svm_node(double* const arr, int const size);
|
18
19
|
|
19
20
|
#endif /* NUMO_LIBSVM_CONVERTER_H */
|
data/ext/numo/libsvm/libsvmext.c
CHANGED
@@ -254,9 +254,10 @@ VALUE predict(VALUE self, VALUE x_val, VALUE param_hash, VALUE model_hash)
|
|
254
254
|
size_t y_shape[1];
|
255
255
|
VALUE y_val;
|
256
256
|
double* y_pt;
|
257
|
-
int i, j;
|
257
|
+
int i, j, k;
|
258
258
|
int n_samples;
|
259
259
|
int n_features;
|
260
|
+
int n_nonzero_features;
|
260
261
|
|
261
262
|
/* Obtain C data structures. */
|
262
263
|
if (CLASS_OF(x_val) != numo_cDFloat) {
|
@@ -285,18 +286,12 @@ VALUE predict(VALUE self, VALUE x_val, VALUE param_hash, VALUE model_hash)
|
|
285
286
|
x_pt = (double*)na_get_pointer_for_read(x_val);
|
286
287
|
|
287
288
|
/* Predict values. */
|
288
|
-
x_nodes = ALLOC_N(struct svm_node, n_features + 1);
|
289
|
-
x_nodes[n_features].index = -1;
|
290
|
-
x_nodes[n_features].value = 0.0;
|
291
289
|
for (i = 0; i < n_samples; i++) {
|
292
|
-
|
293
|
-
x_nodes[j].index = j + 1;
|
294
|
-
x_nodes[j].value = (double)x_pt[i * n_features + j];
|
295
|
-
}
|
290
|
+
x_nodes = dbl_vec_to_svm_node(&x_pt[i * n_features], n_features);
|
296
291
|
y_pt[i] = svm_predict(model, x_nodes);
|
292
|
+
xfree(x_nodes);
|
297
293
|
}
|
298
294
|
|
299
|
-
xfree(x_nodes);
|
300
295
|
xfree_svm_model(model);
|
301
296
|
xfree_svm_parameter(param);
|
302
297
|
|
@@ -368,34 +363,22 @@ VALUE decision_function(VALUE self, VALUE x_val, VALUE param_hash, VALUE model_h
|
|
368
363
|
|
369
364
|
/* Predict values. */
|
370
365
|
if (model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) {
|
371
|
-
x_nodes = ALLOC_N(struct svm_node, n_features + 1);
|
372
|
-
x_nodes[n_features].index = -1;
|
373
|
-
x_nodes[n_features].value = 0.0;
|
374
366
|
for (i = 0; i < n_samples; i++) {
|
375
|
-
|
376
|
-
x_nodes[j].index = j + 1;
|
377
|
-
x_nodes[j].value = (double)x_pt[i * n_features + j];
|
378
|
-
}
|
367
|
+
x_nodes = dbl_vec_to_svm_node(&x_pt[i * n_features], n_features);
|
379
368
|
svm_predict_values(model, x_nodes, &y_pt[i]);
|
369
|
+
xfree(x_nodes);
|
380
370
|
}
|
381
|
-
xfree(x_nodes);
|
382
371
|
} else {
|
383
372
|
y_cols = (int)y_shape[1];
|
384
373
|
dec_values = ALLOC_N(double, y_cols);
|
385
|
-
x_nodes = ALLOC_N(struct svm_node, n_features + 1);
|
386
|
-
x_nodes[n_features].index = -1;
|
387
|
-
x_nodes[n_features].value = 0.0;
|
388
374
|
for (i = 0; i < n_samples; i++) {
|
389
|
-
|
390
|
-
x_nodes[j].index = j + 1;
|
391
|
-
x_nodes[j].value = (double)x_pt[i * n_features + j];
|
392
|
-
}
|
375
|
+
x_nodes = dbl_vec_to_svm_node(&x_pt[i * n_features], n_features);
|
393
376
|
svm_predict_values(model, x_nodes, dec_values);
|
377
|
+
xfree(x_nodes);
|
394
378
|
for (j = 0; j < y_cols; j++) {
|
395
379
|
y_pt[i * y_cols + j] = dec_values[j];
|
396
380
|
}
|
397
381
|
}
|
398
|
-
xfree(x_nodes);
|
399
382
|
xfree(dec_values);
|
400
383
|
}
|
401
384
|
|
@@ -463,20 +446,14 @@ VALUE predict_proba(VALUE self, VALUE x_val, VALUE param_hash, VALUE model_hash)
|
|
463
446
|
|
464
447
|
/* Predict values. */
|
465
448
|
probs = ALLOC_N(double, model->nr_class);
|
466
|
-
x_nodes = ALLOC_N(struct svm_node, n_features + 1);
|
467
|
-
x_nodes[n_features].index = -1;
|
468
|
-
x_nodes[n_features].value = 0.0;
|
469
449
|
for (i = 0; i < n_samples; i++) {
|
470
|
-
|
471
|
-
x_nodes[j].index = j + 1;
|
472
|
-
x_nodes[j].value = (double)x_pt[i * n_features + j];
|
473
|
-
}
|
450
|
+
x_nodes = dbl_vec_to_svm_node(&x_pt[i * n_features], n_features);
|
474
451
|
svm_predict_probability(model, x_nodes, probs);
|
452
|
+
xfree(x_nodes);
|
475
453
|
for (j = 0; j < model->nr_class; j++) {
|
476
454
|
y_pt[i * model->nr_class + j] = probs[j];
|
477
455
|
}
|
478
456
|
}
|
479
|
-
xfree(x_nodes);
|
480
457
|
xfree(probs);
|
481
458
|
}
|
482
459
|
|
@@ -29,9 +29,12 @@ struct svm_problem* dataset_to_svm_problem(VALUE x_val, VALUE y_val)
|
|
29
29
|
narray_t* x_nary;
|
30
30
|
double* x_pt;
|
31
31
|
double* y_pt;
|
32
|
-
int i, j;
|
32
|
+
int i, j, k;
|
33
33
|
int n_samples;
|
34
34
|
int n_features;
|
35
|
+
int n_nonzero_features;
|
36
|
+
int is_padded;
|
37
|
+
int last_feature_id;
|
35
38
|
|
36
39
|
GetNArray(x_val, x_nary);
|
37
40
|
n_samples = (int)NA_SHAPE(x_nary)[0];
|
@@ -43,14 +46,40 @@ struct svm_problem* dataset_to_svm_problem(VALUE x_val, VALUE y_val)
|
|
43
46
|
problem->l = n_samples;
|
44
47
|
problem->x = ALLOC_N(struct svm_node*, n_samples);
|
45
48
|
problem->y = ALLOC_N(double, n_samples);
|
49
|
+
|
50
|
+
is_padded = 0;
|
46
51
|
for (i = 0; i < n_samples; i++) {
|
47
|
-
|
52
|
+
n_nonzero_features = 0;
|
48
53
|
for (j = 0; j < n_features; j++) {
|
49
|
-
|
50
|
-
|
54
|
+
if (x_pt[i * n_features + j] != 0.0) {
|
55
|
+
n_nonzero_features += 1;
|
56
|
+
last_feature_id = j + 1;
|
57
|
+
}
|
58
|
+
}
|
59
|
+
if (is_padded == 0 && last_feature_id == n_features) {
|
60
|
+
is_padded = 1;
|
61
|
+
}
|
62
|
+
if (is_padded == 1) {
|
63
|
+
problem->x[i] = ALLOC_N(struct svm_node, n_nonzero_features + 1);
|
64
|
+
} else {
|
65
|
+
problem->x[i] = ALLOC_N(struct svm_node, n_nonzero_features + 2);
|
66
|
+
}
|
67
|
+
for (j = 0, k = 0; j < n_features; j++) {
|
68
|
+
if (x_pt[i * n_features + j] != 0.0) {
|
69
|
+
problem->x[i][k].index = j + 1;
|
70
|
+
problem->x[i][k].value = (double)x_pt[i * n_features + j];
|
71
|
+
k++;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
if (is_padded == 1) {
|
75
|
+
problem->x[i][n_nonzero_features].index = -1;
|
76
|
+
problem->x[i][n_nonzero_features].value = 0.0;
|
77
|
+
} else {
|
78
|
+
problem->x[i][n_nonzero_features].index = n_features;
|
79
|
+
problem->x[i][n_nonzero_features].value = 0.0;
|
80
|
+
problem->x[i][n_nonzero_features + 1].index = -1;
|
81
|
+
problem->x[i][n_nonzero_features + 1].value = 0.0;
|
51
82
|
}
|
52
|
-
problem->x[i][n_features].index = -1;
|
53
|
-
problem->x[i][n_features].value = 0.0;
|
54
83
|
problem->y[i] = y_pt[i];
|
55
84
|
}
|
56
85
|
|
data/lib/numo/libsvm/version.rb
CHANGED
data/numo-libsvm.gemspec
CHANGED
@@ -33,6 +33,12 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.require_paths = ['lib']
|
34
34
|
spec.extensions = ['ext/numo/libsvm/extconf.rb']
|
35
35
|
|
36
|
+
spec.metadata = {
|
37
|
+
'homepage_uri' => 'https://github.com/yoshoku/numo-libsvm',
|
38
|
+
'source_code_uri' => 'https://github.com/yoshoku/numo-libsvm',
|
39
|
+
'documentation_uri' => 'https://yoshoku.github.io/numo-libsvm/doc/'
|
40
|
+
}
|
41
|
+
|
36
42
|
spec.add_runtime_dependency 'numo-narray', '~> 0.9.1'
|
37
43
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
38
44
|
spec.add_development_dependency 'rake', '~> 10.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numo-libsvm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshoku
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|
@@ -122,7 +122,10 @@ files:
|
|
122
122
|
homepage: https://github.com/yoshoku/numo-libsvm
|
123
123
|
licenses:
|
124
124
|
- BSD-3-Clause
|
125
|
-
metadata:
|
125
|
+
metadata:
|
126
|
+
homepage_uri: https://github.com/yoshoku/numo-libsvm
|
127
|
+
source_code_uri: https://github.com/yoshoku/numo-libsvm
|
128
|
+
documentation_uri: https://yoshoku.github.io/numo-libsvm/doc/
|
126
129
|
post_install_message:
|
127
130
|
rdoc_options: []
|
128
131
|
require_paths:
|