rb-libsvm 1.0.11 → 1.1.0
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.
- data/.gitignore +1 -1
- data/Gemfile +3 -0
- data/README.md +6 -3
- data/TODO.md +14 -0
- data/ext/libsvm/libsvm.c +47 -31
- data/lib/libsvm/version.rb +1 -1
- data/spec/model_spec.rb +8 -0
- metadata +3 -8
data/.gitignore
CHANGED
data/Gemfile
ADDED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# rb-libsvm -- Ruby language bindings for LIBSVM
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/rb-libsvm)
|
3
4
|
[](http://travis-ci.org/febeling/rb-libsvm)
|
4
5
|
|
5
6
|
This package provides a Ruby bindings to the [LIBSVM][] library. SVM
|
@@ -17,10 +18,10 @@ LIBSVM includes a number of command line tools for preprocessing
|
|
17
18
|
training data and finding parameters. These tools are not included in
|
18
19
|
this gem. You should install the original package if you need them.
|
19
20
|
|
20
|
-
It is helpful to consult the
|
21
|
+
It is helpful to consult the [README][] of the LIBSVM package for
|
21
22
|
reference when configuring the training parameters.
|
22
23
|
|
23
|
-
Currently this package includes libsvm version 3.
|
24
|
+
Currently this package includes libsvm version 3.14.
|
24
25
|
|
25
26
|
## Dependencies
|
26
27
|
|
@@ -83,8 +84,8 @@ Written by C. Florian Ebeling.
|
|
83
84
|
## Contributors
|
84
85
|
|
85
86
|
[Rimas Silkaitis](https://github.com/neovintage)
|
86
|
-
|
87
87
|
[Aleksander Pohl](https://github.com/apohllo)
|
88
|
+
[Andreas Eger](https://github.com/sch1zo)
|
88
89
|
|
89
90
|
## License
|
90
91
|
|
@@ -105,3 +106,5 @@ http://www.igvita.com/2008/01/07/support-vector-machines-svm-in-ruby/
|
|
105
106
|
[svmrubyswig]: http://github.com/tomz/libsvm-ruby-swig/tree/master
|
106
107
|
|
107
108
|
[ruby-svm]: http://sourceforge.net/projects/rubysvm/
|
109
|
+
|
110
|
+
[README]: https://github.com/febeling/libsvm/blob/master/README
|
data/TODO.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# TODO
|
2
|
+
|
3
|
+
These functions from the library are not bound as ruby methods:
|
4
|
+
|
5
|
+
`void svm_get_labels(const struct svm_model *model, int *label);`
|
6
|
+
|
7
|
+
`double svm_get_svr_probability(const struct svm_model *model);`
|
8
|
+
|
9
|
+
`void svm_destroy_param(struct svm_parameter *param);`
|
10
|
+
|
11
|
+
The model holds reference to the parameters struct, so it's not
|
12
|
+
obvious when it's safe to use.
|
13
|
+
|
14
|
+
`int svm_check_probability_model(const struct svm_model *model);`
|
data/ext/libsvm/libsvm.c
CHANGED
@@ -22,7 +22,7 @@ static void model_free(struct svm_model *model) {
|
|
22
22
|
/* Libsvm::Node */
|
23
23
|
static struct svm_node *node_new() {
|
24
24
|
struct svm_node *n;
|
25
|
-
n =
|
25
|
+
n = calloc(1,sizeof(struct svm_node));
|
26
26
|
if(n == NULL)
|
27
27
|
return NULL;
|
28
28
|
return n;
|
@@ -47,7 +47,7 @@ rx_def_accessor(cNode,struct svm_node,double,value);
|
|
47
47
|
/* Libsvm::Problem */
|
48
48
|
static struct svm_problem *problem_new() {
|
49
49
|
struct svm_problem *n;
|
50
|
-
n =
|
50
|
+
n = calloc(1,sizeof(struct svm_problem));
|
51
51
|
if(n == NULL)
|
52
52
|
return NULL;
|
53
53
|
return n;
|
@@ -81,7 +81,7 @@ static struct svm_node *example_to_internal(VALUE example_ary)
|
|
81
81
|
|
82
82
|
/* allocate memory for it */
|
83
83
|
example_ary_len = rx_ary_size(example_ary);
|
84
|
-
x =
|
84
|
+
x = calloc(example_ary_len+1,sizeof(struct svm_node));
|
85
85
|
if(x == 0) {
|
86
86
|
rb_raise(rb_eNoMemError, "on Libsvm::Node allocation" " %s:%i", __FILE__,__LINE__);
|
87
87
|
}
|
@@ -100,13 +100,12 @@ static struct svm_node *example_to_internal(VALUE example_ary)
|
|
100
100
|
static struct svm_node **examples_ary_to_internal(VALUE examples_ary)
|
101
101
|
{
|
102
102
|
struct svm_node **x;
|
103
|
-
|
104
|
-
|
105
|
-
int nodes_ary_len, i;
|
103
|
+
VALUE nodes_ary;
|
104
|
+
int i;
|
106
105
|
|
107
106
|
int num = rx_ary_size(examples_ary);
|
108
107
|
|
109
|
-
x =
|
108
|
+
x = calloc(num,sizeof(struct svm_node *));
|
110
109
|
if(x == 0) {
|
111
110
|
rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__);
|
112
111
|
}
|
@@ -133,10 +132,7 @@ static struct svm_node **examples_ary_to_internal(VALUE examples_ary)
|
|
133
132
|
static VALUE cProblem_examples_set(VALUE obj,VALUE labels_ary,VALUE examples_ary)
|
134
133
|
{
|
135
134
|
struct svm_problem *prob;
|
136
|
-
|
137
|
-
/* VALUE num;*/
|
138
|
-
int i, nodes_ary_len;
|
139
|
-
VALUE label, node, nodes_ary;
|
135
|
+
int i;
|
140
136
|
|
141
137
|
int num = rx_ary_size(labels_ary);
|
142
138
|
|
@@ -154,7 +150,7 @@ static VALUE cProblem_examples_set(VALUE obj,VALUE labels_ary,VALUE examples_ary
|
|
154
150
|
free(prob->x);
|
155
151
|
}
|
156
152
|
|
157
|
-
prob->y =
|
153
|
+
prob->y = calloc(num,sizeof(double));
|
158
154
|
if(prob->y == 0) {
|
159
155
|
rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__);
|
160
156
|
}
|
@@ -182,14 +178,14 @@ static VALUE cProblem_examples(VALUE problem) {
|
|
182
178
|
double label;
|
183
179
|
struct svm_node *features;
|
184
180
|
VALUE labels_ary, examples_ary, example_ary, v_node, result;
|
185
|
-
int i
|
181
|
+
int i;
|
186
182
|
|
187
183
|
Data_Get_Struct(problem, struct svm_problem, prob);
|
188
184
|
|
189
185
|
labels_ary = rb_ary_new2(prob->l);
|
190
186
|
examples_ary = rb_ary_new2(prob->l);
|
191
187
|
|
192
|
-
features =
|
188
|
+
features = calloc(prob->l, sizeof(struct svm_node));
|
193
189
|
if(features == 0) {
|
194
190
|
rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__);
|
195
191
|
}
|
@@ -201,7 +197,7 @@ static VALUE cProblem_examples(VALUE problem) {
|
|
201
197
|
node = *(prob->x+i); /* example start pointer */
|
202
198
|
example_ary = rb_ary_new();
|
203
199
|
while(node->index != -1) {
|
204
|
-
node_copy =
|
200
|
+
node_copy = malloc(sizeof(struct svm_node));
|
205
201
|
if(node_copy == 0) {
|
206
202
|
rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__);
|
207
203
|
}
|
@@ -224,7 +220,7 @@ static VALUE cProblem_examples(VALUE problem) {
|
|
224
220
|
|
225
221
|
static struct svm_parameter *parameter_new() {
|
226
222
|
struct svm_parameter *n;
|
227
|
-
n =
|
223
|
+
n = calloc(1,sizeof(struct svm_parameter));
|
228
224
|
if(n == NULL)
|
229
225
|
return NULL;
|
230
226
|
return n;
|
@@ -270,8 +266,7 @@ rx_def_accessor_as(cSvmParameter,struct svm_parameter,double,C,c);
|
|
270
266
|
*/
|
271
267
|
static VALUE cSvmParameter_label_weights_set(VALUE obj,VALUE weight_hash) {
|
272
268
|
struct svm_parameter *param;
|
273
|
-
int i
|
274
|
-
double weight;
|
269
|
+
int i;
|
275
270
|
VALUE keys,key,val;
|
276
271
|
|
277
272
|
Data_Get_Struct(obj,struct svm_parameter,param);
|
@@ -282,8 +277,8 @@ static VALUE cSvmParameter_label_weights_set(VALUE obj,VALUE weight_hash) {
|
|
282
277
|
}
|
283
278
|
|
284
279
|
param->nr_weight = rx_hash_size(weight_hash);
|
285
|
-
param->weight =
|
286
|
-
param->weight_label =
|
280
|
+
param->weight = calloc(param->nr_weight,sizeof(double));
|
281
|
+
param->weight_label = calloc(param->nr_weight,sizeof(int));
|
287
282
|
|
288
283
|
keys = rb_funcall(weight_hash, rb_intern("keys"),0);
|
289
284
|
|
@@ -353,6 +348,36 @@ static VALUE cModel_predict(VALUE obj,VALUE example) {
|
|
353
348
|
return rb_float_new(class);
|
354
349
|
}
|
355
350
|
|
351
|
+
static VALUE cModel_predict_probability(VALUE obj,VALUE example) {
|
352
|
+
struct svm_node *x;
|
353
|
+
struct svm_model *model;
|
354
|
+
double class;
|
355
|
+
double *c_estimates;
|
356
|
+
VALUE estimates;
|
357
|
+
VALUE target;
|
358
|
+
int i;
|
359
|
+
|
360
|
+
x = example_to_internal(example);
|
361
|
+
Data_Get_Struct(obj, struct svm_model, model);
|
362
|
+
c_estimates = calloc(model->nr_class, sizeof(double));
|
363
|
+
if(c_estimates == 0) {
|
364
|
+
rb_raise(rb_eNoMemError, "on predict probability estimates allocation" " %s:%i", __FILE__,__LINE__);
|
365
|
+
}
|
366
|
+
|
367
|
+
class = svm_predict_probability(model, x, c_estimates);
|
368
|
+
|
369
|
+
estimates = rb_ary_new();
|
370
|
+
for (i = 0; i < model->nr_class; i++)
|
371
|
+
rb_ary_push(estimates, rx_from_double(c_estimates[i]));
|
372
|
+
|
373
|
+
free(c_estimates);
|
374
|
+
|
375
|
+
target = rb_ary_new();
|
376
|
+
rb_ary_push(target, rb_float_new(class));
|
377
|
+
rb_ary_push(target, estimates);
|
378
|
+
return target;
|
379
|
+
}
|
380
|
+
|
356
381
|
static VALUE cModel_save(VALUE obj, VALUE filename)
|
357
382
|
{
|
358
383
|
const struct svm_model *model;
|
@@ -406,7 +431,7 @@ static VALUE cModel_class_cross_validation(VALUE cls, VALUE problem, VALUE param
|
|
406
431
|
nr_fold = NUM2INT(num_fold);
|
407
432
|
|
408
433
|
target = rb_ary_new2(prob->l);
|
409
|
-
target_ptr =
|
434
|
+
target_ptr = calloc(prob->l, sizeof(double));
|
410
435
|
if(target_ptr == 0) {
|
411
436
|
rb_raise(rb_eNoMemError, "on cross-validation result allocation" " %s:%i", __FILE__,__LINE__);
|
412
437
|
}
|
@@ -466,16 +491,7 @@ void Init_libsvm_ext() {
|
|
466
491
|
rb_define_method(cModel, "svm_type", cModel_svm_type, 0);
|
467
492
|
rb_define_method(cModel, "classes", cModel_classes, 0);
|
468
493
|
rb_define_method(cModel, "predict", cModel_predict, 1);
|
469
|
-
|
470
|
-
/*
|
471
|
-
Not covered, for various reasons:
|
472
|
-
TODO - void svm_get_labels(const struct svm_model *model, int *label);
|
473
|
-
SVR? - double svm_get_svr_probability(const struct svm_model *model);
|
474
|
-
SVR? - double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates);
|
475
|
-
Model holds reference to this, so when to use it?
|
476
|
-
void svm_destroy_param(struct svm_parameter *param);
|
477
|
-
SVR? - int svm_check_probability_model(const struct svm_model *model);
|
478
|
-
*/
|
494
|
+
rb_define_method(cModel, "predict_probability", cModel_predict_probability, 1);
|
479
495
|
|
480
496
|
mKernelType = rb_define_module_under(mLibsvm, "KernelType");
|
481
497
|
rb_define_const(mKernelType, "LINEAR", INT2NUM(LINEAR));
|
data/lib/libsvm/version.rb
CHANGED
data/spec/model_spec.rb
CHANGED
@@ -21,6 +21,7 @@ module ModelSpecHelper
|
|
21
21
|
parameter.cache_size = 50 # mb
|
22
22
|
parameter.eps = 0.01
|
23
23
|
parameter.c = 10
|
24
|
+
parameter.probability = 1
|
24
25
|
parameter
|
25
26
|
end
|
26
27
|
|
@@ -92,4 +93,11 @@ describe "An Libsvm model" do
|
|
92
93
|
prediction = @model.predict(create_example)
|
93
94
|
prediction.should_not be_nil
|
94
95
|
end
|
96
|
+
|
97
|
+
it "can predict probability" do
|
98
|
+
prediction, probabilities = @model.predict_probability(create_example)
|
99
|
+
prediction.should_not be_nil
|
100
|
+
probabilities.should have(@model.classes).items
|
101
|
+
probabilities.each { |e| e.should_not be_nil }
|
102
|
+
end
|
95
103
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb-libsvm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2013-01-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake-compiler
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- MIT-LICENSE
|
62
62
|
- README.md
|
63
63
|
- Rakefile
|
64
|
+
- TODO.md
|
64
65
|
- examples/text.rb
|
65
66
|
- examples/toy.rb
|
66
67
|
- ext/libsvm/extconf.rb
|
@@ -90,18 +91,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
91
|
- - ! '>='
|
91
92
|
- !ruby/object:Gem::Version
|
92
93
|
version: '0'
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
hash: 859207920834715629
|
96
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
95
|
none: false
|
98
96
|
requirements:
|
99
97
|
- - ! '>='
|
100
98
|
- !ruby/object:Gem::Version
|
101
99
|
version: '0'
|
102
|
-
segments:
|
103
|
-
- 0
|
104
|
-
hash: 859207920834715629
|
105
100
|
requirements: []
|
106
101
|
rubyforge_project: rb-libsvm
|
107
102
|
rubygems_version: 1.8.23
|