liblinear-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +46 -0
- data/Rakefile +1 -0
- data/ext/Makefile +237 -0
- data/ext/blas.h +25 -0
- data/ext/blasp.h +430 -0
- data/ext/daxpy.c +49 -0
- data/ext/ddot.c +50 -0
- data/ext/dnrm2.c +62 -0
- data/ext/dscal.c +44 -0
- data/ext/extconf.rb +12 -0
- data/ext/liblinear_wrap.cxx +4646 -0
- data/ext/linear.cpp +2811 -0
- data/ext/linear.h +74 -0
- data/ext/linear.rb +357 -0
- data/ext/tron.cpp +235 -0
- data/ext/tron.h +34 -0
- data/lib/liblinear.rb +89 -0
- data/lib/liblinear/error.rb +4 -0
- data/lib/liblinear/model.rb +66 -0
- data/lib/liblinear/parameter.rb +42 -0
- data/lib/liblinear/problem.rb +55 -0
- data/lib/liblinear/version.rb +3 -0
- data/liblinear-1.93/COPYRIGHT +31 -0
- data/liblinear-1.93/Makefile +37 -0
- data/liblinear-1.93/Makefile.win +30 -0
- data/liblinear-1.93/README +531 -0
- data/liblinear-1.93/blas/Makefile +22 -0
- data/liblinear-1.93/blas/blas.a +0 -0
- data/liblinear-1.93/blas/blas.h +25 -0
- data/liblinear-1.93/blas/blasp.h +430 -0
- data/liblinear-1.93/blas/daxpy.c +49 -0
- data/liblinear-1.93/blas/daxpy.o +0 -0
- data/liblinear-1.93/blas/ddot.c +50 -0
- data/liblinear-1.93/blas/ddot.o +0 -0
- data/liblinear-1.93/blas/dnrm2.c +62 -0
- data/liblinear-1.93/blas/dnrm2.o +0 -0
- data/liblinear-1.93/blas/dscal.c +44 -0
- data/liblinear-1.93/blas/dscal.o +0 -0
- data/liblinear-1.93/heart_scale +270 -0
- data/liblinear-1.93/linear.cpp +2811 -0
- data/liblinear-1.93/linear.def +18 -0
- data/liblinear-1.93/linear.h +74 -0
- data/liblinear-1.93/linear.o +0 -0
- data/liblinear-1.93/matlab/Makefile +58 -0
- data/liblinear-1.93/matlab/README +197 -0
- data/liblinear-1.93/matlab/libsvmread.c +212 -0
- data/liblinear-1.93/matlab/libsvmwrite.c +106 -0
- data/liblinear-1.93/matlab/linear_model_matlab.c +176 -0
- data/liblinear-1.93/matlab/linear_model_matlab.h +2 -0
- data/liblinear-1.93/matlab/make.m +21 -0
- data/liblinear-1.93/matlab/predict.c +331 -0
- data/liblinear-1.93/matlab/train.c +418 -0
- data/liblinear-1.93/predict +0 -0
- data/liblinear-1.93/predict.c +245 -0
- data/liblinear-1.93/python/Makefile +4 -0
- data/liblinear-1.93/python/README +343 -0
- data/liblinear-1.93/python/liblinear.py +277 -0
- data/liblinear-1.93/python/liblinearutil.py +250 -0
- data/liblinear-1.93/ruby/liblinear.i +41 -0
- data/liblinear-1.93/ruby/liblinear_wrap.cxx +4646 -0
- data/liblinear-1.93/ruby/linear.h +74 -0
- data/liblinear-1.93/ruby/linear.o +0 -0
- data/liblinear-1.93/train +0 -0
- data/liblinear-1.93/train.c +399 -0
- data/liblinear-1.93/tron.cpp +235 -0
- data/liblinear-1.93/tron.h +34 -0
- data/liblinear-1.93/tron.o +0 -0
- data/liblinear-1.93/windows/liblinear.dll +0 -0
- data/liblinear-1.93/windows/libsvmread.mexw64 +0 -0
- data/liblinear-1.93/windows/libsvmwrite.mexw64 +0 -0
- data/liblinear-1.93/windows/predict.exe +0 -0
- data/liblinear-1.93/windows/predict.mexw64 +0 -0
- data/liblinear-1.93/windows/train.exe +0 -0
- data/liblinear-1.93/windows/train.mexw64 +0 -0
- data/liblinear-ruby.gemspec +24 -0
- 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,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,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
|
+
|