numo-liblinear 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ #ifndef NUMO_LIBLINEAREXT_H
2
+ #define NUMO_LIBLINEAREXT_H 1
3
+
4
+ #include <math.h>
5
+ #include <string.h>
6
+ #include <linear.h>
7
+ #include <ruby.h>
8
+ #include <numo/narray.h>
9
+ #include <numo/template.h>
10
+
11
+ #include "converter.h"
12
+ #include "parameter.h"
13
+ #include "model.h"
14
+ #include "problem.h"
15
+ #include "solver_type.h"
16
+
17
+ #endif /* NUMO_LIBLINEAREXT_H */
@@ -0,0 +1,45 @@
1
+ #include "model.h"
2
+
3
+ struct model* rb_hash_to_model(VALUE model_hash)
4
+ {
5
+ VALUE el;
6
+ struct model* model = ALLOC(struct model);
7
+ el = rb_hash_aref(model_hash, ID2SYM(rb_intern("nr_class")));
8
+ model->nr_class = el != Qnil ? NUM2INT(el) : 0;
9
+ el = rb_hash_aref(model_hash, ID2SYM(rb_intern("nr_feature")));
10
+ model->nr_feature = el != Qnil ? NUM2INT(el) : 0;
11
+ el = rb_hash_aref(model_hash, ID2SYM(rb_intern("w")));
12
+ model->w = nary_to_dbl_vec(el);
13
+ el = rb_hash_aref(model_hash, ID2SYM(rb_intern("label")));
14
+ model->label = nary_to_int_vec(el);
15
+ el = rb_hash_aref(model_hash, ID2SYM(rb_intern("bias")));
16
+ model->bias = NUM2DBL(el);
17
+ return model;
18
+ }
19
+
20
+ VALUE model_to_rb_hash(struct model* const model)
21
+ {
22
+ int const n_cols = model->nr_class > 2 ? model->nr_class : 1;
23
+ int const n_rows = model->nr_feature;
24
+ VALUE model_hash = rb_hash_new();
25
+ rb_hash_aset(model_hash, ID2SYM(rb_intern("nr_class")), INT2NUM(model->nr_class));
26
+ rb_hash_aset(model_hash, ID2SYM(rb_intern("nr_feature")), INT2NUM(model->nr_feature));
27
+ rb_hash_aset(model_hash, ID2SYM(rb_intern("w")),
28
+ model->w ? dbl_vec_to_nary(model->w, n_rows * n_cols) : Qnil);
29
+ rb_hash_aset(model_hash, ID2SYM(rb_intern("label")),
30
+ model->label ? int_vec_to_nary(model->label, model->nr_class) : Qnil);
31
+ rb_hash_aset(model_hash, ID2SYM(rb_intern("bias")), DBL2NUM(model->bias));
32
+ return model_hash;
33
+ }
34
+
35
+ void xfree_model(struct model* model)
36
+ {
37
+ if (model) {
38
+ xfree(model->w);
39
+ model->w = NULL;
40
+ xfree(model->label);
41
+ model->label = NULL;
42
+ xfree(model);
43
+ model = NULL;
44
+ }
45
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LIBLINEAR_MODEL_H
2
+ #define NUMO_LIBLINEAR_MODEL_H 1
3
+
4
+ #include <linear.h>
5
+ #include <ruby.h>
6
+ #include <numo/narray.h>
7
+ #include <numo/template.h>
8
+
9
+ #include "converter.h"
10
+
11
+ struct model* rb_hash_to_model(VALUE model_hash);
12
+ VALUE model_to_rb_hash(struct model* const model);
13
+ void xfree_model(struct model* model);
14
+
15
+ #endif /* NUMO_LIBLINEAR_MODEL_H */
@@ -0,0 +1,98 @@
1
+ #include "parameter.h"
2
+
3
+ struct parameter* rb_hash_to_parameter(VALUE param_hash)
4
+ {
5
+ VALUE el;
6
+ struct parameter* param = ALLOC(struct parameter);
7
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("solver_type")));
8
+ param->solver_type = !NIL_P(el) ? NUM2INT(el) : L2R_L2LOSS_SVC_DUAL;
9
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("eps")));
10
+ if (!NIL_P(el)) {
11
+ param->eps = NUM2DBL(el);
12
+ } else {
13
+ switch(param->solver_type)
14
+ {
15
+ case L2R_LR:
16
+ case L2R_L2LOSS_SVC:
17
+ param->eps = 0.01;
18
+ break;
19
+ case L2R_L2LOSS_SVR:
20
+ param->eps = 0.0001;
21
+ break;
22
+ case L2R_L2LOSS_SVC_DUAL:
23
+ case L2R_L1LOSS_SVC_DUAL:
24
+ case MCSVM_CS:
25
+ case L2R_LR_DUAL:
26
+ param->eps = 0.1;
27
+ break;
28
+ case L1R_L2LOSS_SVC:
29
+ case L1R_LR:
30
+ param->eps = 0.01;
31
+ break;
32
+ case L2R_L1LOSS_SVR_DUAL:
33
+ case L2R_L2LOSS_SVR_DUAL:
34
+ param->eps = 0.1;
35
+ break;
36
+ }
37
+ }
38
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("C")));
39
+ param->C = !NIL_P(el) ? NUM2DBL(el) : 1;
40
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("nr_weight")));
41
+ param->nr_weight = !NIL_P(el) ? NUM2INT(el) : 0;
42
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("weight_label")));
43
+ param->weight_label = NULL;
44
+ if (!NIL_P(el)) {
45
+ param->weight_label = ALLOC_N(int, param->nr_weight);
46
+ memcpy(param->weight_label, (int32_t*)na_get_pointer_for_read(el), param->nr_weight);
47
+ }
48
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("weight")));
49
+ param->weight = NULL;
50
+ if (!NIL_P(el)) {
51
+ param->weight = ALLOC_N(double, param->nr_weight);
52
+ memcpy(param->weight, (double*)na_get_pointer_for_read(el), param->nr_weight);
53
+ }
54
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("p")));
55
+ param->p = !NIL_P(el) ? NUM2DBL(el) : 0.1;
56
+ el = rb_hash_aref(param_hash, ID2SYM(rb_intern("init_sol")));
57
+ param->init_sol = NULL;
58
+ if (!NIL_P(el)) {
59
+ param->init_sol = nary_to_dbl_vec(el);
60
+ }
61
+ return param;
62
+ }
63
+
64
+ VALUE parameter_to_rb_hash(struct parameter* const param)
65
+ {
66
+ VALUE param_hash = rb_hash_new();
67
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("solver_type")), INT2NUM(param->solver_type));
68
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("eps")), DBL2NUM(param->eps));
69
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("C")), DBL2NUM(param->C));
70
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("nr_weight")), INT2NUM(param->nr_weight));
71
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("weight_label")),
72
+ param->weight_label ? int_vec_to_nary(param->weight_label, param->nr_weight) : Qnil);
73
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("weight")),
74
+ param->weight ? dbl_vec_to_nary(param->weight, param->nr_weight) : Qnil);
75
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("p")), DBL2NUM(param->p));
76
+ rb_hash_aset(param_hash, ID2SYM(rb_intern("init_sol")), Qnil);
77
+ return param_hash;
78
+ }
79
+
80
+ void xfree_parameter(struct parameter* param)
81
+ {
82
+ if (param) {
83
+ if (param->weight_label) {
84
+ xfree(param->weight_label);
85
+ param->weight_label = NULL;
86
+ }
87
+ if (param->weight) {
88
+ xfree(param->weight);
89
+ param->weight = NULL;
90
+ }
91
+ if (param->init_sol) {
92
+ xfree(param->init_sol);
93
+ param->init_sol = NULL;
94
+ }
95
+ xfree(param);
96
+ param = NULL;
97
+ }
98
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef NUMO_LIBLINEAR_PARAMETER_H
2
+ #define NUMO_LIBLINEAR_PARAMETER_H 1
3
+
4
+ #include <linear.h>
5
+ #include <ruby.h>
6
+ #include <numo/narray.h>
7
+ #include <numo/template.h>
8
+
9
+ #include "converter.h"
10
+
11
+ struct parameter* rb_hash_to_parameter(VALUE parm_hash);
12
+ VALUE parameter_to_rb_hash(struct parameter* const param);
13
+ void xfree_parameter(struct parameter* param);
14
+
15
+ #endif /* NUMO_LIBLINEAR_PARAMETER_H */
@@ -0,0 +1,61 @@
1
+ #include "problem.h"
2
+
3
+ void xfree_problem(struct problem* problem)
4
+ {
5
+ int i;
6
+ if (problem) {
7
+ if (problem->x) {
8
+ for (i = 0; i < problem->l; i++) {
9
+ if (problem->x[i]) {
10
+ xfree(problem->x[i]);
11
+ problem->x[i] = NULL;
12
+ }
13
+ }
14
+ xfree(problem->x);
15
+ problem->x = NULL;
16
+ }
17
+ if (problem->y) {
18
+ xfree(problem->y);
19
+ problem->y = NULL;
20
+ }
21
+ xfree(problem);
22
+ problem = NULL;
23
+ }
24
+ }
25
+
26
+ struct problem* dataset_to_problem(VALUE x_val, VALUE y_val)
27
+ {
28
+ struct problem* problem;
29
+ narray_t* x_nary;
30
+ double* x_pt;
31
+ double* y_pt;
32
+ int i, j;
33
+ int n_samples;
34
+ int n_features;
35
+
36
+ GetNArray(x_val, x_nary);
37
+ n_samples = (int)NA_SHAPE(x_nary)[0];
38
+ n_features = (int)NA_SHAPE(x_nary)[1];
39
+ x_pt = (double*)na_get_pointer_for_read(x_val);
40
+ y_pt = (double*)na_get_pointer_for_read(y_val);
41
+
42
+ problem = ALLOC(struct problem);
43
+ problem->bias = -1;
44
+ problem->n = n_features;
45
+ problem->l = n_samples;
46
+ problem->x = ALLOC_N(struct feature_node*, n_samples);
47
+ problem->y = ALLOC_N(double, n_samples);
48
+
49
+ for (i = 0; i < n_samples; i++) {
50
+ problem->x[i] = ALLOC_N(struct feature_node, n_features + 1);
51
+ 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];
54
+ }
55
+ problem->x[i][n_features].index = -1;
56
+ problem->x[i][n_features].value = 0.0;
57
+ problem->y[i] = y_pt[i];
58
+ }
59
+
60
+ return problem;
61
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef NUMO_LIBLINEAR_PROBLEM_H
2
+ #define NUMO_LIBLINEAR_PROBLEM_H 1
3
+
4
+ #include <linear.h>
5
+ #include <ruby.h>
6
+ #include <numo/narray.h>
7
+ #include <numo/template.h>
8
+
9
+ void xfree_problem(struct problem* problem);
10
+ struct problem* dataset_to_problem(VALUE x_val, VALUE y_val);
11
+
12
+ #endif /* NUMO_LIBLINEAR_PROBLEM_H */
@@ -0,0 +1,34 @@
1
+ #include "solver_type.h"
2
+
3
+ RUBY_EXTERN VALUE mLiblinear;
4
+
5
+ void rb_init_solver_type_module()
6
+ {
7
+ /**
8
+ * Document-module: Numo::Liblinear::SolverType
9
+ * The module consisting of constants for solver type that used for parameter of LIBLINER.
10
+ */
11
+ VALUE mSolverType = rb_define_module_under(mLiblinear, "SolverType");
12
+ /* L2-regularized logistic regression (primal) */
13
+ rb_define_const(mSolverType, "L2R_LR", INT2NUM(L2R_LR));
14
+ /* L2-regularized L2-loss support vector classification (dual) */
15
+ rb_define_const(mSolverType, "L2R_L2LOSS_SVC_DUAL", INT2NUM(L2R_L2LOSS_SVC_DUAL));
16
+ /* L2-regularized L2-loss support vector classification (primal) */
17
+ rb_define_const(mSolverType, "L2R_L2LOSS_SVC", INT2NUM(L2R_L2LOSS_SVC));
18
+ /* L2-regularized L1-loss support vector classification (dual) */
19
+ rb_define_const(mSolverType, "L2R_L1LOSS_SVC_DUAL", INT2NUM(L2R_L1LOSS_SVC_DUAL));
20
+ /* support vector classification by Crammer and Singer */
21
+ rb_define_const(mSolverType, "MCSVM_CS", INT2NUM(MCSVM_CS));
22
+ /* L1-regularized L2-loss support vector classification */
23
+ rb_define_const(mSolverType, "L1R_L2LOSS_SVC", INT2NUM(L1R_L2LOSS_SVC));
24
+ /* L1-regularized logistic regression */
25
+ rb_define_const(mSolverType, "L1R_LR", INT2NUM(L1R_LR));
26
+ /* L2-regularized logistic regression (dual) */
27
+ rb_define_const(mSolverType, "L2R_LR_DUAL", INT2NUM(L2R_LR_DUAL));
28
+ /* L2-regularized L2-loss support vector regression (primal) */
29
+ rb_define_const(mSolverType, "L2R_L2LOSS_SVR", INT2NUM(L2R_L2LOSS_SVR));
30
+ /* L2-regularized L2-loss support vector regression (dual) */
31
+ rb_define_const(mSolverType, "L2R_L2LOSS_SVR_DUAL", INT2NUM(L2R_L2LOSS_SVR_DUAL));
32
+ /* L2-regularized L1-loss support vector regression (dual) */
33
+ rb_define_const(mSolverType, "L2R_L1LOSS_SVR_DUAL", INT2NUM(L2R_L1LOSS_SVR_DUAL));
34
+ }
@@ -0,0 +1,9 @@
1
+ #ifndef NUMO_LIBLINEAR_SOLVER_TYPE_H
2
+ #define NUMO_LIBLINEAR_SOLVER_TYPE_H 1
3
+
4
+ #include <linear.h>
5
+ #include <ruby.h>
6
+
7
+ void rb_init_solver_type_module();
8
+
9
+ #endif /* NUMO_LIBLINEAR_SOLVER_TYPE_H */
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'numo/narray'
4
+ require 'numo/liblinear/version'
5
+ require 'numo/liblinear/liblinearext'
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Numo
4
+ module Liblinear
5
+ # The version of Numo::Liblienar you are using.
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'numo/liblinear/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'numo-liblinear'
9
+ spec.version = Numo::Liblinear::VERSION
10
+ spec.authors = ['yoshoku']
11
+ spec.email = ['yoshoku@outlook.com']
12
+
13
+ spec.summary = <<~MSG
14
+ Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library.
15
+ Numo::Liblinear makes to use the LIBLINEAR functions with dataset represented by Numo::NArray.
16
+ MSG
17
+ spec.description = <<~MSG
18
+ Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library.
19
+ LIBLINEAR is one of the famous libraries for large-scale regularized linear classification and regression.
20
+ Numo::Liblinear makes to use the LIBLINEAR functions with dataset represented by Numo::NArray.
21
+ MSG
22
+ spec.homepage = 'https://github.com/yoshoku/numo-liblinear'
23
+ spec.license = 'BSD-3-Clause'
24
+
25
+ # Specify which files should be added to the gem when it is released.
26
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
28
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ end
30
+ spec.bindir = 'exe'
31
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
+ spec.require_paths = ['lib']
33
+ spec.extensions = ['ext/numo/liblinear/extconf.rb']
34
+
35
+ spec.add_runtime_dependency 'numo-narray', '~> 0.9.1'
36
+ spec.add_development_dependency 'bundler', '~> 2.0'
37
+ spec.add_development_dependency 'rake', '~> 10.0'
38
+ spec.add_development_dependency 'rake-compiler', '~> 1.0'
39
+ spec.add_development_dependency 'rspec', '~> 3.0'
40
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: numo-liblinear
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - yoshoku
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-07-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: numo-narray
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.9.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.9.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake-compiler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ description: |
84
+ Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library.
85
+ LIBLINEAR is one of the famous libraries for large-scale regularized linear classification and regression.
86
+ Numo::Liblinear makes to use the LIBLINEAR functions with dataset represented by Numo::NArray.
87
+ email:
88
+ - yoshoku@outlook.com
89
+ executables: []
90
+ extensions:
91
+ - ext/numo/liblinear/extconf.rb
92
+ extra_rdoc_files: []
93
+ files:
94
+ - ".gitignore"
95
+ - ".rspec"
96
+ - ".travis.yml"
97
+ - CHANGELOG.md
98
+ - CODE_OF_CONDUCT.md
99
+ - Gemfile
100
+ - LICENSE.txt
101
+ - README.md
102
+ - Rakefile
103
+ - ext/numo/liblinear/converter.c
104
+ - ext/numo/liblinear/converter.h
105
+ - ext/numo/liblinear/extconf.rb
106
+ - ext/numo/liblinear/liblinearext.c
107
+ - ext/numo/liblinear/liblinearext.h
108
+ - ext/numo/liblinear/model.c
109
+ - ext/numo/liblinear/model.h
110
+ - ext/numo/liblinear/parameter.c
111
+ - ext/numo/liblinear/parameter.h
112
+ - ext/numo/liblinear/problem.c
113
+ - ext/numo/liblinear/problem.h
114
+ - ext/numo/liblinear/solver_type.c
115
+ - ext/numo/liblinear/solver_type.h
116
+ - lib/numo/liblinear.rb
117
+ - lib/numo/liblinear/version.rb
118
+ - numo-liblinear.gemspec
119
+ homepage: https://github.com/yoshoku/numo-liblinear
120
+ licenses:
121
+ - BSD-3-Clause
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.6.14.4
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Numo::Liblinear is a Ruby gem binding to the LIBLINEAR library. Numo::Liblinear
143
+ makes to use the LIBLINEAR functions with dataset represented by Numo::NArray.
144
+ test_files: []