numo-liblinear 0.1.0 → 0.2.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 +4 -0
- data/README.md +2 -0
- data/ext/numo/liblinear/liblinearext.c +118 -24
- data/lib/numo/liblinear/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bf71a14ccac359b6dffce32a5a5d3c784ef9efa
|
4
|
+
data.tar.gz: 6af9f95c6b28c11b06fc0b10628a37e9397564c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18e64c5d487cab2636216425e45fd8eeaefa0f14026068d3678f0d8d643aea00acf867aa64ba510a62d4c343408a9e22bace2a0347a7b7aba7ddd872f2bbc579
|
7
|
+
data.tar.gz: 43e16f69a931aab7a45163f1909e307f3334ef88f4e45ed79e5513b288804d5c0dfcbb92ef79642bb7c40e70bcdffe6f47548a2cad10351da3585dd48f0a84db
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# Numo::Liblinear
|
2
2
|
|
3
3
|
[](https://travis-ci.org/yoshoku/numo-liblinear)
|
4
|
+
[](https://badge.fury.io/rb/numo-liblinear)
|
4
5
|
[](https://github.com/yoshoku/numo-liblinear/blob/master/LICENSE.txt)
|
6
|
+
[](https://www.rubydoc.info/gems/numo-liblinear/0.2.0)
|
5
7
|
|
6
8
|
Numo::Liblinear is a Ruby gem binding to the [LIBLINEAR](https://www.csie.ntu.edu.tw/~cjlin/liblinear/) library.
|
7
9
|
LIBLINEAR is one of the famous libraries for large-scale regularized linear classification and regression.
|
@@ -12,10 +12,13 @@ void print_null(const char *s) {}
|
|
12
12
|
* Train the model according to the given training data.
|
13
13
|
*
|
14
14
|
* @overload train(x, y, param) -> Hash
|
15
|
+
* @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to be used for training the model.
|
16
|
+
* @param y [Numo::DFloat] (shape: [n_samples]) The labels or target values for samples.
|
17
|
+
* @param param [Hash] The parameters of a model.
|
15
18
|
*
|
16
|
-
* @
|
17
|
-
*
|
18
|
-
*
|
19
|
+
* @raise [ArgumentError] If the sample array is not 2-dimensional, the label array is not 1-dimensional,
|
20
|
+
* the sample array and label array do not have the same number of samples, or
|
21
|
+
* the hyperparameter has an invalid value, this error is raised.
|
19
22
|
* @return [Hash] The model obtained from the training procedure.
|
20
23
|
*/
|
21
24
|
static
|
@@ -24,6 +27,9 @@ VALUE numo_liblinear_train(VALUE self, VALUE x_val, VALUE y_val, VALUE param_has
|
|
24
27
|
struct problem* problem;
|
25
28
|
struct parameter* param;
|
26
29
|
struct model* model;
|
30
|
+
narray_t* x_nary;
|
31
|
+
narray_t* y_nary;
|
32
|
+
char* err_msg;
|
27
33
|
VALUE model_hash;
|
28
34
|
|
29
35
|
if (CLASS_OF(x_val) != numo_cDFloat) {
|
@@ -39,9 +45,32 @@ VALUE numo_liblinear_train(VALUE self, VALUE x_val, VALUE y_val, VALUE param_has
|
|
39
45
|
y_val = nary_dup(y_val);
|
40
46
|
}
|
41
47
|
|
48
|
+
GetNArray(x_val, x_nary);
|
49
|
+
GetNArray(y_val, y_nary);
|
50
|
+
if (NA_NDIM(x_nary) != 2) {
|
51
|
+
rb_raise(rb_eArgError, "Expect samples to be 2-D array.");
|
52
|
+
return Qnil;
|
53
|
+
}
|
54
|
+
if (NA_NDIM(y_nary) != 1) {
|
55
|
+
rb_raise(rb_eArgError, "Expect label or target values to be 1-D arrray.");
|
56
|
+
return Qnil;
|
57
|
+
}
|
58
|
+
if (NA_SHAPE(x_nary)[0] != NA_SHAPE(y_nary)[0]) {
|
59
|
+
rb_raise(rb_eArgError, "Expect to have the same number of samples for samples and labels.");
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
|
42
63
|
param = rb_hash_to_parameter(param_hash);
|
43
64
|
problem = dataset_to_problem(x_val, y_val);
|
44
65
|
|
66
|
+
err_msg = check_parameter(problem, param);
|
67
|
+
if (err_msg) {
|
68
|
+
xfree_problem(problem);
|
69
|
+
xfree_parameter(param);
|
70
|
+
rb_raise(rb_eArgError, "Invalid LIBLINEAR parameter is given: %s", err_msg);
|
71
|
+
return Qnil;
|
72
|
+
}
|
73
|
+
|
45
74
|
set_print_string_function(print_null);
|
46
75
|
model = train(problem, param);
|
47
76
|
model_hash = model_to_rb_hash(model);
|
@@ -58,11 +87,14 @@ VALUE numo_liblinear_train(VALUE self, VALUE x_val, VALUE y_val, VALUE param_has
|
|
58
87
|
* The predicted labels or values in the validation process are returned.
|
59
88
|
*
|
60
89
|
* @overload cv(x, y, param, n_folds) -> Numo::DFloat
|
90
|
+
* @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to be used for training the model.
|
91
|
+
* @param y [Numo::DFloat] (shape: [n_samples]) The labels or target values for samples.
|
92
|
+
* @param param [Hash] The parameters of a model.
|
93
|
+
* @param n_folds [Integer] The number of folds.
|
61
94
|
*
|
62
|
-
* @
|
63
|
-
*
|
64
|
-
*
|
65
|
-
* @param n_folds [Integer] The number of folds.
|
95
|
+
* @raise [ArgumentError] If the sample array is not 2-dimensional, the label array is not 1-dimensional,
|
96
|
+
* the sample array and label array do not have the same number of samples, or
|
97
|
+
* the hyperparameter has an invalid value, this error is raised.
|
66
98
|
* @return [Numo::DFloat] (shape: [n_samples]) The predicted class label or value of each sample.
|
67
99
|
*/
|
68
100
|
static
|
@@ -72,6 +104,9 @@ VALUE numo_liblinear_cross_validation(VALUE self, VALUE x_val, VALUE y_val, VALU
|
|
72
104
|
size_t t_shape[1];
|
73
105
|
VALUE t_val;
|
74
106
|
double* t_pt;
|
107
|
+
narray_t* x_nary;
|
108
|
+
narray_t* y_nary;
|
109
|
+
char* err_msg;
|
75
110
|
struct problem* problem;
|
76
111
|
struct parameter* param;
|
77
112
|
|
@@ -88,9 +123,32 @@ VALUE numo_liblinear_cross_validation(VALUE self, VALUE x_val, VALUE y_val, VALU
|
|
88
123
|
y_val = nary_dup(y_val);
|
89
124
|
}
|
90
125
|
|
126
|
+
GetNArray(x_val, x_nary);
|
127
|
+
GetNArray(y_val, y_nary);
|
128
|
+
if (NA_NDIM(x_nary) != 2) {
|
129
|
+
rb_raise(rb_eArgError, "Expect samples to be 2-D array.");
|
130
|
+
return Qnil;
|
131
|
+
}
|
132
|
+
if (NA_NDIM(y_nary) != 1) {
|
133
|
+
rb_raise(rb_eArgError, "Expect label or target values to be 1-D arrray.");
|
134
|
+
return Qnil;
|
135
|
+
}
|
136
|
+
if (NA_SHAPE(x_nary)[0] != NA_SHAPE(y_nary)[0]) {
|
137
|
+
rb_raise(rb_eArgError, "Expect to have the same number of samples for samples and labels.");
|
138
|
+
return Qnil;
|
139
|
+
}
|
140
|
+
|
91
141
|
param = rb_hash_to_parameter(param_hash);
|
92
142
|
problem = dataset_to_problem(x_val, y_val);
|
93
143
|
|
144
|
+
err_msg = check_parameter(problem, param);
|
145
|
+
if (err_msg) {
|
146
|
+
xfree_problem(problem);
|
147
|
+
xfree_parameter(param);
|
148
|
+
rb_raise(rb_eArgError, "Invalid LIBLINEAR parameter is given: %s", err_msg);
|
149
|
+
return Qnil;
|
150
|
+
}
|
151
|
+
|
94
152
|
t_shape[0] = problem->l;
|
95
153
|
t_val = rb_narray_new(numo_cDFloat, 1, t_shape);
|
96
154
|
t_pt = (double*)na_get_pointer_for_write(t_val);
|
@@ -109,10 +167,11 @@ VALUE numo_liblinear_cross_validation(VALUE self, VALUE x_val, VALUE y_val, VALU
|
|
109
167
|
* Predict class labels or values for given samples.
|
110
168
|
*
|
111
169
|
* @overload predict(x, param, model) -> Numo::DFloat
|
170
|
+
* @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to calculate the scores.
|
171
|
+
* @param param [Hash] The parameters of the trained model.
|
172
|
+
* @param model [Hash] The model obtained from the training procedure.
|
112
173
|
*
|
113
|
-
* @
|
114
|
-
* @param param [Hash] The parameters of the trained model.
|
115
|
-
* @param model [Hash] The model obtained from the training procedure.
|
174
|
+
* @raise [ArgumentError] If the sample array is not 2-dimensional, this error is raised.
|
116
175
|
* @return [Numo::DFloat] (shape: [n_samples]) The predicted class label or value of each sample.
|
117
176
|
*/
|
118
177
|
static
|
@@ -137,7 +196,13 @@ VALUE numo_liblinear_predict(VALUE self, VALUE x_val, VALUE param_hash, VALUE mo
|
|
137
196
|
if (!RTEST(nary_check_contiguous(x_val))) {
|
138
197
|
x_val = nary_dup(x_val);
|
139
198
|
}
|
199
|
+
|
140
200
|
GetNArray(x_val, x_nary);
|
201
|
+
if (NA_NDIM(x_nary) != 2) {
|
202
|
+
rb_raise(rb_eArgError, "Expect samples to be 2-D array.");
|
203
|
+
return Qnil;
|
204
|
+
}
|
205
|
+
|
141
206
|
param = rb_hash_to_parameter(param_hash);
|
142
207
|
model = rb_hash_to_model(model_hash);
|
143
208
|
model->param = *param;
|
@@ -173,10 +238,11 @@ VALUE numo_liblinear_predict(VALUE self, VALUE x_val, VALUE param_hash, VALUE mo
|
|
173
238
|
* Calculate decision values for given samples.
|
174
239
|
*
|
175
240
|
* @overload decision_function(x, param, model) -> Numo::DFloat
|
241
|
+
* @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to calculate the scores.
|
242
|
+
* @param param [Hash] The parameters of the trained model.
|
243
|
+
* @param model [Hash] The model obtained from the training procedure.
|
176
244
|
*
|
177
|
-
* @
|
178
|
-
* @param param [Hash] The parameters of the trained model.
|
179
|
-
* @param model [Hash] The model obtained from the training procedure.
|
245
|
+
* @raise [ArgumentError] If the sample array is not 2-dimensional, this error is raised.
|
180
246
|
* @return [Numo::DFloat] (shape: [n_samples, n_classes]) The decision value of each sample.
|
181
247
|
*/
|
182
248
|
static
|
@@ -203,7 +269,13 @@ VALUE numo_liblinear_decision_function(VALUE self, VALUE x_val, VALUE param_hash
|
|
203
269
|
if (!RTEST(nary_check_contiguous(x_val))) {
|
204
270
|
x_val = nary_dup(x_val);
|
205
271
|
}
|
272
|
+
|
206
273
|
GetNArray(x_val, x_nary);
|
274
|
+
if (NA_NDIM(x_nary) != 2) {
|
275
|
+
rb_raise(rb_eArgError, "Expect samples to be 2-D array.");
|
276
|
+
return Qnil;
|
277
|
+
}
|
278
|
+
|
207
279
|
param = rb_hash_to_parameter(param_hash);
|
208
280
|
model = rb_hash_to_model(model_hash);
|
209
281
|
model->param = *param;
|
@@ -270,10 +342,11 @@ VALUE numo_liblinear_decision_function(VALUE self, VALUE x_val, VALUE param_hash
|
|
270
342
|
* The method supports only the logistic regression.
|
271
343
|
*
|
272
344
|
* @overload predict_proba(x, param, model) -> Numo::DFloat
|
345
|
+
* @param x [Numo::DFloat] (shape: [n_samples, n_features]) The samples to predict the class probabilities.
|
346
|
+
* @param param [Hash] The parameters of the trained Logistic Regression model.
|
347
|
+
* @param model [Hash] The model obtained from the training procedure.
|
273
348
|
*
|
274
|
-
* @
|
275
|
-
* @param param [Hash] The parameters of the trained Logistic Regression model.
|
276
|
-
* @param model [Hash] The model obtained from the training procedure.
|
349
|
+
* @raise [ArgumentError] If the sample array is not 2-dimensional, this error is raised.
|
277
350
|
* @return [Numo::DFloat] (shape: [n_samples, n_classes]) Predicted probablity of each class per sample.
|
278
351
|
*/
|
279
352
|
static
|
@@ -292,6 +365,12 @@ VALUE numo_liblinear_predict_proba(VALUE self, VALUE x_val, VALUE param_hash, VA
|
|
292
365
|
int n_samples;
|
293
366
|
int n_features;
|
294
367
|
|
368
|
+
GetNArray(x_val, x_nary);
|
369
|
+
if (NA_NDIM(x_nary) != 2) {
|
370
|
+
rb_raise(rb_eArgError, "Expect samples to be 2-D array.");
|
371
|
+
return Qnil;
|
372
|
+
}
|
373
|
+
|
295
374
|
param = rb_hash_to_parameter(param_hash);
|
296
375
|
model = rb_hash_to_model(model_hash);
|
297
376
|
model->param = *param;
|
@@ -304,7 +383,6 @@ VALUE numo_liblinear_predict_proba(VALUE self, VALUE x_val, VALUE param_hash, VA
|
|
304
383
|
if (!RTEST(nary_check_contiguous(x_val))) {
|
305
384
|
x_val = nary_dup(x_val);
|
306
385
|
}
|
307
|
-
GetNArray(x_val, x_nary);
|
308
386
|
|
309
387
|
/* Initialize some variables. */
|
310
388
|
n_samples = (int)NA_SHAPE(x_nary)[0];
|
@@ -343,17 +421,26 @@ VALUE numo_liblinear_predict_proba(VALUE self, VALUE x_val, VALUE param_hash, VA
|
|
343
421
|
/**
|
344
422
|
* Load the parameters and model from a text file with LIBLINEAR format.
|
345
423
|
*
|
346
|
-
* @
|
424
|
+
* @overload load_model(filename) -> Array
|
425
|
+
* @param filename [String] The path to a file to load.
|
426
|
+
*
|
427
|
+
* @raise [IOError] This error raises when failed to load the model file.
|
347
428
|
* @return [Array] Array contains the parameters and model.
|
348
429
|
*/
|
349
430
|
static
|
350
431
|
VALUE numo_liblinear_load_model(VALUE self, VALUE filename)
|
351
432
|
{
|
352
|
-
|
433
|
+
char* filename_ = StringValuePtr(filename);
|
434
|
+
struct model* model = load_model(filename_);
|
353
435
|
VALUE res = rb_ary_new2(2);
|
354
436
|
VALUE param_hash = Qnil;
|
355
437
|
VALUE model_hash = Qnil;
|
356
438
|
|
439
|
+
if (model == NULL) {
|
440
|
+
rb_raise(rb_eIOError, "Failed to load file '%s'", filename_);
|
441
|
+
return Qnil;
|
442
|
+
}
|
443
|
+
|
357
444
|
if (model) {
|
358
445
|
param_hash = parameter_to_rb_hash(&(model->param));
|
359
446
|
model_hash = model_to_rb_hash(model);
|
@@ -371,26 +458,33 @@ VALUE numo_liblinear_load_model(VALUE self, VALUE filename)
|
|
371
458
|
* Note that the save_model saves only the parameters necessary for estimation with the trained model.
|
372
459
|
*
|
373
460
|
* @overload save_model(filename, param, model) -> Boolean
|
461
|
+
* @param filename [String] The path to a file to save.
|
462
|
+
* @param param [Hash] The parameters of the trained model.
|
463
|
+
* @param model [Hash] The model obtained from the training procedure.
|
374
464
|
*
|
375
|
-
* @
|
376
|
-
* @param param [Hash] The parameters of the trained model.
|
377
|
-
* @param model [Hash] The model obtained from the training procedure.
|
465
|
+
* @raise [IOError] This error raises when failed to save the model file.
|
378
466
|
* @return [Boolean] true on success, or false if an error occurs.
|
379
467
|
*/
|
380
468
|
static
|
381
469
|
VALUE numo_liblinear_save_model(VALUE self, VALUE filename, VALUE param_hash, VALUE model_hash)
|
382
470
|
{
|
471
|
+
char* filename_ = StringValuePtr(filename);
|
383
472
|
struct parameter* param = rb_hash_to_parameter(param_hash);
|
384
473
|
struct model* model = rb_hash_to_model(model_hash);
|
385
474
|
int res;
|
386
475
|
|
387
476
|
model->param = *param;
|
388
|
-
res = save_model(
|
477
|
+
res = save_model(filename_, model);
|
389
478
|
|
390
479
|
xfree_model(model);
|
391
480
|
xfree_parameter(param);
|
392
481
|
|
393
|
-
|
482
|
+
if (res < 0) {
|
483
|
+
rb_raise(rb_eIOError, "Failed to save file '%s'", filename_);
|
484
|
+
return Qfalse;
|
485
|
+
}
|
486
|
+
|
487
|
+
return Qtrue;
|
394
488
|
}
|
395
489
|
|
396
490
|
void Init_liblinearext()
|
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
|
+
version: 0.2.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-
|
11
|
+
date: 2019-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: numo-narray
|