liblinear-ruby 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +141 -10
- data/{liblinear-1.93/ruby → ext}/liblinear.i +0 -0
- data/ext/linear.cpp +30 -7
- data/ext/tron.cpp +4 -4
- data/lib/liblinear/model.rb +3 -3
- data/lib/liblinear/parameter.rb +2 -2
- data/lib/liblinear/problem.rb +4 -17
- data/lib/liblinear/version.rb +1 -1
- data/lib/liblinear.rb +46 -13
- data/{liblinear-1.93 → liblinear-1.94}/COPYRIGHT +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/Makefile +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/Makefile.win +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/README +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/Makefile +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/blas.h +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/blasp.h +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/daxpy.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/ddot.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/dnrm2.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/blas/dscal.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/heart_scale +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/linear.cpp +30 -7
- data/{liblinear-1.93 → liblinear-1.94}/linear.def +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/linear.h +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/matlab/Makefile +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/matlab/README +2 -1
- data/{liblinear-1.93 → liblinear-1.94}/matlab/libsvmread.c +25 -24
- data/{liblinear-1.93 → liblinear-1.94}/matlab/libsvmwrite.c +15 -1
- data/{liblinear-1.93 → liblinear-1.94}/matlab/linear_model_matlab.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/matlab/linear_model_matlab.h +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/matlab/make.m +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/matlab/predict.c +37 -25
- data/{liblinear-1.93 → liblinear-1.94}/matlab/train.c +16 -7
- data/{liblinear-1.93 → liblinear-1.94}/predict.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/python/Makefile +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/python/README +1 -1
- data/{liblinear-1.93 → liblinear-1.94}/python/liblinear.py +1 -1
- data/{liblinear-1.93 → liblinear-1.94}/python/liblinearutil.py +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/train.c +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/tron.cpp +4 -4
- data/{liblinear-1.93 → liblinear-1.94}/tron.h +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/windows/liblinear.dll +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/windows/libsvmread.mexw64 +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/windows/libsvmwrite.mexw64 +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/windows/predict.exe +0 -0
- data/liblinear-1.94/windows/predict.mexw64 +0 -0
- data/{liblinear-1.93 → liblinear-1.94}/windows/train.exe +0 -0
- data/liblinear-1.94/windows/train.mexw64 +0 -0
- data/spec/liblinear/model_spec.rb +56 -0
- data/spec/liblinear/parameter_spec.rb +57 -0
- data/spec/liblinear/problem_spec.rb +23 -0
- data/spec/liblinear_spec.rb +104 -0
- metadata +51 -56
- data/ext/linear.rb +0 -357
- data/liblinear-1.93/blas/blas.a +0 -0
- data/liblinear-1.93/blas/daxpy.o +0 -0
- data/liblinear-1.93/blas/ddot.o +0 -0
- data/liblinear-1.93/blas/dnrm2.o +0 -0
- data/liblinear-1.93/blas/dscal.o +0 -0
- data/liblinear-1.93/linear.o +0 -0
- data/liblinear-1.93/predict +0 -0
- data/liblinear-1.93/ruby/liblinear_wrap.cxx +0 -4646
- data/liblinear-1.93/ruby/linear.h +0 -74
- data/liblinear-1.93/ruby/linear.o +0 -0
- data/liblinear-1.93/train +0 -0
- data/liblinear-1.93/tron.o +0 -0
- data/liblinear-1.93/windows/predict.mexw64 +0 -0
- data/liblinear-1.93/windows/train.mexw64 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5a7efbbe95e53288a0a4be6ae55411f693a16b65
|
4
|
+
data.tar.gz: c7882e4f98923ff2193b9eb797f918bf7a83295d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 333b9b43537b0b903761a7141b25dce9ef9af61cc04a9b985ad6988c63a9d53c46caa07ff8ed123a295a759ab7bd4dcfcbbf69ccabdaf7529d41f250eea37712
|
7
|
+
data.tar.gz: d94f42793a1b98e6bdf3f33fddded2934806be5e8a9e0913fb8c44a041b59a6c4d7afa4f3d84aa0985ac3b5f5811b61f48d2a01b65e066bb13d0e1c49e2b85b7
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Liblinear-Ruby
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/liblinear-ruby.png)](http://badge.fury.io/rb/liblinear-ruby)
|
2
3
|
|
3
|
-
Liblinear-Ruby is Ruby interface to LIBLINEAR
|
4
|
+
Liblinear-Ruby is Ruby interface to LIBLINEAR using SWIG.
|
5
|
+
Now, this interface is supporting LIBLINEAR 1.94.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -16,21 +18,150 @@ Or install it yourself as:
|
|
16
18
|
|
17
19
|
$ gem install liblinear-ruby
|
18
20
|
|
19
|
-
##
|
20
|
-
|
21
|
+
## Quick Start
|
22
|
+
This sample code execute classification with L2-regularized logistic regression.
|
21
23
|
```ruby
|
22
24
|
require 'liblinear'
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
|
26
|
+
# Setting parameters
|
27
|
+
param = Liblinear::Parameter.new
|
28
|
+
param.solver_type = Liblinear::L2R_LR
|
29
|
+
|
30
|
+
# Training phase
|
31
|
+
labels = [1, -1]
|
27
32
|
examples = [
|
28
33
|
{1=>0, 2=>0, 3=>0, 4=>0, 5=>0},
|
29
34
|
{1=>1, 2=>1, 3=>1, 4=>1, 5=>1}
|
30
35
|
]
|
31
|
-
|
32
|
-
|
33
|
-
|
36
|
+
bias = 0.5
|
37
|
+
prob = Liblinear::Problem.new(labels, examples, bias)
|
38
|
+
model = Liblinear::Model.new(prob, param)
|
39
|
+
|
40
|
+
# Predicting phase
|
41
|
+
puts model.predict({1=>1, 2=>1, 3=>1, 4=>1, 5=>1}) # => -1.0
|
42
|
+
```
|
43
|
+
## Usage
|
44
|
+
|
45
|
+
### Setting parameters
|
46
|
+
First, you have to make an instance of Liblinear::Parameter:
|
47
|
+
```ruby
|
48
|
+
param = Liblinear::Parameter.new
|
49
|
+
```
|
50
|
+
And then set the parameters as:
|
51
|
+
```ruby
|
52
|
+
param.[parameter_you_set] = value
|
53
|
+
```
|
54
|
+
Or you can set by Hash as:
|
55
|
+
```ruby
|
56
|
+
parameter = {
|
57
|
+
parameter_you_set: value,
|
58
|
+
...
|
59
|
+
}
|
60
|
+
param = Liblinear::Parameter.new(parameter)
|
61
|
+
```
|
62
|
+
|
63
|
+
#### Type of solver
|
64
|
+
This parameter is comparable to -s option on command line.
|
65
|
+
You can set as:
|
66
|
+
```ruby
|
67
|
+
param.solver_type = solver_type # default 1 (Liblinear::L2R_L2LOSS_SVC_DUAL)
|
68
|
+
```
|
69
|
+
Solver types you can set are shown below.
|
70
|
+
```ruby
|
71
|
+
# for multi-class classification
|
72
|
+
Liblinear::L2R_LR # L2-regularized logistic regression (primal)
|
73
|
+
Liblinear::L2R_L2LOSS_SVC_DUAL # L2-regularized L2-loss support vector classification (dual)
|
74
|
+
Liblinear::L2R_L2LOSS_SVC # L2-regularized L2-loss support vector classification (primal)
|
75
|
+
Liblinear::L2R_L1LOSS_SVC_DUAL # L2-regularized L1-loss support vector classification (dual)
|
76
|
+
Liblinear::MCSVM_CS # support vector classification by Crammer and Singer
|
77
|
+
Liblinear::L1R_L2LOSS_SVC # L1-regularized L2-loss support vector classification
|
78
|
+
Liblinear::L1R_LR # L1-regularized logistic regression
|
79
|
+
Liblinear::L2R_LR_DUAL # L2-regularized logistic regression (dual)
|
80
|
+
|
81
|
+
# for regression
|
82
|
+
Liblinear::L2R_L2LOSS_SVR # L2-regularized L2-loss support vector regression (primal)
|
83
|
+
Liblinear::L2R_L2LOSS_SVR_DUAL # L2-regularized L2-loss support vector regression (dual)
|
84
|
+
Liblinear::L2R_L1LOSS_SVR_DUAL # L2-regularized L1-loss support vector regression (dual)
|
85
|
+
```
|
86
|
+
|
87
|
+
#### C parameter
|
88
|
+
This parameter is comparable to -c option on command line.
|
89
|
+
You can set as:
|
90
|
+
```ruby
|
91
|
+
param.C = value # default 1
|
92
|
+
```
|
93
|
+
|
94
|
+
#### Epsilon in loss function of epsilon-SVR
|
95
|
+
This parameter is comparable to -p option on command line.
|
96
|
+
You can set as:
|
97
|
+
```ruby
|
98
|
+
param.p = value # default 0.1
|
99
|
+
```
|
100
|
+
|
101
|
+
#### Tolerance of termination criterion
|
102
|
+
This parameter is comparable to -e option on command line.
|
103
|
+
You can set as:
|
104
|
+
```ruby
|
105
|
+
param.eps = value # default 0.1
|
106
|
+
```
|
107
|
+
|
108
|
+
#### Weight
|
109
|
+
This parameter adjust the parameter C of different classes(see LIBLINEAR's README for details).
|
110
|
+
nr_weight is the number of elements in the array weight_label and weight.
|
111
|
+
You can set as:
|
112
|
+
```ruby
|
113
|
+
param.nr_weight = value # default 0
|
114
|
+
param.weight_label = [Array <Integer>] # default []
|
115
|
+
param.weight = [Array <Double>] # default []
|
116
|
+
```
|
117
|
+
|
118
|
+
### Training phase
|
119
|
+
You have to prepare training data.
|
120
|
+
The format of training data is shown below:
|
121
|
+
```ruby
|
122
|
+
# Labels mean class
|
123
|
+
label = [1, -1, ...]
|
124
|
+
|
125
|
+
# Training data have to be array of hash or array of array
|
126
|
+
# If you chose array of hash
|
127
|
+
examples = [
|
128
|
+
{1=>0, 2=>0, 3=>0, 4=>0, 5=>0},
|
129
|
+
{1=>1, 2=>1, 3=>1, 4=>1, 5=>1},
|
130
|
+
...
|
131
|
+
]
|
132
|
+
|
133
|
+
# If you chose array of array
|
134
|
+
examples = [
|
135
|
+
[0, 0, 0, 0, 0],
|
136
|
+
[1, 1, 1, 1, 1],
|
137
|
+
]
|
138
|
+
```
|
139
|
+
Next, set the bias (this is comparable to -B option on command line):
|
140
|
+
```ruby
|
141
|
+
bias = 0.5 # default -1
|
142
|
+
```
|
143
|
+
And then make an instance of Liblinear::Problem and Liblinear::Model:
|
144
|
+
```ruby
|
145
|
+
prob = Liblinear::Problem.new(labels, examples, bias)
|
146
|
+
model = Liblinear::Model.new(prob, param)
|
147
|
+
```
|
148
|
+
If you have already had a model file, you can load it as:
|
149
|
+
```ruby
|
150
|
+
prob = Liblinear::Problem.new(labels, examples, bias)
|
151
|
+
model = Liblinear::Model.new(model_file)
|
152
|
+
```
|
153
|
+
In this phase, you can save model as:
|
154
|
+
```ruby
|
155
|
+
model.save(file_name)
|
156
|
+
```
|
157
|
+
|
158
|
+
### Predicting phase
|
159
|
+
Input a data whose format is same as training data:
|
160
|
+
```ruby
|
161
|
+
# Hash
|
162
|
+
model.predict({1=>1, 2=>1, 3=>1, 4=>1, 5=>1})
|
163
|
+
# Array
|
164
|
+
model.predict([1, 1, 1, 1, 1])
|
34
165
|
```
|
35
166
|
|
36
167
|
## Contributing
|
File without changes
|
data/ext/linear.cpp
CHANGED
@@ -2051,8 +2051,8 @@ static void transpose(const problem *prob, feature_node **x_space_ret, problem *
|
|
2051
2051
|
int i;
|
2052
2052
|
int l = prob->l;
|
2053
2053
|
int n = prob->n;
|
2054
|
-
int nnz = 0;
|
2055
|
-
int *col_ptr = new int[n+1];
|
2054
|
+
long int nnz = 0;
|
2055
|
+
long int *col_ptr = new long int [n+1];
|
2056
2056
|
feature_node *x_space;
|
2057
2057
|
prob_col->l = l;
|
2058
2058
|
prob_col->n = n;
|
@@ -2140,6 +2140,24 @@ static void group_classes(const problem *prob, int *nr_class_ret, int **label_re
|
|
2140
2140
|
}
|
2141
2141
|
}
|
2142
2142
|
|
2143
|
+
//
|
2144
|
+
// Labels are ordered by their first occurrence in the training set.
|
2145
|
+
// However, for two-class sets with -1/+1 labels and -1 appears first,
|
2146
|
+
// we swap labels to ensure that internally the binary SVM has positive data corresponding to the +1 instances.
|
2147
|
+
//
|
2148
|
+
if (nr_class == 2 && label[0] == -1 && label[1] == 1)
|
2149
|
+
{
|
2150
|
+
swap(label[0],label[1]);
|
2151
|
+
swap(count[0],count[1]);
|
2152
|
+
for(i=0;i<l;i++)
|
2153
|
+
{
|
2154
|
+
if(data_label[i] == 0)
|
2155
|
+
data_label[i] = 1;
|
2156
|
+
else
|
2157
|
+
data_label[i] = 0;
|
2158
|
+
}
|
2159
|
+
}
|
2160
|
+
|
2143
2161
|
int *start = Malloc(int,nr_class);
|
2144
2162
|
start[0] = 0;
|
2145
2163
|
for(i=1;i<nr_class;i++)
|
@@ -2190,7 +2208,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2190
2208
|
tron_obj.set_print_string(liblinear_print_string);
|
2191
2209
|
tron_obj.tron(w);
|
2192
2210
|
delete fun_obj;
|
2193
|
-
delete C;
|
2211
|
+
delete[] C;
|
2194
2212
|
break;
|
2195
2213
|
}
|
2196
2214
|
case L2R_L2LOSS_SVC:
|
@@ -2208,7 +2226,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2208
2226
|
tron_obj.set_print_string(liblinear_print_string);
|
2209
2227
|
tron_obj.tron(w);
|
2210
2228
|
delete fun_obj;
|
2211
|
-
delete C;
|
2229
|
+
delete[] C;
|
2212
2230
|
break;
|
2213
2231
|
}
|
2214
2232
|
case L2R_L2LOSS_SVC_DUAL:
|
@@ -2253,7 +2271,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2253
2271
|
tron_obj.set_print_string(liblinear_print_string);
|
2254
2272
|
tron_obj.tron(w);
|
2255
2273
|
delete fun_obj;
|
2256
|
-
delete C;
|
2274
|
+
delete[] C;
|
2257
2275
|
break;
|
2258
2276
|
|
2259
2277
|
}
|
@@ -2409,10 +2427,15 @@ model* train(const problem *prob, const parameter *param)
|
|
2409
2427
|
void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target)
|
2410
2428
|
{
|
2411
2429
|
int i;
|
2412
|
-
int *fold_start
|
2430
|
+
int *fold_start;
|
2413
2431
|
int l = prob->l;
|
2414
2432
|
int *perm = Malloc(int,l);
|
2415
|
-
|
2433
|
+
if (nr_fold > l)
|
2434
|
+
{
|
2435
|
+
nr_fold = l;
|
2436
|
+
fprintf(stderr,"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
|
2437
|
+
}
|
2438
|
+
fold_start = Malloc(int,nr_fold+1);
|
2416
2439
|
for(i=0;i<l;i++) perm[i]=i;
|
2417
2440
|
for(i=0;i<l;i++)
|
2418
2441
|
{
|
data/ext/tron.cpp
CHANGED
@@ -74,7 +74,7 @@ void TRON::tron(double *w)
|
|
74
74
|
for (i=0; i<n; i++)
|
75
75
|
w[i] = 0;
|
76
76
|
|
77
|
-
|
77
|
+
f = fun_obj->fun(w);
|
78
78
|
fun_obj->grad(w, g);
|
79
79
|
delta = dnrm2_(&n, g, &inc);
|
80
80
|
double gnorm1 = delta;
|
@@ -94,10 +94,10 @@ void TRON::tron(double *w)
|
|
94
94
|
|
95
95
|
gs = ddot_(&n, g, &inc, s, &inc);
|
96
96
|
prered = -0.5*(gs-ddot_(&n, s, &inc, r, &inc));
|
97
|
-
|
97
|
+
fnew = fun_obj->fun(w_new);
|
98
98
|
|
99
99
|
// Compute the actual reduction.
|
100
|
-
|
100
|
+
actred = f - fnew;
|
101
101
|
|
102
102
|
// On the first iteration, adjust the initial step bound.
|
103
103
|
snorm = dnrm2_(&n, s, &inc);
|
@@ -127,7 +127,7 @@ void TRON::tron(double *w)
|
|
127
127
|
iter++;
|
128
128
|
memcpy(w, w_new, sizeof(double)*n);
|
129
129
|
f = fnew;
|
130
|
-
|
130
|
+
fun_obj->grad(w, g);
|
131
131
|
|
132
132
|
gnorm = dnrm2_(&n, g, &inc);
|
133
133
|
if (gnorm <= eps*gnorm1)
|
data/lib/liblinear/model.rb
CHANGED
@@ -11,13 +11,13 @@ module Liblinear
|
|
11
11
|
def initialize(arg_1, arg_2 = nil)
|
12
12
|
if arg_2
|
13
13
|
unless arg_1.is_a?(Liblinear::Problem) && arg_2.is_a?(Liblinear::Parameter)
|
14
|
-
raise ArgumentError, 'arguments must be Liblinear::Problem and Liblinear::Parameter'
|
14
|
+
raise ArgumentError, 'arguments must be [Liblinear::Problem] and [Liblinear::Parameter]'
|
15
15
|
end
|
16
16
|
error_msg = check_parameter(arg_1.prob, arg_2.params)
|
17
17
|
raise InvalidParameter, error_msg if error_msg
|
18
18
|
@model = train(arg_1.prob, arg_2.params)
|
19
19
|
else
|
20
|
-
raise ArgumentError, 'argument must be String' unless arg_1.is_a?(String)
|
20
|
+
raise ArgumentError, 'argument must be [String]' unless arg_1.is_a?(String)
|
21
21
|
@model = load_model(arg_1)
|
22
22
|
end
|
23
23
|
end
|
@@ -27,7 +27,7 @@ module Liblinear
|
|
27
27
|
get_nr_class(@model)
|
28
28
|
end
|
29
29
|
|
30
|
-
# @return [Array<Integer>]
|
30
|
+
# @return [Array <Integer>]
|
31
31
|
def labels
|
32
32
|
c_int_array = new_int(nr_class)
|
33
33
|
get_labels(@model, c_int_array)
|
data/lib/liblinear/parameter.rb
CHANGED
@@ -19,13 +19,13 @@ module Liblinear
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
# @params weigt_label [Array<Integer>]
|
22
|
+
# @params weigt_label [Array <Integer>]
|
23
23
|
def weight_label=(weight_label)
|
24
24
|
free_int_array(@params.weight_label)
|
25
25
|
@params.weight_label = new_int_array(weight_label)
|
26
26
|
end
|
27
27
|
|
28
|
-
# @params weight [Array<Double>]
|
28
|
+
# @params weight [Array <Double>]
|
29
29
|
def weight=(weight)
|
30
30
|
free_double_array(@params.weight)
|
31
31
|
@params.weight = new_double_array(weight)
|
data/lib/liblinear/problem.rb
CHANGED
@@ -4,11 +4,11 @@ module Liblinear
|
|
4
4
|
include Liblinearswig
|
5
5
|
attr_accessor :prob
|
6
6
|
|
7
|
-
# @param labels [Array<Double>]
|
8
|
-
# @param examples [Array<Double
|
7
|
+
# @param labels [Array <Double>]
|
8
|
+
# @param examples [Array <Double, Hash>]
|
9
9
|
# @param bias [Double]
|
10
10
|
# @raise [ArgumentError]
|
11
|
-
def initialize(labels, examples, bias)
|
11
|
+
def initialize(labels, examples, bias = -1)
|
12
12
|
unless labels.size == examples.size
|
13
13
|
raise ArgumentError, 'labels and examples must be same size'
|
14
14
|
end
|
@@ -16,7 +16,7 @@ module Liblinear
|
|
16
16
|
@c_label = new_double_array(labels)
|
17
17
|
@examples = examples
|
18
18
|
@bias = bias
|
19
|
-
@max_example_index =
|
19
|
+
@max_example_index = max_index(@examples)
|
20
20
|
@example_matrix = feature_node_matrix(examples.size)
|
21
21
|
@c_example_array = []
|
22
22
|
|
@@ -32,19 +32,6 @@ module Liblinear
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
# @return [Integer]
|
36
|
-
def max_example_index
|
37
|
-
max_example_index = 0
|
38
|
-
@examples.each do |example|
|
39
|
-
if example.is_a?(Hash)
|
40
|
-
max_example_index = [max_example_index, example.keys.max].max if example.size > 0
|
41
|
-
else
|
42
|
-
max_example_index = [max_example_index, example.size].max
|
43
|
-
end
|
44
|
-
end
|
45
|
-
max_example_index
|
46
|
-
end
|
47
|
-
|
48
35
|
def set_example_matrix
|
49
36
|
@examples.size.times do |index|
|
50
37
|
c_example = convert_to_feature_node_array(@examples[index], @max_example_index, @bias)
|
data/lib/liblinear/version.rb
CHANGED
data/lib/liblinear.rb
CHANGED
@@ -8,7 +8,19 @@ require 'liblinear/problem'
|
|
8
8
|
require 'liblinear/version'
|
9
9
|
|
10
10
|
module Liblinear
|
11
|
-
|
11
|
+
L2R_LR = Liblinearswig::L2R_LR
|
12
|
+
L2R_L2LOSS_SVC_DUAL = Liblinearswig::L2R_L2LOSS_SVC_DUAL
|
13
|
+
L2R_L2LOSS_SVC = Liblinearswig::L2R_L2LOSS_SVC
|
14
|
+
L2R_L1LOSS_SVC_DUAL = Liblinearswig::L2R_L1LOSS_SVC_DUAL
|
15
|
+
MCSVM_CS = Liblinearswig::MCSVM_CS
|
16
|
+
L1R_L2LOSS_SVC = Liblinearswig::L1R_L2LOSS_SVC
|
17
|
+
L1R_LR = Liblinearswig::L1R_LR
|
18
|
+
L2R_LR_DUAL = Liblinearswig::L2R_LR_DUAL
|
19
|
+
L2R_L2LOSS_SVR = Liblinearswig::L2R_L2LOSS_SVR
|
20
|
+
L2R_L2LOSS_SVR_DUAL = Liblinearswig::L2R_L2LOSS_SVR_DUAL
|
21
|
+
L2R_L1LOSS_SVR_DUAL = Liblinearswig::L2R_L1LOSS_SVR_DUAL
|
22
|
+
|
23
|
+
# @param ruby_array [Array <Integer>]
|
12
24
|
# @return [SWIG::TYPE_p_int]
|
13
25
|
def new_int_array(ruby_array)
|
14
26
|
c_int_array = Liblinearswig.new_int(ruby_array.size)
|
@@ -23,7 +35,7 @@ module Liblinear
|
|
23
35
|
delete_int(c_array) unless c_array.nil?
|
24
36
|
end
|
25
37
|
|
26
|
-
# @param ruby_array [Array<Double>]
|
38
|
+
# @param ruby_array [Array <Double>]
|
27
39
|
# @return [SWIG::TYPE_p_double]
|
28
40
|
def new_double_array(ruby_array)
|
29
41
|
c_double_array = Liblinearswig.new_double(ruby_array.size)
|
@@ -47,27 +59,48 @@ module Liblinear
|
|
47
59
|
|
48
60
|
# @param c_array [SWIG::TYPE_p_double]
|
49
61
|
# @param size [Integer]
|
50
|
-
# @return [Array<Double>]
|
62
|
+
# @return [Array <Double>]
|
51
63
|
def double_array_c_to_ruby(c_array, size)
|
52
64
|
size.times.map {|index| double_getitem(c_array, index)}
|
53
65
|
end
|
54
66
|
|
67
|
+
# @param examples [Array <Hash, Array>]
|
68
|
+
# @return [Integer]
|
69
|
+
def max_index(examples)
|
70
|
+
max_index = 0
|
71
|
+
examples.each do |example|
|
72
|
+
if example.is_a?(Hash)
|
73
|
+
max_index = [max_index, example.keys.max].max if example.size > 0
|
74
|
+
else
|
75
|
+
max_index = [max_index, example.size].max
|
76
|
+
end
|
77
|
+
end
|
78
|
+
max_index
|
79
|
+
end
|
80
|
+
|
81
|
+
# @param array [Array]
|
82
|
+
# @return [Hash]
|
83
|
+
def array_to_hash(array)
|
84
|
+
raise ArgumentError unless array.is_a?(Array)
|
85
|
+
hash = {}
|
86
|
+
key = 1
|
87
|
+
array.each do |value|
|
88
|
+
hash[key] = value
|
89
|
+
key += 1
|
90
|
+
end
|
91
|
+
hash
|
92
|
+
end
|
93
|
+
|
55
94
|
# @param example [Hash, Array]
|
56
95
|
# @param max_value_index [Integer]
|
57
96
|
# @param bias [Double]
|
58
97
|
# @return [Liblinearswig::Feature_node]
|
59
98
|
def convert_to_feature_node_array(example, max_value_index, bias = -1)
|
99
|
+
example = array_to_hash(example) if example.is_a?(Array)
|
100
|
+
|
60
101
|
example_indexes = []
|
61
|
-
|
62
|
-
|
63
|
-
example_indexes << key
|
64
|
-
end
|
65
|
-
elsif example.is_a?(Array)
|
66
|
-
example.each_index do |index|
|
67
|
-
example_indexes << index
|
68
|
-
end
|
69
|
-
else
|
70
|
-
raise TypeError, 'example must be a Hash or an Array'
|
102
|
+
example.each_key do |key|
|
103
|
+
example_indexes << key
|
71
104
|
end
|
72
105
|
example_indexes.sort!
|
73
106
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -2051,8 +2051,8 @@ static void transpose(const problem *prob, feature_node **x_space_ret, problem *
|
|
2051
2051
|
int i;
|
2052
2052
|
int l = prob->l;
|
2053
2053
|
int n = prob->n;
|
2054
|
-
int nnz = 0;
|
2055
|
-
int *col_ptr = new int[n+1];
|
2054
|
+
long int nnz = 0;
|
2055
|
+
long int *col_ptr = new long int [n+1];
|
2056
2056
|
feature_node *x_space;
|
2057
2057
|
prob_col->l = l;
|
2058
2058
|
prob_col->n = n;
|
@@ -2140,6 +2140,24 @@ static void group_classes(const problem *prob, int *nr_class_ret, int **label_re
|
|
2140
2140
|
}
|
2141
2141
|
}
|
2142
2142
|
|
2143
|
+
//
|
2144
|
+
// Labels are ordered by their first occurrence in the training set.
|
2145
|
+
// However, for two-class sets with -1/+1 labels and -1 appears first,
|
2146
|
+
// we swap labels to ensure that internally the binary SVM has positive data corresponding to the +1 instances.
|
2147
|
+
//
|
2148
|
+
if (nr_class == 2 && label[0] == -1 && label[1] == 1)
|
2149
|
+
{
|
2150
|
+
swap(label[0],label[1]);
|
2151
|
+
swap(count[0],count[1]);
|
2152
|
+
for(i=0;i<l;i++)
|
2153
|
+
{
|
2154
|
+
if(data_label[i] == 0)
|
2155
|
+
data_label[i] = 1;
|
2156
|
+
else
|
2157
|
+
data_label[i] = 0;
|
2158
|
+
}
|
2159
|
+
}
|
2160
|
+
|
2143
2161
|
int *start = Malloc(int,nr_class);
|
2144
2162
|
start[0] = 0;
|
2145
2163
|
for(i=1;i<nr_class;i++)
|
@@ -2190,7 +2208,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2190
2208
|
tron_obj.set_print_string(liblinear_print_string);
|
2191
2209
|
tron_obj.tron(w);
|
2192
2210
|
delete fun_obj;
|
2193
|
-
delete C;
|
2211
|
+
delete[] C;
|
2194
2212
|
break;
|
2195
2213
|
}
|
2196
2214
|
case L2R_L2LOSS_SVC:
|
@@ -2208,7 +2226,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2208
2226
|
tron_obj.set_print_string(liblinear_print_string);
|
2209
2227
|
tron_obj.tron(w);
|
2210
2228
|
delete fun_obj;
|
2211
|
-
delete C;
|
2229
|
+
delete[] C;
|
2212
2230
|
break;
|
2213
2231
|
}
|
2214
2232
|
case L2R_L2LOSS_SVC_DUAL:
|
@@ -2253,7 +2271,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
|
|
2253
2271
|
tron_obj.set_print_string(liblinear_print_string);
|
2254
2272
|
tron_obj.tron(w);
|
2255
2273
|
delete fun_obj;
|
2256
|
-
delete C;
|
2274
|
+
delete[] C;
|
2257
2275
|
break;
|
2258
2276
|
|
2259
2277
|
}
|
@@ -2409,10 +2427,15 @@ model* train(const problem *prob, const parameter *param)
|
|
2409
2427
|
void cross_validation(const problem *prob, const parameter *param, int nr_fold, double *target)
|
2410
2428
|
{
|
2411
2429
|
int i;
|
2412
|
-
int *fold_start
|
2430
|
+
int *fold_start;
|
2413
2431
|
int l = prob->l;
|
2414
2432
|
int *perm = Malloc(int,l);
|
2415
|
-
|
2433
|
+
if (nr_fold > l)
|
2434
|
+
{
|
2435
|
+
nr_fold = l;
|
2436
|
+
fprintf(stderr,"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
|
2437
|
+
}
|
2438
|
+
fold_start = Malloc(int,nr_fold+1);
|
2416
2439
|
for(i=0;i<l;i++) perm[i]=i;
|
2417
2440
|
for(i=0;i<l;i++)
|
2418
2441
|
{
|
File without changes
|
File without changes
|
File without changes
|
@@ -19,7 +19,7 @@ Introduction
|
|
19
19
|
|
20
20
|
This tool provides a simple interface to LIBLINEAR, a library for
|
21
21
|
large-scale regularized linear classification and regression
|
22
|
-
(http://www.csie.ntu.edu.tw/~cjlin/liblinear).
|
22
|
+
(http://www.csie.ntu.edu.tw/~cjlin/liblinear). It is very easy to use
|
23
23
|
as the usage and the way of specifying parameters are the same as that
|
24
24
|
of LIBLINEAR.
|
25
25
|
|
@@ -95,6 +95,7 @@ matlab> model = train(training_label_vector, training_instance_matrix [,'libline
|
|
95
95
|
if 'col' is set, each column of training_instance_matrix is a data instance. Otherwise each row is a data instance.
|
96
96
|
|
97
97
|
matlab> [predicted_label, accuracy, decision_values/prob_estimates] = predict(testing_label_vector, testing_instance_matrix, model [, 'liblinear_options', 'col']);
|
98
|
+
matlab> [predicted_label] = predict(testing_label_vector, testing_instance_matrix, model [, 'liblinear_options', 'col']);
|
98
99
|
|
99
100
|
-testing_label_vector:
|
100
101
|
An m by 1 vector of prediction labels. If labels of test
|