numo-liblinear 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7db70ba7431ce52aa9530d3d340a6dce5a616daa
4
+ data.tar.gz: ce1a99b9082477922ed35768de8467b514d36541
5
+ SHA512:
6
+ metadata.gz: 79e9cbacea54a665ddb971da7b08fd3a43d159a0314715d0aecbf5c19b3b3c95adca6f8b29217c354348d9d8417b9c14742a8d1a5f2debd2db51dd92c32007d5
7
+ data.tar.gz: 96a37fde1a15d9a79d7c2bbf374691e8358b42afadf1df58ac1097a6af1bc52ebcd5e6b43601e5ec15582fc79e9b430c20bc39b42503083c0991066b34d9bbbc
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /bin/
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
14
+
15
+ *.swp
16
+ *.bundle
17
+ mkmf.log
18
+ tags
19
+ .DS_Store
20
+ .ruby-version
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ ---
2
+ sudo: true
3
+ os: linux
4
+ dist: bionic
5
+ language: ruby
6
+ cache: bundler
7
+ rvm:
8
+ - '2.4'
9
+ - '2.5'
10
+ - '2.6'
11
+
12
+ before_install:
13
+ - sudo apt-get install -y liblinear-dev
14
+ - gem install bundler -v 2.0.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ # 0.1.0
2
+ - First release.
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at yoshoku@outlook.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in numo-liblinear.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,27 @@
1
+ Copyright (c) 2019 Atsushi Tatsuma
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ * Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # Numo::Liblinear
2
+
3
+ [![Build Status](https://travis-ci.org/yoshoku/numo-liblinear.svg?branch=master)](https://travis-ci.org/yoshoku/numo-liblinear)
4
+ [![BSD 3-Clause License](https://img.shields.io/badge/License-BSD%203--Clause-orange.svg)](https://github.com/yoshoku/numo-liblinear/blob/master/LICENSE.txt)
5
+
6
+ Numo::Liblinear is a Ruby gem binding to the [LIBLINEAR](https://www.csie.ntu.edu.tw/~cjlin/liblinear/) library.
7
+ LIBLINEAR is one of the famous libraries for large-scale regularized linear classification and regression.
8
+ Numo::Liblinear makes to use the LIBLINEAR functions with
9
+ dataset represented by [Numo::NArray](https://github.com/ruby-numo/numo-narray).
10
+
11
+ Note: There are other useful Ruby gems binding to LIBLINEAR:
12
+ [liblinear-ruby](https://github.com/kei500/liblinear-ruby) by Kei Tsuchiya and
13
+ [liblinear-ruby-swig](https://github.com/tomz/liblinear-ruby-swig) by Tom Zeng.
14
+
15
+ ## Installation
16
+ Numo::Liblinear does not bundle LIBLINEAR. You need to install LIBLINEAR in advance along your environment.
17
+
18
+ macOS:
19
+
20
+ $ brew install liblinear
21
+
22
+ Ubuntu:
23
+
24
+ $ sudo apt-get install liblinear-dev
25
+
26
+ Add this line to your application's Gemfile:
27
+
28
+ ```ruby
29
+ gem 'numo-liblinear'
30
+ ```
31
+
32
+ And then execute:
33
+
34
+ $ bundle
35
+
36
+ Or install it yourself as:
37
+
38
+ $ gem install numo-liblinear
39
+
40
+ ## Usage
41
+
42
+ ### Preparation
43
+
44
+ In the following examples, we use [red-datasets](https://github.com/red-data-tools/red-datasets) to download dataset.
45
+
46
+ $ gem install red-datasets-numo-narray
47
+
48
+ ### Example 1. Cross-validation
49
+
50
+ We conduct cross validation of the Support Vector Classifier on [Iris dataset](https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html#iris).
51
+
52
+ ```ruby
53
+ require 'numo/narray'
54
+ require 'numo/liblinear'
55
+ require 'datasets-numo-narray'
56
+
57
+ # Download Iris dataset.
58
+ puts 'Download dataset.'
59
+ iris = Datasets::LIBSVM.new('iris').to_narray
60
+ x = iris[true, 1..-1]
61
+ y = iris[true, 0]
62
+
63
+ # Define parameters of L2-regularized L2-loss support vector classification.
64
+ param = {
65
+ solver_type: Numo::Liblinear::SolverType::L2R_L2LOSS_SVC_DUAL,
66
+ C: 1
67
+ }
68
+
69
+ # Perform 5-cross validation.
70
+ puts 'Perform cross validation.'
71
+ n_folds = 5
72
+ predicted = Numo::Liblinear::cv(x, y, param, n_folds)
73
+
74
+ # Print mean accuracy.
75
+ mean_accuracy = y.eq(predicted).count.fdiv(y.size)
76
+ puts "Accuracy: %.1f %%" % (100 * mean_accuracy)
77
+ ```
78
+
79
+ Execution result in the following:
80
+
81
+ ```sh
82
+ Download dataset.
83
+ Perform cross validation.
84
+ Accuracy: 87.3 %
85
+ ```
86
+
87
+ ### Example 2. Pendigits dataset classification
88
+
89
+ We first train the Logistic Regression using training [pendigits dataset](https://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html#pendigits).
90
+
91
+ ```ruby
92
+ require 'numo/liblinear'
93
+ require 'datasets-numo-narray'
94
+
95
+ # Download pendigits training dataset.
96
+ puts 'Download dataset.'
97
+ pendigits = Datasets::LIBSVM.new('pendigits').to_narray
98
+ x = pendigits[true, 1..-1]
99
+ y = pendigits[true, 0]
100
+
101
+ # Define parameters of L2-regularized logistic regression.
102
+ param = {
103
+ solver_type: Numo::Liblinear::SolverType::L2R_LR_DUAL,
104
+ C: 1
105
+ }
106
+
107
+ # Perform training procedure.
108
+ puts 'Train logistic regression.'
109
+ model = Numo::Liblinear.train(x, y, param)
110
+
111
+ # Save parameters and trained model.
112
+ puts 'Save parameters and model with Marshal'
113
+ File.open('pendigits.dat', 'wb') { |f| f.write(Marshal.dump([param, model])) }
114
+ ```
115
+
116
+ ```sh
117
+ Download dataset.
118
+ Train logistic regression.
119
+ Save parameters and model with Marshal
120
+ ```
121
+
122
+ We then predict labels of testing dataset, and evaluate the classifier.
123
+
124
+ ```ruby
125
+ require 'numo/liblinear'
126
+ require 'datasets-numo-narray'
127
+
128
+ # Download pendigits testing dataset.
129
+ puts 'Download dataset.'
130
+ pendigits_test = Datasets::LIBSVM.new('pendigits', note: 'testing').to_narray
131
+ x = pendigits_test[true, 1..-1]
132
+ y = pendigits_test[true, 0]
133
+
134
+ # Load parameter and model.
135
+ puts 'Load parameter and model.'
136
+ param, model = Marshal.load(File.binread('pendigits.dat'))
137
+
138
+ # Predict labels.
139
+ puts 'Predict labels.'
140
+ predicted = Numo::Liblinear.predict(x, param, model)
141
+
142
+ # Evaluate classification results.
143
+ mean_accuracy = y.eq(predicted).count.fdiv(y.size)
144
+ puts "Accuracy: %.1f %%" % (100 * mean_accuracy)
145
+ ```
146
+
147
+ ```sh
148
+ Download dataset.
149
+ Load parameter and model.
150
+ Predict labels.
151
+ Accuracy: 87.9 %
152
+ ```
153
+
154
+ ## Development
155
+
156
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
157
+
158
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
159
+
160
+ ## Contributing
161
+
162
+ Bug reports and pull requests are welcome on GitHub at https://github.com/yoshoku/numo-liblinear.
163
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
164
+
165
+ ## Code of Conduct
166
+
167
+ Everyone interacting in the Numo::Liblinear project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow
168
+ the [code of conduct](https://github.com/yoshoku/numo-liblinear/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ require 'rake/extensiontask'
7
+
8
+ task :build => :compile
9
+
10
+ Rake::ExtensionTask.new('liblinearext') do |ext|
11
+ ext.ext_dir = 'ext/numo/liblinear'
12
+ ext.lib_dir = 'lib/numo/liblinear'
13
+ end
14
+
15
+ task :default => [:clobber, :compile, :spec]
@@ -0,0 +1,102 @@
1
+ #include "converter.h"
2
+
3
+ VALUE int_vec_to_nary(int* const arr, int const size)
4
+ {
5
+ int i;
6
+ size_t shape[1] = { size };
7
+ VALUE v = rb_narray_new(numo_cInt32, 1, shape);
8
+ int32_t* vp = (int32_t*)na_get_pointer_for_write(v);
9
+ for (i = 0; i < size; i++) { vp[i] = (int32_t)arr[i]; }
10
+ return v;
11
+ }
12
+
13
+ int* nary_to_int_vec(VALUE vec_val)
14
+ {
15
+ int i;
16
+ int n_elements;
17
+ narray_t* vec_nary;
18
+ int32_t* vec_pt;
19
+ int* vec;
20
+
21
+ if (vec_val == Qnil) return NULL;
22
+
23
+ GetNArray(vec_val, vec_nary);
24
+ n_elements = (int)NA_SHAPE(vec_nary)[0];
25
+
26
+ vec = ALLOC_N(int, n_elements);
27
+ vec_pt = (int32_t*)na_get_pointer_for_read(vec_val);
28
+ for (i = 0; i < n_elements; i++) { vec[i] = (int)vec_pt[i]; }
29
+
30
+ return vec;
31
+ }
32
+
33
+ VALUE dbl_vec_to_nary(double* const arr, int const size)
34
+ {
35
+ int i;
36
+ size_t shape[1] = { size };
37
+ VALUE v = rb_narray_new(numo_cDFloat, 1, shape);
38
+ double* vp = (double*)na_get_pointer_for_write(v);
39
+ for (i = 0; i < size; i++) { vp[i] = arr[i]; }
40
+ return v;
41
+ }
42
+
43
+ double* nary_to_dbl_vec(VALUE vec_val)
44
+ {
45
+ int n_elements;
46
+ narray_t* vec_nary;
47
+ double* vec_pt;
48
+ double* vec;
49
+
50
+ if (vec_val == Qnil) return NULL;
51
+
52
+ GetNArray(vec_val, vec_nary);
53
+ n_elements = (int)NA_SHAPE(vec_nary)[0];
54
+
55
+ vec = ALLOC_N(double, n_elements);
56
+ vec_pt = (double*)na_get_pointer_for_read(vec_val);
57
+ memcpy(vec, vec_pt, n_elements * sizeof(double));
58
+
59
+ return vec;
60
+ }
61
+
62
+ VALUE dbl_mat_to_nary(double** const mat, int const n_rows, int const n_cols)
63
+ {
64
+ int i, j;
65
+ size_t shape[2] = { n_rows, n_cols };
66
+ VALUE v = rb_narray_new(numo_cDFloat, 2, shape);
67
+ double* vp = (double*)na_get_pointer_for_write(v);
68
+
69
+ for (i = 0; i < n_rows; i++) {
70
+ for (j = 0; j < n_cols; j++) {
71
+ vp[i * n_cols + j] = mat[i][j];
72
+ }
73
+ }
74
+
75
+ return v;
76
+ }
77
+
78
+ double** nary_to_dbl_mat(VALUE mat_val)
79
+ {
80
+ int i, j;
81
+ int n_rows, n_cols;
82
+ narray_t* mat_nary;
83
+ double* mat_pt;
84
+ double** mat;
85
+
86
+ if (mat_val == Qnil) return NULL;
87
+
88
+ GetNArray(mat_val, mat_nary);
89
+ n_rows = (int)NA_SHAPE(mat_nary)[0];
90
+ n_cols = (int)NA_SHAPE(mat_nary)[1];
91
+
92
+ mat_pt = (double*)na_get_pointer_for_read(mat_val);
93
+ mat = ALLOC_N(double*, n_rows);
94
+ for (i = 0; i < n_rows; i++) {
95
+ mat[i] = ALLOC_N(double, n_cols);
96
+ for (j = 0; j < n_cols; j++) {
97
+ mat[i][j] = mat_pt[i * n_cols + j];
98
+ }
99
+ }
100
+
101
+ return mat;
102
+ }