numo-liblinear 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31b76e6a2a8dcfc5cb643fa0b62cd9ace5b6a76c
4
- data.tar.gz: 6d8b6d9ed6a7e069ca8fcb78fb9f8999ccdfe1c5
3
+ metadata.gz: 25a456af8f35df53f449634445d25b92acbd3b78
4
+ data.tar.gz: 803d29787ecbe7c9f97c98924315c45ae8a8eba0
5
5
  SHA512:
6
- metadata.gz: 8efe216d52fc7bba1561f46c3a372e842d6bdaf371c9b71b7662e380a17e9c6396e4a67348156522a41785bf2a12f37675dd137f173a0f52b6c48528c9c70cf7
7
- data.tar.gz: e23e845ed639ee5e7fff6cbbbe936feed71f3a7e16429c52a27872b019201818649de57576030fb996cd697ff490588a0ec8e8d1e452eb0d441baa4ea00bcf52
6
+ metadata.gz: a4cc867afc83ea85f816113136b31454edfacd5eb8471341492dd3bf3e618e1ac95a144f58a024625d0c35cc17e726085c43d7a69c4e36acb058b5348cd68846
7
+ data.tar.gz: 559931664558ca8979493254037dd275bd1e5d5b892f2a9d53f4d4c1e1bc805faf9466c88787ae31fc8103bdd58f5b7bb277f2d3fb9934b37d5d5d739d9d51a5
@@ -1,3 +1,6 @@
1
+ # 0.5.0
2
+ - Fix to use LIBLINEAR sparce vector representation for internal processing.
3
+
1
4
  # 0.4.0
2
5
  - Add verbose parameter to output learning process messages.
3
6
  - Several documentation improvements.
@@ -100,3 +100,28 @@ double** nary_to_dbl_mat(VALUE mat_val)
100
100
 
101
101
  return mat;
102
102
  }
103
+
104
+ struct feature_node* dbl_vec_to_node(double* const arr, int const size)
105
+ {
106
+ int i, j;
107
+ int n_nonzero_elements;
108
+ struct feature_node* node;
109
+
110
+ n_nonzero_elements = 0;
111
+ for (i = 0; i < size; i++) {
112
+ if (arr[i] != 0.0) n_nonzero_elements++;
113
+ }
114
+
115
+ node = ALLOC_N(struct feature_node, n_nonzero_elements + 1);
116
+ for (i = 0, j = 0; i < size; i++) {
117
+ if (arr[i] != 0.0) {
118
+ node[j].index = i + 1;
119
+ node[j].value = arr[i];
120
+ j++;
121
+ }
122
+ }
123
+ node[n_nonzero_elements].index = -1;
124
+ node[n_nonzero_elements].value = 0.0;
125
+
126
+ return node;
127
+ }
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <string.h>
5
5
  #include <ruby.h>
6
+ #include <linear.h>
6
7
  #include <numo/narray.h>
7
8
  #include <numo/template.h>
8
9
 
@@ -12,5 +13,6 @@ VALUE dbl_vec_to_nary(double* const arr, int const size);
12
13
  double* nary_to_dbl_vec(VALUE vec_val);
13
14
  VALUE dbl_mat_to_nary(double** const mat, int const n_rows, int const n_cols);
14
15
  double** nary_to_dbl_mat(VALUE mat_val);
16
+ struct feature_node* dbl_vec_to_node(double* const arr, int const size);
15
17
 
16
18
  #endif /* NUMO_LIBLINEAR_CONVERTER_H */
