liblinear-ruby 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](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
|