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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +141 -10
  3. data/{liblinear-1.93/ruby → ext}/liblinear.i +0 -0
  4. data/ext/linear.cpp +30 -7
  5. data/ext/tron.cpp +4 -4
  6. data/lib/liblinear/model.rb +3 -3
  7. data/lib/liblinear/parameter.rb +2 -2
  8. data/lib/liblinear/problem.rb +4 -17
  9. data/lib/liblinear/version.rb +1 -1
  10. data/lib/liblinear.rb +46 -13
  11. data/{liblinear-1.93 → liblinear-1.94}/COPYRIGHT +0 -0
  12. data/{liblinear-1.93 → liblinear-1.94}/Makefile +0 -0
  13. data/{liblinear-1.93 → liblinear-1.94}/Makefile.win +0 -0
  14. data/{liblinear-1.93 → liblinear-1.94}/README +0 -0
  15. data/{liblinear-1.93 → liblinear-1.94}/blas/Makefile +0 -0
  16. data/{liblinear-1.93 → liblinear-1.94}/blas/blas.h +0 -0
  17. data/{liblinear-1.93 → liblinear-1.94}/blas/blasp.h +0 -0
  18. data/{liblinear-1.93 → liblinear-1.94}/blas/daxpy.c +0 -0
  19. data/{liblinear-1.93 → liblinear-1.94}/blas/ddot.c +0 -0
  20. data/{liblinear-1.93 → liblinear-1.94}/blas/dnrm2.c +0 -0
  21. data/{liblinear-1.93 → liblinear-1.94}/blas/dscal.c +0 -0
  22. data/{liblinear-1.93 → liblinear-1.94}/heart_scale +0 -0
  23. data/{liblinear-1.93 → liblinear-1.94}/linear.cpp +30 -7
  24. data/{liblinear-1.93 → liblinear-1.94}/linear.def +0 -0
  25. data/{liblinear-1.93 → liblinear-1.94}/linear.h +0 -0
  26. data/{liblinear-1.93 → liblinear-1.94}/matlab/Makefile +0 -0
  27. data/{liblinear-1.93 → liblinear-1.94}/matlab/README +2 -1
  28. data/{liblinear-1.93 → liblinear-1.94}/matlab/libsvmread.c +25 -24
  29. data/{liblinear-1.93 → liblinear-1.94}/matlab/libsvmwrite.c +15 -1
  30. data/{liblinear-1.93 → liblinear-1.94}/matlab/linear_model_matlab.c +0 -0
  31. data/{liblinear-1.93 → liblinear-1.94}/matlab/linear_model_matlab.h +0 -0
  32. data/{liblinear-1.93 → liblinear-1.94}/matlab/make.m +0 -0
  33. data/{liblinear-1.93 → liblinear-1.94}/matlab/predict.c +37 -25
  34. data/{liblinear-1.93 → liblinear-1.94}/matlab/train.c +16 -7
  35. data/{liblinear-1.93 → liblinear-1.94}/predict.c +0 -0
  36. data/{liblinear-1.93 → liblinear-1.94}/python/Makefile +0 -0
  37. data/{liblinear-1.93 → liblinear-1.94}/python/README +1 -1
  38. data/{liblinear-1.93 → liblinear-1.94}/python/liblinear.py +1 -1
  39. data/{liblinear-1.93 → liblinear-1.94}/python/liblinearutil.py +0 -0
  40. data/{liblinear-1.93 → liblinear-1.94}/train.c +0 -0
  41. data/{liblinear-1.93 → liblinear-1.94}/tron.cpp +4 -4
  42. data/{liblinear-1.93 → liblinear-1.94}/tron.h +0 -0
  43. data/{liblinear-1.93 → liblinear-1.94}/windows/liblinear.dll +0 -0
  44. data/{liblinear-1.93 → liblinear-1.94}/windows/libsvmread.mexw64 +0 -0
  45. data/{liblinear-1.93 → liblinear-1.94}/windows/libsvmwrite.mexw64 +0 -0
  46. data/{liblinear-1.93 → liblinear-1.94}/windows/predict.exe +0 -0
  47. data/liblinear-1.94/windows/predict.mexw64 +0 -0
  48. data/{liblinear-1.93 → liblinear-1.94}/windows/train.exe +0 -0
  49. data/liblinear-1.94/windows/train.mexw64 +0 -0
  50. data/spec/liblinear/model_spec.rb +56 -0
  51. data/spec/liblinear/parameter_spec.rb +57 -0
  52. data/spec/liblinear/problem_spec.rb +23 -0
  53. data/spec/liblinear_spec.rb +104 -0
  54. metadata +51 -56
  55. data/ext/linear.rb +0 -357
  56. data/liblinear-1.93/blas/blas.a +0 -0
  57. data/liblinear-1.93/blas/daxpy.o +0 -0
  58. data/liblinear-1.93/blas/ddot.o +0 -0
  59. data/liblinear-1.93/blas/dnrm2.o +0 -0
  60. data/liblinear-1.93/blas/dscal.o +0 -0
  61. data/liblinear-1.93/linear.o +0 -0
  62. data/liblinear-1.93/predict +0 -0
  63. data/liblinear-1.93/ruby/liblinear_wrap.cxx +0 -4646
  64. data/liblinear-1.93/ruby/linear.h +0 -74
  65. data/liblinear-1.93/ruby/linear.o +0 -0
  66. data/liblinear-1.93/train +0 -0
  67. data/liblinear-1.93/tron.o +0 -0
  68. data/liblinear-1.93/windows/predict.mexw64 +0 -0
  69. data/liblinear-1.93/windows/train.mexw64 +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5627682e3eced50c405c213569f4c18f178bd6a5
