liblinear-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +46 -0
  6. data/Rakefile +1 -0
  7. data/ext/Makefile +237 -0
  8. data/ext/blas.h +25 -0
  9. data/ext/blasp.h +430 -0
  10. data/ext/daxpy.c +49 -0
  11. data/ext/ddot.c +50 -0
  12. data/ext/dnrm2.c +62 -0
  13. data/ext/dscal.c +44 -0
  14. data/ext/extconf.rb +12 -0
  15. data/ext/liblinear_wrap.cxx +4646 -0
  16. data/ext/linear.cpp +2811 -0
  17. data/ext/linear.h +74 -0
  18. data/ext/linear.rb +357 -0
  19. data/ext/tron.cpp +235 -0
  20. data/ext/tron.h +34 -0
  21. data/lib/liblinear.rb +89 -0
  22. data/lib/liblinear/error.rb +4 -0
  23. data/lib/liblinear/model.rb +66 -0
  24. data/lib/liblinear/parameter.rb +42 -0
  25. data/lib/liblinear/problem.rb +55 -0
  26. data/lib/liblinear/version.rb +3 -0
  27. data/liblinear-1.93/COPYRIGHT +31 -0
  28. data/liblinear-1.93/Makefile +37 -0
  29. data/liblinear-1.93/Makefile.win +30 -0
  30. data/liblinear-1.93/README +531 -0
  31. data/liblinear-1.93/blas/Makefile +22 -0
  32. data/liblinear-1.93/blas/blas.a +0 -0
  33. data/liblinear-1.93/blas/blas.h +25 -0
  34. data/liblinear-1.93/blas/blasp.h +430 -0
  35. data/liblinear-1.93/blas/daxpy.c +49 -0
  36. data/liblinear-1.93/blas/daxpy.o +0 -0
  37. data/liblinear-1.93/blas/ddot.c +50 -0
  38. data/liblinear-1.93/blas/ddot.o +0 -0
  39. data/liblinear-1.93/blas/dnrm2.c +62 -0
  40. data/liblinear-1.93/blas/dnrm2.o +0 -0
  41. data/liblinear-1.93/blas/dscal.c +44 -0
  42. data/liblinear-1.93/blas/dscal.o +0 -0
  43. data/liblinear-1.93/heart_scale +270 -0
  44. data/liblinear-1.93/linear.cpp +2811 -0
  45. data/liblinear-1.93/linear.def +18 -0
  46. data/liblinear-1.93/linear.h +74 -0
  47. data/liblinear-1.93/linear.o +0 -0
  48. data/liblinear-1.93/matlab/Makefile +58 -0
  49. data/liblinear-1.93/matlab/README +197 -0
  50. data/liblinear-1.93/matlab/libsvmread.c +212 -0
  51. data/liblinear-1.93/matlab/libsvmwrite.c +106 -0
  52. data/liblinear-1.93/matlab/linear_model_matlab.c +176 -0
  53. data/liblinear-1.93/matlab/linear_model_matlab.h +2 -0
  54. data/liblinear-1.93/matlab/make.m +21 -0
  55. data/liblinear-1.93/matlab/predict.c +331 -0
  56. data/liblinear-1.93/matlab/train.c +418 -0
  57. data/liblinear-1.93/predict +0 -0
  58. data/liblinear-1.93/predict.c +245 -0
  59. data/liblinear-1.93/python/Makefile +4 -0
  60. data/liblinear-1.93/python/README +343 -0
  61. data/liblinear-1.93/python/liblinear.py +277 -0
  62. data/liblinear-1.93/python/liblinearutil.py +250 -0
  63. data/liblinear-1.93/ruby/liblinear.i +41 -0
  64. data/liblinear-1.93/ruby/liblinear_wrap.cxx +4646 -0
  65. data/liblinear-1.93/ruby/linear.h +74 -0
  66. data/liblinear-1.93/ruby/linear.o +0 -0
  67. data/liblinear-1.93/train +0 -0
  68. data/liblinear-1.93/train.c +399 -0
  69. data/liblinear-1.93/tron.cpp +235 -0
  70. data/liblinear-1.93/tron.h +34 -0
  71. data/liblinear-1.93/tron.o +0 -0
  72. data/liblinear-1.93/windows/liblinear.dll +0 -0
  73. data/liblinear-1.93/windows/libsvmread.mexw64 +0 -0
  74. data/liblinear-1.93/windows/libsvmwrite.mexw64 +0 -0
  75. data/liblinear-1.93/windows/predict.exe +0 -0
  76. data/liblinear-1.93/windows/predict.mexw64 +0 -0
  77. data/liblinear-1.93/windows/train.exe +0 -0
  78. data/liblinear-1.93/windows/train.mexw64 +0 -0
  79. data/liblinear-ruby.gemspec +24 -0
  80. metadata +152 -0
