numo-libsvm 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|