4
- data.tar.gz: abdf3297770c99e176b26a74c34d2e2c4eb03de1
3
+ metadata.gz: 5a7efbbe95e53288a0a4be6ae55411f693a16b65
4
+ data.tar.gz: c7882e4f98923ff2193b9eb797f918bf7a83295d
5
5
  SHA512:
6
- metadata.gz: 71443f67c21c93fbafd8031554045db2b8bdeddd2574b5dc582bf7cd034f5725c2bfe2acf56706fb5b07f5e82b598b43b2595619e14889c7ca913136668bf1ee
7
- data.tar.gz: c85b14d11e5a858297826747c49a890ef60e63531750be77cb403cfc3543ca294d440dafa084d25752801387a351cd7da9d7cca8277846345de30b0bb9d02e2e
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(1.9.3) using SWIG.
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
- ## Usage
20
-
21
+ ## Quick Start
22
+ This sample code execute classification with L2-regularized logistic regression.
21
23
  ```ruby
22
24
  require 'liblinear'
23
- pa = Liblinear::Parameter.new({solver_type: 0})
24
- bias = 0.5
25
- labels = [1, 2]
26
- # examples must be Array of Hash or Array
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
- pr = Liblinear::Problem.new(labels, examples, bias)
32
- m = Liblinear::Model.new(pr, pa)
33
- puts m.predict({1=>1, 2=>1, 3=>1, 4=>1, 5=>1}) # => 2.0
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 = Malloc(int,nr_fold+1);
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
- f = fun_obj->fun(w);
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
- fnew = fun_obj->fun(w_new);
97
+ fnew = fun_obj->fun(w_new);
98
98
 
99
99
  // Compute the actual reduction.
100
- actred = f - fnew;
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
- fun_obj->grad(w, g);
130
+ fun_obj->grad(w, g);
131
131
 
132
132
  gnorm = dnrm2_(&n, g, &inc);
133
133
  if (gnorm <= eps*gnorm1)
@@ -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)
@@ -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)
@@ -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>, Array<Hash>]
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 = 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)
@@ -1,3 +1,3 @@
1
1
  module Liblinear
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
data/lib/liblinear.rb CHANGED
@@ -8,7 +8,19 @@ require 'liblinear/problem'
8
8
  require 'liblinear/version'
9
9
 
10
10
  module Liblinear
11
- # @param ruby_array [Array<Integer>]
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
- if example.is_a?(Hash)
62
- example.each_key do |key|
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 = Malloc(int,nr_fold+1);
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). It is very easy to use
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