data/ext/tron.h ADDED
@@ -0,0 +1,34 @@
1
+ #ifndef _TRON_H
2
+ #define _TRON_H
3
+
4
+ class function
5
+ {
6
+ public:
7
+ virtual double fun(double *w) = 0 ;
8
+ virtual void grad(double *w, double *g) = 0 ;
9
+ virtual void Hv(double *s, double *Hs) = 0 ;
10
+
11
+ virtual int get_nr_variable(void) = 0 ;
12
+ virtual ~function(void){}
13
+ };
14
+
15
+ class TRON
16
+ {
17
+ public:
18
+ TRON(const function *fun_obj, double eps = 0.1, int max_iter = 1000);
19
+ ~TRON();
20
+
21
+ void tron(double *w);
22
+ void set_print_string(void (*i_print) (const char *buf));
23
+
24
+ private:
25
+ int trcg(double delta, double *g, double *s, double *r);
26
+ double norm_inf(int n, double *x);
27
+
28
+ double eps;
29
+ int max_iter;
30
+ function *fun_obj;
31
+ void info(const char *fmt,...);
32
+ void (*tron_print_string)(const char *buf);
33
+ };
34
+ #endif
data/lib/liblinear.rb ADDED
@@ -0,0 +1,89 @@
1
+ $: << File.expand_path(File.join(__FILE__, '..', '..', 'ext'))
2
+
3
+ require 'liblinearswig'
4
+ require 'liblinear/error'
5
+ require 'liblinear/model'
6
+ require 'liblinear/parameter'
7
+ require 'liblinear/problem'
8
+ require 'liblinear/version'
9
+
10
+ module Liblinear
11
+ #include Liblinearswig
12
+ # @param ruby_array [Array<Integer>]
13
+ # @return [SWIG::TYPE_p_int]
14
+ def new_int_array(ruby_array)
15
+ c_int_array = Liblinearswig.new_int(ruby_array.size)
16
+ ruby_array.size.times do |index|
17
+ Liblinearswig.int_setitem(c_int_array, index, ruby_array[index])
18
+ end
19
+ c_int_array
20
+ end
21
+
22
+ # @param c_array [SWIG::TYPE_p_int]
23
+ def free_int_array(c_array)
24
+ delete_int(c_array) unless c_array.nil?
25
+ end
26
+
27
+ # @param ruby_array [Array<Double>]
28
+ # @return [SWIG::TYPE_p_double]
29
+ def new_double_array(ruby_array)
30
+ c_double_array = Liblinearswig.new_double(ruby_array.size)
31
+ ruby_array.size.times do |index|
32
+ Liblinearswig.double_setitem(c_double_array, index, ruby_array[index])
33
+ end
34
+ c_double_array
35
+ end
36
+
37
+ # @param c_array [SWIG::TYPE_p_double]
38
+ def free_double_array(c_array)
39
+ delete_double(c_array) unless c_array.nil?
40
+ end
41
+
42
+ # @param c_array [SWIG::TYPE_p_int]
43
+ # @param size [Integer]
44
+ def int_array_c_to_ruby(c_array, size)
45
+ size.times.map {|index| int_getitem(c_array, index)}
46
+ end
47
+
48
+ # @param c_array [SWIG::TYPE_p_double]
49
+ # @param size [Integer]
50
+ def double_array_c_to_ruby(c_array, size)
51
+ size.times.map {|index| double_getitem(c_array, index)}
52
+ end
53
+
54
+ # @param example [Hash, Array]
55
+ # @param max_value_index [Integer]
56
+ # @param bias [Double]
57
+ # @return [Liblinearswig::Feature_node]
58
+ def convert_to_feature_node_array(example, max_value_index, bias = -1)
59
+ example_indexes = []
60
+ if example.is_a?(Hash)
61
+ example.each_key do |key|
62
+ example_indexes << key
63
+ end
64
+ elsif example.is_a?(Array)
65
+ example.each_index do |index|
66
+ example_indexes << index
67
+ end
68
+ else
69
+ raise TypeError, 'data must be a Hash or an Array'
70
+ end
71
+ example_indexes.sort!
72
+
73
+ if bias >= 0
74
+ feature_nodes = Liblinearswig.feature_node_array(example_indexes.size + 2)
75
+ Liblinearswig.feature_node_array_set(feature_nodes, example_indexes.size, max_value_index + 1, bias)
76
+ Liblinearswig.feature_node_array_set(feature_nodes, example_indexes.size + 1, -1, 0)
77
+ else
78
+ feature_nodes = Liblinearswig.feature_node_array(example_indexes.size + 1)
79
+ Liblinearswig.feature_node_array_set(feature_nodes, example_indexes.size, -1, 0)
80
+ end
81
+
82
+ f_index = 0
83
+ example_indexes.each do |e_index|
84
+ Liblinearswig.feature_node_array_set(feature_nodes, f_index, e_index, example[e_index])
85
+ f_index += 1
86
+ end
87
+ feature_nodes
88
+ end
89
+ end
@@ -0,0 +1,4 @@
1
+ module Liblinear
2
+ class InvalidParameter < StandardError
3
+ end
4
+ end
@@ -0,0 +1,66 @@
1
+ module Liblinear
2
+ class Model
3
+ include Liblinear
4
+ include Liblinearswig
5
+ attr_accessor :model
6
+
7
+ # @param arg_1 [LibLinear::Problem, String]
8
+ # @param arg_2 [Liblinear::Parameter]
9
+ def initialize(arg_1, arg_2 = nil)
10
+ if arg_2
11
+ unless arg_1.is_a?(Liblinear::Problem) && arg_2.is_a?(Liblinear::Parameter)
12
+ raise ArgumentError, 'arguments must be Liblinear::Problem and Liblinear::Parameter'
13
+ end
14
+ error_msg = check_parameter(arg_1.prob, arg_2.params)
15
+ raise InvalidParameter, error_msg if error_msg
16
+ @model = train(arg_1.prob, arg_2.params)
17
+ else
18
+ raise ArgumentError, 'argument must be String' unless arg_1.is_a?(String)
19
+ @model = load_model(arg_1)
20
+ end
21
+ end
22
+
23
+ # return [Integer]
24
+ def nr_class
25
+ get_nr_class(@model)
26
+ end
27
+
28
+ # return [Array<Integer>]
29
+ def labels
30
+ c_int_array = new_int(nr_class)
31
+ get_labels(@model, c_int_array)
32
+ labels = int_array_c_to_ruby(c_int_array, nr_class)
33
+ delete_int(c_int_array)
34
+ labels
35
+ end
36
+
37
+ # @param example [Array, Hash]
38
+ def predict(example)
39
+ feature_nodes = convert_to_feature_node_array(example, @model.nr_feature, @model.bias)
40
+ prediction = Liblinearswig.predict(@model, feature_nodes)
41
+ feature_node_array_destroy(feature_nodes)
42
+ prediction
43
+ end
44
+
45
+ # @param example [Array, Hash]
46
+ # @return [Hash]
47
+ def predict_probability(example)
48
+ feature_nodes = convert_to_feature_node_array(example, @model.nr_feature, @model.bias)
49
+ c_double_array = new_double_array(nr_class)
50
+ Liblinearswig.predict_probability(@model, feature_nodes, c_double_array)
51
+ probabilities = double_array_c_to_ruby(c_double_array, nr_class)
52
+ delete_double(c_double_array)
53
+ feature_node_array_destroy(feature_nodes)
54
+ probability_list = {}
55
+ labels.size.times do |i|
56
+ probability_list[labels[i]] = probabilities[i]
57
+ end
58
+ probability_list
59
+ end
60
+
61
+ # @param filename [String]
62
+ def save(filename)
63
+ save_model(filename, @model)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,42 @@
1
+ module Liblinear
2
+ class Parameter
3
+ include Liblinear
4
+ include Liblinearswig
5
+ attr_accessor :params
6
+
7
+ # @param params [Hash]
8
+ def initialize(params = {})
9
+ @params = Liblinearswig::Parameter.new
10
+ self.solver_type = 1
11
+ self.C = 1
12
+ self.eps = 0.1
13
+ self.p = 0.1
14
+ self.nr_weight = 0
15
+ self.weight_label = []
16
+ self.weight = []
17
+ params.each do |k, v|
18
+ self.send("#{k}=", v)
19
+ end
20
+ end
21
+
22
+ # @params weigt_label [Array<Integer>]
23
+ def weight_label=(weight_label)
24
+ free_int_array(@params.weight_label)
25
+ @params.weight_label = new_int_array(weight_label)
26
+ end
27
+
28
+ # @params weight [Array<Double>]
29
+ def weight=(weight)
30
+ free_double_array(@params.weight)
31
+ @params.weight = new_double_array(weight)
32
+ end
33
+
34
+ def method_missing(m, *args)
35
+ if m.to_s.index('=')
36
+ @params.send(m.to_sym, args.first)
37
+ else
38
+ @params.send(m.to_sym)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,55 @@
1
+ module Liblinear
2
+ class Problem
3
+ include Liblinear
4
+ include Liblinearswig
5
+ attr_accessor :prob
6
+
7
+ # @param labels [Array<Double>]
8
+ # @param examples [Array<Double>, Array<Hash>]
9
+ # @param bias [Double]
10
+ def initialize(labels, examples, bias)
11
+ unless labels.size == examples.size
12
+ raise ArgumentError, 'labels and examples must be same size'
13
+ end
14
+ @prob = Liblinearswig::Problem.new
15
+ @c_label = new_double_array(labels)
16
+ @examples = examples
17
+ @bias = bias
18
+ @max_example_index = max_example_index
19
+ @example_matrix = feature_node_matrix(examples.size)
20
+ @c_example_array = []
21
+
22
+ set_example_matrix
23
+
24
+ @prob.tap do |p|
25
+ p.y = @c_label
26
+ p.x = @example_matrix
27
+ p.bias = bias
28
+ p.l = examples.size
29
+ p.n = @max_example_index
30
+ p.n += 1 if bias >= 0
31
+ end
32
+ end
33
+
34
+ # @return [Integer]
35
+ def max_example_index
36
+ max_example_index = 0
37
+ @examples.each do |example|
38
+ if example.is_a?(Hash)
39
+ max_example_index = [max_example_index, example.keys.max].max if example.size > 0
40
+ else
41
+ max_example_index = [max_example_index, example.size].max
42
+ end
43
+ end
44
+ max_example_index
45
+ end
46
+
47
+ def set_example_matrix
48
+ @examples.size.times do |index|
49
+ c_example = convert_to_feature_node_array(@examples[index], @max_example_index, @bias)
50
+ @c_example_array << c_example
51
+ feature_node_matrix_set(@example_matrix, index, c_example)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,3 @@
1
+ module Liblinear
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,31 @@
1
+
2
+ Copyright (c) 2007-2013 The LIBLINEAR Project.
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions
7
+ are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright
13
+ notice, this list of conditions and the following disclaimer in the
14
+ documentation and/or other materials provided with the distribution.
15
+
16
+ 3. Neither name of copyright holders nor the names of its contributors
17
+ may be used to endorse or promote products derived from this software
18
+ without specific prior written permission.
19
+
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
25
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,37 @@
1
+ CXX ?= g++
2
+ CC ?= gcc
3
+ CFLAGS = -Wall -Wconversion -O3 -fPIC
4
+ LIBS = blas/blas.a
5
+ SHVER = 1
6
+ OS = $(shell uname)
7
+ #LIBS = -lblas
8
+
9
+ all: train predict
10
+
11
+ lib: linear.o tron.o blas/blas.a
12
+ if [ "$(OS)" = "Darwin" ]; then \
13
+ SHARED_LIB_FLAG="-dynamiclib -Wl,-install_name,liblinear.so.$(SHVER)"; \
14
+ else \
15
+ SHARED_LIB_FLAG="-shared -Wl,-soname,liblinear.so.$(SHVER)"; \
16
+ fi; \
17
+ $(CXX) $${SHARED_LIB_FLAG} linear.o tron.o blas/blas.a -o liblinear.so.$(SHVER)
18
+
19
+ train: tron.o linear.o train.c blas/blas.a
20
+ $(CXX) $(CFLAGS) -o train train.c tron.o linear.o $(LIBS)
21
+
22
+ predict: tron.o linear.o predict.c blas/blas.a
23
+ $(CXX) $(CFLAGS) -o predict predict.c tron.o linear.o $(LIBS)
24
+
25
+ tron.o: tron.cpp tron.h
26
+ $(CXX) $(CFLAGS) -c -o tron.o tron.cpp
27
+
28
+ linear.o: linear.cpp linear.h
29
+ $(CXX) $(CFLAGS) -c -o linear.o linear.cpp
30
+
31
+ blas/blas.a: blas/*.c blas/*.h
32
+ make -C blas OPTFLAGS='$(CFLAGS)' CC='$(CC)';
33
+
34
+ clean:
35
+ make -C blas clean
36
+ make -C matlab clean
37
+ rm -f *~ tron.o linear.o train predict liblinear.so.$(SHVER)
@@ -0,0 +1,30 @@
1
+ #You must ensure nmake.exe, cl.exe, link.exe are in system path.
2
+ #VCVARS32.bat
3
+ #Under dosbox prompt
4
+ #nmake -f Makefile.win
5
+
6
+ ##########################################
7
+ CXX = cl.exe
8
+ CFLAGS = -nologo -O2 -EHsc -I. -D __WIN32__ -D _CRT_SECURE_NO_DEPRECATE
9
+ TARGET = windows
10
+
11
+ all: $(TARGET)\train.exe $(TARGET)\predict.exe
12
+
13
+ $(TARGET)\train.exe: tron.obj linear.obj train.c blas\*.c
14
+ $(CXX) $(CFLAGS) -Fe$(TARGET)\train.exe tron.obj linear.obj train.c blas\*.c
15
+
16
+ $(TARGET)\predict.exe: tron.obj linear.obj predict.c blas\*.c
17
+ $(CXX) $(CFLAGS) -Fe$(TARGET)\predict.exe tron.obj linear.obj predict.c blas\*.c
18
+
19
+ linear.obj: linear.cpp linear.h
20
+ $(CXX) $(CFLAGS) -c linear.cpp
21
+
22
+ tron.obj: tron.cpp tron.h
23
+ $(CXX) $(CFLAGS) -c tron.cpp
24
+
25
+ lib: linear.cpp linear.h linear.def tron.obj
26
+ $(CXX) $(CFLAGS) -LD linear.cpp tron.obj blas\*.c -Fe$(TARGET)\liblinear -link -DEF:linear.def
27
+
28
+ clean:
29
+ -erase /Q *.obj $(TARGET)\.
30
+
@@ -0,0 +1,531 @@
1
+ LIBLINEAR is a simple package for solving large-scale regularized linear
2
+ classification and regression. It currently supports
3
+ - L2-regularized logistic regression/L2-loss support vector classification/L1-loss support vector classification
4
+ - L1-regularized L2-loss support vector classification/L1-regularized logistic regression
5
+ - L2-regularized L2-loss support vector regression/L1-loss support vector regression.
6
+ This document explains the usage of LIBLINEAR.
7
+
8
+ To get started, please read the ``Quick Start'' section first.
9
+ For developers, please check the ``Library Usage'' section to learn
10
+ how to integrate LIBLINEAR in your software.
11
+
12
+ Table of Contents
13
+ =================
14
+
15
+ - When to use LIBLINEAR but not LIBSVM
16
+ - Quick Start
17
+ - Installation
18
+ - `train' Usage
19
+ - `predict' Usage
20
+ - Examples
21
+ - Library Usage
22
+ - Building Windows Binaries
23
+ - Additional Information
24
+ - MATLAB/OCTAVE interface
25
+ - PYTHON interface
26
+
27
+ When to use LIBLINEAR but not LIBSVM
28
+ ====================================
29
+
30
+ There are some large data for which with/without nonlinear mappings
31
+ gives similar performances. Without using kernels, one can
32
+ efficiently train a much larger set via linear classification/regression.
33
+ These data usually have a large number of features. Document classification
34
+ is an example.
35
+
36
+ Warning: While generally liblinear is very fast, its default solver
37
+ may be slow under certain situations (e.g., data not scaled or C is
38
+ large). See Appendix B of our SVM guide about how to handle such
39
+ cases.
40
+ http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
41
+
42
+ Warning: If you are a beginner and your data sets are not large, you
43
+ should consider LIBSVM first.
44
+
45
+ LIBSVM page:
46
+ http://www.csie.ntu.edu.tw/~cjlin/libsvm
47
+
48
+
49
+ Quick Start
50
+ ===========
51
+
52
+ See the section ``Installation'' for installing LIBLINEAR.
53
+
54
+ After installation, there are programs `train' and `predict' for
55
+ training and testing, respectively.
56
+
57
+ About the data format, please check the README file of LIBSVM. Note
58
+ that feature index must start from 1 (but not 0).
59
+
60
+ A sample classification data included in this package is `heart_scale'.
61
+
62
+ Type `train heart_scale', and the program will read the training
63
+ data and output the model file `heart_scale.model'. If you have a test
64
+ set called heart_scale.t, then type `predict heart_scale.t
65
+ heart_scale.model output' to see the prediction accuracy. The `output'
66
+ file contains the predicted class labels.
67
+
68
+ For more information about `train' and `predict', see the sections
69
+ `train' Usage and `predict' Usage.
70
+
71
+ To obtain good performances, sometimes one needs to scale the
72
+ data. Please check the program `svm-scale' of LIBSVM. For large and
73
+ sparse data, use `-l 0' to keep the sparsity.
74
+
75
+ Installation
76
+ ============
77
+
78
+ On Unix systems, type `make' to build the `train' and `predict'
79
+ programs. Run them without arguments to show the usages.
80
+
81
+ On other systems, consult `Makefile' to build them (e.g., see
82
+ 'Building Windows binaries' in this file) or use the pre-built
83
+ binaries (Windows binaries are in the directory `windows').
84
+
85
+ This software uses some level-1 BLAS subroutines. The needed functions are
86
+ included in this package. If a BLAS library is available on your
87
+ machine, you may use it by modifying the Makefile: Unmark the following line
88
+
89
+ #LIBS ?= -lblas
90
+
91
+ and mark
92
+
93
+ LIBS ?= blas/blas.a
94
+
95
+ `train' Usage
96
+ =============
97
+
98
+ Usage: train [options] training_set_file [model_file]
99
+ options:
100
+ -s type : set type of solver (default 1)
101
+ for multi-class classification
102
+ 0 -- L2-regularized logistic regression (primal)
103
+ 1 -- L2-regularized L2-loss support vector classification (dual)
104
+ 2 -- L2-regularized L2-loss support vector classification (primal)
105
+ 3 -- L2-regularized L1-loss support vector classification (dual)
106
+ 4 -- support vector classification by Crammer and Singer
107
+ 5 -- L1-regularized L2-loss support vector classification
108
+ 6 -- L1-regularized logistic regression
109
+ 7 -- L2-regularized logistic regression (dual)
110
+ for regression
111
+ 11 -- L2-regularized L2-loss support vector regression (primal)
112
+ 12 -- L2-regularized L2-loss support vector regression (dual)
113
+ 13 -- L2-regularized L1-loss support vector regression (dual)
114
+ -c cost : set the parameter C (default 1)
115
+ -p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
116
+ -e epsilon : set tolerance of termination criterion
117
+ -s 0 and 2
118
+ |f'(w)|_2 <= eps*min(pos,neg)/l*|f'(w0)|_2,
119
+ where f is the primal function and pos/neg are # of
120
+ positive/negative data (default 0.01)
121
+ -s 11
122
+ |f'(w)|_2 <= eps*|f'(w0)|_2 (default 0.001)
123
+ -s 1, 3, 4 and 7
124
+ Dual maximal violation <= eps; similar to libsvm (default 0.1)
125
+ -s 5 and 6
126
+ |f'(w)|_inf <= eps*min(pos,neg)/l*|f'(w0)|_inf,
127
+ where f is the primal function (default 0.01)
128
+ -s 12 and 13\n"
129
+ |f'(alpha)|_1 <= eps |f'(alpha0)|,
130
+ where f is the dual function (default 0.1)
131
+ -B bias : if bias >= 0, instance x becomes [x; bias]; if < 0, no bias term added (default -1)
132
+ -wi weight: weights adjust the parameter C of different classes (see README for details)
133
+ -v n: n-fold cross validation mode
134
+ -q : quiet mode (no outputs)
135
+
136
+ Option -v randomly splits the data into n parts and calculates cross
137
+ validation accuracy on them.
138
+
139
+ Formulations:
140
+
141
+ For L2-regularized logistic regression (-s 0), we solve
142
+
143
+ min_w w^Tw/2 + C \sum log(1 + exp(-y_i w^Tx_i))
144
+
145
+ For L2-regularized L2-loss SVC dual (-s 1), we solve
146
+
147
+ min_alpha 0.5(alpha^T (Q + I/2/C) alpha) - e^T alpha
148
+ s.t. 0 <= alpha_i,
149
+
150
+ For L2-regularized L2-loss SVC (-s 2), we solve
151
+
152
+ min_w w^Tw/2 + C \sum max(0, 1- y_i w^Tx_i)^2
153
+
154
+ For L2-regularized L1-loss SVC dual (-s 3), we solve
155
+
156
+ min_alpha 0.5(alpha^T Q alpha) - e^T alpha
157
+ s.t. 0 <= alpha_i <= C,
158
+
159
+ For L1-regularized L2-loss SVC (-s 5), we solve
160
+
161
+ min_w \sum |w_j| + C \sum max(0, 1- y_i w^Tx_i)^2
162
+
163
+ For L1-regularized logistic regression (-s 6), we solve
164
+
165
+ min_w \sum |w_j| + C \sum log(1 + exp(-y_i w^Tx_i))
166
+
167
+ For L2-regularized logistic regression (-s 7), we solve
168
+
169
+ min_alpha 0.5(alpha^T Q alpha) + \sum alpha_i*log(alpha_i) + \sum (C-alpha_i)*log(C-alpha_i) - a constant
170
+ s.t. 0 <= alpha_i <= C,
171
+
172
+ where
173
+
174
+ Q is a matrix with Q_ij = y_i y_j x_i^T x_j.
175
+
176
+ For L2-regularized L2-loss SVR (-s 11), we solve
177
+
178
+ min_w w^Tw/2 + C \sum max(0, |y_i-w^Tx_i|-epsilon)^2
179
+
180
+ For L2-regularized L2-loss SVR dual (-s 12), we solve
181
+
182
+ min_beta 0.5(beta^T (Q + lambda I/2/C) beta) - y^T beta + \sum |beta_i|
183
+
184
+ For L2-regularized L1-loss SVR dual (-s 13), we solve
185
+
186
+ min_beta 0.5(beta^T Q beta) - y^T beta + \sum |beta_i|
187
+ s.t. -C <= beta_i <= C,
188
+
189
+ where
190
+
191
+ Q is a matrix with Q_ij = x_i^T x_j.
192
+
193
+ If bias >= 0, w becomes [w; w_{n+1}] and x becomes [x; bias].
194
+
195
+ The primal-dual relationship implies that -s 1 and -s 2 give the same
196
+ model, -s 0 and -s 7 give the same, and -s 11 and -s 12 give the same.
197
+
198
+ We implement 1-vs-the rest multi-class strategy for classification.
199
+ In training i vs. non_i, their C parameters are (weight from -wi)*C
200
+ and C, respectively. If there are only two classes, we train only one
201
+ model. Thus weight1*C vs. weight2*C is used. See examples below.
202
+
203
+ We also implement multi-class SVM by Crammer and Singer (-s 4):
204
+
205
+ min_{w_m, \xi_i} 0.5 \sum_m ||w_m||^2 + C \sum_i \xi_i
206
+ s.t. w^T_{y_i} x_i - w^T_m x_i >= \e^m_i - \xi_i \forall m,i
207
+
208
+ where e^m_i = 0 if y_i = m,
209
+ e^m_i = 1 if y_i != m,
210
+
211
+ Here we solve the dual problem:
212
+
213
+ min_{\alpha} 0.5 \sum_m ||w_m(\alpha)||^2 + \sum_i \sum_m e^m_i alpha^m_i
214
+ s.t. \alpha^m_i <= C^m_i \forall m,i , \sum_m \alpha^m_i=0 \forall i
215
+
216
+ where w_m(\alpha) = \sum_i \alpha^m_i x_i,
217
+ and C^m_i = C if m = y_i,
218
+ C^m_i = 0 if m != y_i.
219
+
220
+ `predict' Usage
221
+ ===============
222
+
223
+ Usage: predict [options] test_file model_file output_file
224
+ options:
225
+ -b probability_estimates: whether to output probability estimates, 0 or 1 (default 0); currently for logistic regression only
226
+ -q : quiet mode (no outputs)
227
+
228
+ Note that -b is only needed in the prediction phase. This is different
229
+ from the setting of LIBSVM.
230
+
231
+ Examples
232
+ ========
233
+
234
+ > train data_file
235
+
236
+ Train linear SVM with L2-loss function.
237
+
238
+ > train -s 0 data_file
239
+
240
+ Train a logistic regression model.
241
+
242
+ > train -v 5 -e 0.001 data_file
243
+
244
+ Do five-fold cross-validation using L2-loss svm.
245
+ Use a smaller stopping tolerance 0.001 than the default
246
+ 0.1 if you want more accurate solutions.
247
+
248
+ > train -c 10 -w1 2 -w2 5 -w3 2 four_class_data_file
249
+
250
+ Train four classifiers:
251
+ positive negative Cp Cn
252
+ class 1 class 2,3,4. 20 10
253
+ class 2 class 1,3,4. 50 10
254
+ class 3 class 1,2,4. 20 10
255
+ class 4 class 1,2,3. 10 10
256
+
257
+ > train -c 10 -w3 1 -w2 5 two_class_data_file
258
+
259
+ If there are only two classes, we train ONE model.
260
+ The C values for the two classes are 10 and 50.
261
+
262
+ > predict -b 1 test_file data_file.model output_file
263
+
264
+ Output probability estimates (for logistic regression only).
265
+
266
+ Library Usage
267
+ =============
268
+
269
+ - Function: model* train(const struct problem *prob,
270
+ const struct parameter *param);
271
+
272
+ This function constructs and returns a linear classification
273
+ or regression model according to the given training data and
274
+ parameters.
275
+
276
+ struct problem describes the problem:
277
+
278
+ struct problem
279
+ {
280
+ int l, n;
281
+ int *y;
282
+ struct feature_node **x;
283
+ double bias;
284
+ };
285
+
286
+ where `l' is the number of training data. If bias >= 0, we assume
287
+ that one additional feature is added to the end of each data
288
+ instance. `n' is the number of feature (including the bias feature
289
+ if bias >= 0). `y' is an array containing the target values. (integers
290
+ in classification, real numbers in regression) And `x' is an array
291
+ of pointers, each of which points to a sparse representation (array
292
+ of feature_node) of one training vector.
293
+
294
+ For example, if we have the following training data:
295
+
296
+ LABEL ATTR1 ATTR2 ATTR3 ATTR4 ATTR5
297
+ ----- ----- ----- ----- ----- -----
298
+ 1 0 0.1 0.2 0 0
299
+ 2 0 0.1 0.3 -1.2 0
300
+ 1 0.4 0 0 0 0
301
+ 2 0 0.1 0 1.4 0.5
302
+ 3 -0.1 -0.2 0.1 1.1 0.1
303
+
304
+ and bias = 1, then the components of problem are:
305
+
306
+ l = 5
307
+ n = 6
308
+
309
+ y -> 1 2 1 2 3
310
+
311
+ x -> [ ] -> (2,0.1) (3,0.2) (6,1) (-1,?)
312
+ [ ] -> (2,0.1) (3,0.3) (4,-1.2) (6,1) (-1,?)
313
+ [ ] -> (1,0.4) (6,1) (-1,?)
314
+ [ ] -> (2,0.1) (4,1.4) (5,0.5) (6,1) (-1,?)
315
+ [ ] -> (1,-0.1) (2,-0.2) (3,0.1) (4,1.1) (5,0.1) (6,1) (-1,?)
316
+
317
+ struct parameter describes the parameters of a linear classification
318
+ or regression model:
319
+
320
+ struct parameter
321
+ {
322
+ int solver_type;
323
+
324
+ /* these are for training only */
325
+ double eps; /* stopping criteria */
326
+ double C;
327
+ int nr_weight;
328
+ int *weight_label;
329
+ double* weight;
330
+ double p;
331
+ };
332
+
333
+ solver_type can be one of L2R_LR, L2R_L2LOSS_SVC_DUAL, L2R_L2LOSS_SVC, L2R_L1LOSS_SVC_DUAL, MCSVM_CS, L1R_L2LOSS_SVC, L1R_LR, L2R_LR_DUAL, L2R_L2LOSS_SVR, L2R_L2LOSS_SVR_DUAL, L2R_L1LOSS_SVR_DUAL.
334
+ for classification
335
+ L2R_LR L2-regularized logistic regression (primal)
336
+ L2R_L2LOSS_SVC_DUAL L2-regularized L2-loss support vector classification (dual)
337
+ L2R_L2LOSS_SVC L2-regularized L2-loss support vector classification (primal)
338
+ L2R_L1LOSS_SVC_DUAL L2-regularized L1-loss support vector classification (dual)
339
+ MCSVM_CS support vector classification by Crammer and Singer
340
+ L1R_L2LOSS_SVC L1-regularized L2-loss support vector classification
341
+ L1R_LR L1-regularized logistic regression
342
+ L2R_LR_DUAL L2-regularized logistic regression (dual)
343
+ for regression
344
+ L2R_L2LOSS_SVR L2-regularized L2-loss support vector regression (primal)
345
+ L2R_L2LOSS_SVR_DUAL L2-regularized L2-loss support vector regression (dual)
346
+ L2R_L1LOSS_SVR_DUAL L2-regularized L1-loss support vector regression (dual)
347
+
348
+ C is the cost of constraints violation.
349
+ p is the sensitiveness of loss of support vector regression.
350
+ eps is the stopping criterion.
351
+
352
+ nr_weight, weight_label, and weight are used to change the penalty
353
+ for some classes (If the weight for a class is not changed, it is
354
+ set to 1). This is useful for training classifier using unbalanced
355
+ input data or with asymmetric misclassification cost.
356
+
357
+ nr_weight is the number of elements in the array weight_label and
358
+ weight. Each weight[i] corresponds to weight_label[i], meaning that
359
+ the penalty of class weight_label[i] is scaled by a factor of weight[i].
360
+
361
+ If you do not want to change penalty for any of the classes,
362
+ just set nr_weight to 0.
363
+
364
+ *NOTE* To avoid wrong parameters, check_parameter() should be
365
+ called before train().
366
+
367
+ struct model stores the model obtained from the training procedure:
368
+
369
+ struct model
370
+ {
371
+ struct parameter param;
372
+ int nr_class; /* number of classes */
373
+ int nr_feature;
374
+ double *w;
375
+ int *label; /* label of each class */
376
+ double bias;
377
+ };
378
+
379
+ param describes the parameters used to obtain the model.
380
+
381
+ nr_class and nr_feature are the number of classes and features,
382
+ respectively. nr_class = 2 for regression.
383
+
384
+ The nr_feature*nr_class array w gives feature weights. We use one
385
+ against the rest for multi-class classification, so each feature
386
+ index corresponds to nr_class weight values. Weights are
387
+ organized in the following way
388
+
389
+ +------------------+------------------+------------+
390
+ | nr_class weights | nr_class weights | ...
391
+ | for 1st feature | for 2nd feature |
392
+ +------------------+------------------+------------+
393
+
394
+ If bias >= 0, x becomes [x; bias]. The number of features is
395
+ increased by one, so w is a (nr_feature+1)*nr_class array. The
396
+ value of bias is stored in the variable bias.
397
+
398
+ The array label stores class labels.
399
+
400
+ - Function: void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target);
401
+
402
+ This function conducts cross validation. Data are separated to
403
+ nr_fold folds. Under given parameters, sequentially each fold is
404
+ validated using the model from training the remaining. Predicted
405
+ labels in the validation process are stored in the array called
406
+ target.
407
+
408
+ The format of prob is same as that for train().
409
+
410
+ - Function: double predict(const model *model_, const feature_node *x);
411
+
412
+ For a classification model, the predicted class for x is returned.
413
+ For a regression model, the function value of x calculated using
414
+ the model is returned.
415
+
416
+ - Function: double predict_values(const struct model *model_,
417
+ const struct feature_node *x, double* dec_values);
418
+
419
+ This function gives nr_w decision values in the array dec_values.
420
+ nr_w=1 if regression is applied or the number of classes is two. An exception is
421
+ multi-class svm by Crammer and Singer (-s 4), where nr_w = 2 if there are two classes. For all other situations, nr_w is the
422
+ number of classes.
423
+
424
+ We implement one-vs-the rest multi-class strategy (-s 0,1,2,3,5,6,7)
425
+ and multi-class svm by Crammer and Singer (-s 4) for multi-class SVM.
426
+ The class with the highest decision value is returned.
427
+
428
+ - Function: double predict_probability(const struct model *model_,
429
+ const struct feature_node *x, double* prob_estimates);
430
+
431
+ This function gives nr_class probability estimates in the array
432
+ prob_estimates. nr_class can be obtained from the function
433
+ get_nr_class. The class with the highest probability is
434
+ returned. Currently, we support only the probability outputs of
435
+ logistic regression.
436
+
437
+ - Function: int get_nr_feature(const model *model_);
438
+
439
+ The function gives the number of attributes of the model.
440
+
441
+ - Function: int get_nr_class(const model *model_);
442
+
443
+ The function gives the number of classes of the model.
444
+ For a regression model, 2 is returned.
445
+
446
+ - Function: void get_labels(const model *model_, int* label);
447
+
448
+ This function outputs the name of labels into an array called label.
449
+ For a regression model, label is unchanged.
450
+
451
+ - Function: const char *check_parameter(const struct problem *prob,
452
+ const struct parameter *param);
453
+
454
+ This function checks whether the parameters are within the feasible
455
+ range of the problem. This function should be called before calling
456
+ train() and cross_validation(). It returns NULL if the
457
+ parameters are feasible, otherwise an error message is returned.
458
+
459
+ - Function: int save_model(const char *model_file_name,
460
+ const struct model *model_);
461
+
462
+ This function saves a model to a file; returns 0 on success, or -1
463
+ if an error occurs.
464
+
465
+ - Function: struct model *load_model(const char *model_file_name);
466
+
467
+ This function returns a pointer to the model read from the file,
468
+ or a null pointer if the model could not be loaded.
469
+
470
+ - Function: void free_model_content(struct model *model_ptr);
471
+
472
+ This function frees the memory used by the entries in a model structure.
473
+
474
+ - Function: void free_and_destroy_model(struct model **model_ptr_ptr);
475
+
476
+ This function frees the memory used by a model and destroys the model
477
+ structure.
478
+
479
+ - Function: void destroy_param(struct parameter *param);
480
+
481
+ This function frees the memory used by a parameter set.
482
+
483
+ - Function: void set_print_string_function(void (*print_func)(const char *));
484
+
485
+ Users can specify their output format by a function. Use
486
+ set_print_string_function(NULL);
487
+ for default printing to stdout.
488
+
489
+ Building Windows Binaries
490
+ =========================
491
+
492
+ Windows binaries are in the directory `windows'. To build them via
493
+ Visual C++, use the following steps:
494
+
495
+ 1. Open a dos command box and change to liblinear directory. If
496
+ environment variables of VC++ have not been set, type
497
+
498
+ "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
499
+
500
+ You may have to modify the above command according which version of
501
+ VC++ or where it is installed.
502
+
503
+ 2. Type
504
+
505
+ nmake -f Makefile.win clean all
506
+
507
+
508
+ MATLAB/OCTAVE Interface
509
+ =======================
510
+
511
+ Please check the file README in the directory `matlab'.
512
+
513
+ PYTHON Interface
514
+ ================
515
+
516
+ Please check the file README in the directory `python'.
517
+
518
+ Additional Information
519
+ ======================
520
+
521
+ If you find LIBLINEAR helpful, please cite it as
522
+
523
+ R.-E. Fan, K.-W. Chang, C.-J. Hsieh, X.-R. Wang, and C.-J. Lin.
524
+ LIBLINEAR: A Library for Large Linear Classification, Journal of
525
+ Machine Learning Research 9(2008), 1871-1874. Software available at
526
+ http://www.csie.ntu.edu.tw/~cjlin/liblinear
527
+
528
+ For any questions and comments, please send your email to
529
+ cjlin@csie.ntu.edu.tw
530
+
531
+