@@ -282,18 +282,12 @@ VALUE numo_liblinear_predict(VALUE self, VALUE x_val, VALUE param_hash, VALUE mo
282
282
  x_pt = (double*)na_get_pointer_for_read(x_val);
283
283
 
284
284
  /* Predict values. */
285
- x_nodes = ALLOC_N(struct feature_node, n_features + 1);
286
- x_nodes[n_features].index = -1;
287
- x_nodes[n_features].value = 0.0;
288
285
  for (i = 0; i < n_samples; i++) {
289
- for (j = 0; j < n_features; j++) {
290
- x_nodes[j].index = j + 1;
291
- x_nodes[j].value = (double)x_pt[i * n_features + j];
292
- }
286
+ x_nodes = dbl_vec_to_node(&x_pt[i * n_features], n_features);
293
287
  y_pt[i] = predict(model, x_nodes);
288
+ xfree(x_nodes);
294
289
  }
295
290
 
296
- xfree(x_nodes);
297
291
  xfree_model(model);
298
292
  xfree_parameter(param);
299
293
 
@@ -365,34 +359,22 @@ VALUE numo_liblinear_decision_function(VALUE self, VALUE x_val, VALUE param_hash
365
359
 
366
360
  /* Predict values. */
367
361
  if (model->nr_class == 2 && model->param.solver_type != MCSVM_CS) {
368
- x_nodes = ALLOC_N(struct feature_node, n_features + 1);
369
- x_nodes[n_features].index = -1;
370
- x_nodes[n_features].value = 0.0;
371
362
  for (i = 0; i < n_samples; i++) {
372
- for (j = 0; j < n_features; j++) {
373
- x_nodes[j].index = j + 1;
374
- x_nodes[j].value = (double)x_pt[i * n_features + j];
375
- }
363
+ x_nodes = dbl_vec_to_node(&x_pt[i * n_features], n_features);
376
364
  predict_values(model, x_nodes, &y_pt[i]);
365
+ xfree(x_nodes);
377
366
  }
378
- xfree(x_nodes);
379
367
  } else {
380
368
  y_cols = (int)y_shape[1];
381
369
  dec_values = ALLOC_N(double, y_cols);
382
- x_nodes = ALLOC_N(struct feature_node, n_features + 1);
383
- x_nodes[n_features].index = -1;
384
- x_nodes[n_features].value = 0.0;
385
370
  for (i = 0; i < n_samples; i++) {
386
- for (j = 0; j < n_features; j++) {
387
- x_nodes[j].index = j + 1;
388
- x_nodes[j].value = (double)x_pt[i * n_features + j];
389
- }
371
+ x_nodes = dbl_vec_to_node(&x_pt[i * n_features], n_features);
390
372
  predict_values(model, x_nodes, dec_values);
373
+ xfree(x_nodes);
391
374
  for (j = 0; j < y_cols; j++) {
392
375
  y_pt[i * y_cols + j] = dec_values[j];
393
376
  }
394
377
  }
395
- xfree(x_nodes);
396
378
  xfree(dec_values);
397
379
  }
398
380
 
@@ -461,20 +443,14 @@ VALUE numo_liblinear_predict_proba(VALUE self, VALUE x_val, VALUE param_hash, VA
461
443
 
462
444
  /* Predict values. */
463
445
  probs = ALLOC_N(double, model->nr_class);
464
- x_nodes = ALLOC_N(struct feature_node, n_features + 1);
465
- x_nodes[n_features].index = -1;
466
- x_nodes[n_features].value = 0.0;
467
446
  for (i = 0; i < n_samples; i++) {
468
- for (j = 0; j < n_features; j++) {
469
- x_nodes[j].index = j + 1;
470
- x_nodes[j].value = (double)x_pt[i * n_features + j];
471
- }
447
+ x_nodes = dbl_vec_to_node(&x_pt[i * n_features], n_features);
472
448
  predict_probability(model, x_nodes, probs);
449
+ xfree(x_nodes);
473
450
  for (j = 0; j < model->nr_class; j++) {
474
451
  y_pt[i * model->nr_class + j] = probs[j];
475
452
  }
476
453
  }
477
- xfree(x_nodes);
478
454
  xfree(probs);
479
455
  }
480
456
 
@@ -29,9 +29,12 @@ struct problem* dataset_to_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];
@@ -46,14 +49,39 @@ struct problem* dataset_to_problem(VALUE x_val, VALUE y_val)
46
49
  problem->x = ALLOC_N(struct feature_node*, n_samples);
47
50
  problem->y = ALLOC_N(double, n_samples);
48
51
 
52
+ is_padded = 0;
49
53
  for (i = 0; i < n_samples; i++) {
50
- problem->x[i] = ALLOC_N(struct feature_node, n_features + 1);
54
+ n_nonzero_features = 0;
51
55
  for (j = 0; j < n_features; j++) {
52
- problem->x[i][j].index = j + 1;
53
- problem->x[i][j].value = x_pt[i * n_features + j];
56
+ if (x_pt[i * n_features + j] != 0.0) {
57
+ n_nonzero_features++;
58
+ last_feature_id = j + 1;
59
+ }
60
+ }
61
+ if (is_padded == 0 && last_feature_id == n_features) {
62
+ is_padded = 1;
63
+ }
64
+ if (is_padded == 1) {
65
+ problem->x[i] = ALLOC_N(struct feature_node, n_nonzero_features + 1);
66
+ } else {
67
+ problem->x[i] = ALLOC_N(struct feature_node, n_nonzero_features + 2);
68
+ }
69
+ for (j = 0, k = 0; j < n_features; j++) {
70
+ if (x_pt[i * n_features + j] != 0.0) {
71
+ problem->x[i][k].index = j + 1;
72
+ problem->x[i][k].value = x_pt[i * n_features + j];
73
+ k++;
74
+ }
75
+ }
76
+ if (is_padded == 1) {
77
+ problem->x[i][n_nonzero_features].index = -1;
78
+ problem->x[i][n_nonzero_features].value = 0.0;
79
+ } else {
80
+ problem->x[i][n_nonzero_features].index = n_features;
81
+ problem->x[i][n_nonzero_features].value = 0.0;
82
+ problem->x[i][n_nonzero_features + 1].index = -1;
83
+ problem->x[i][n_nonzero_features + 1].value = 0.0;
54
84
  }
55
- problem->x[i][n_features].index = -1;
56
- problem->x[i][n_features].value = 0.0;
57
85
  problem->y[i] = y_pt[i];
58
86
  }
59
87
 
@@ -3,6 +3,6 @@
3
3
  module Numo
4
4
  module Liblinear
5
5
  # The version of Numo::Liblienar you are using.
6
- VERSION = '0.4.0'
6
+ VERSION = '0.5.0'
7
7
  end
8
8
  end
@@ -32,6 +32,12 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ['lib']
33
33
  spec.extensions = ['ext/numo/liblinear/extconf.rb']
34
34
 
35
+ spec.metadata = {
36
+ 'homepage_uri' => 'https://github.com/yoshoku/numo-liblinear',
37
+ 'source_code_uri' => 'https://github.com/yoshoku/numo-liblinear',
38
+ 'documentation_uri' => 'https://yoshoku.github.io/numo-liblinear/doc/'
39
+ }
40
+
35
41
  spec.add_runtime_dependency 'numo-narray', '~> 0.9.1'
36
42
  spec.add_development_dependency 'bundler', '~> 2.0'
37
43
  spec.add_development_dependency 'rake', '~> 10.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-liblinear
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.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-01 00:00:00.000000000 Z
11
+ date: 2019-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: numo-narray
@@ -119,7 +119,10 @@ files:
119
119
  homepage: https://github.com/yoshoku/numo-liblinear
120
120
  licenses:
121
121
  - BSD-3-Clause
122
- metadata: {}
122
+ metadata:
123
+ homepage_uri: https://github.com/yoshoku/numo-liblinear
124
+ source_code_uri: https://github.com/yoshoku/numo-liblinear
125
+ documentation_uri: https://yoshoku.github.io/numo-liblinear/doc/
123
126
  post_install_message:
124
127
  rdoc_options: []
125
128
  require_paths: