rb-libsvm 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ tmp/
2
+ *.bundle
3
+ *.so
4
+ *.dylib
5
+ *.model
6
+ pkg/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@rblibsvm --create
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in libsvmr.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rb-libsvm (1.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.3)
10
+ rake (0.9.2.2)
11
+ rake-compiler (0.7.9)
12
+ rake
13
+ rspec (2.7.0)
14
+ rspec-core (~> 2.7.0)
15
+ rspec-expectations (~> 2.7.0)
16
+ rspec-mocks (~> 2.7.0)
17
+ rspec-core (2.7.1)
18
+ rspec-expectations (2.7.0)
19
+ diff-lcs (~> 1.1.2)
20
+ rspec-mocks (2.7.0)
21
+
22
+ PLATFORMS
23
+ ruby
24
+
25
+ DEPENDENCIES
26
+ rake-compiler
27
+ rb-libsvm!
28
+ rspec (= 2.7.0)
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2004-2008 Caspar Florian Ebeling
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,37 @@
1
+ h1. rb-libsvm -- Ruby language bindings for LIBSVM
2
+
3
+ This is a module which provides a Ruby API to the LIBSVM [1] library.
4
+ SVM is a machine learning and classification algorithm, and LIBSVM is
5
+ a popular free implementation of it, written by Chih-Chung Chang and
6
+ Chih-Jen Lin, of National Taiwan University, Taipei. See "Programming
7
+ Collective Intelligence," [2] among others, for a usage example.
8
+
9
+ Note: There exists another Ruby binding for LIBSVM, named Ruby SVM,
10
+ [3] written by Rudi Cilibrasi. (That's the one mentioned in the
11
+ libsvm documentation.) This package is not related but written
12
+ independently and from scratch.
13
+
14
+ h2. Dependencies
15
+
16
+ None. Libsvm is bundled with the project. Just clone and go!
17
+
18
+ Currently using libsvm version 3.1
19
+
20
+ h2. Author, License
21
+
22
+ Written by C. Florian Ebeling. This software can be freely used under
23
+ the terms of the MIT license, see file MIT-LICENSE.
24
+
25
+ h2. Contributors
26
+
27
+ Rimas Silkaitis
28
+
29
+ h3. Notes
30
+
31
+ fn1. http://www.csie.ntu.edu.tw/~cjlin/libsvm/
32
+
33
+ fn2. http://books.google.com/books?id=fEsZ3Ey-Hq4C
34
+
35
+ fn3. http://rubysvm.cilibrar.com/
36
+
37
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/extensiontask"
3
+ require 'rspec/core/rake_task'
4
+
5
+ Rake::ExtensionTask.new('rb-libsvm') do |ext|
6
+ ext.lib_dir = File.join('lib', 'rb-libsvm')
7
+ ext.name = 'libsvm'
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new('spec')
11
+ Rake::Task[:spec].prerequisites << :clean
12
+ Rake::Task[:spec].prerequisites << :compile
13
+
@@ -0,0 +1,46 @@
1
+ require 'mkmf'
2
+
3
+ # $CFLAGS << " -save-temps -ggdb3 "
4
+ # $LDFLAGS << " -lstdc++ "
5
+
6
+ # find_header('ruby.h')
7
+ # find_library('svm', 'svm_train', '/opt/local/lib/', '/usr/lib/') || raise("svm library not found.")
8
+ # find_header('svm.h', "/opt/local/include/", "/usr/include/libsvm-2.0/libsvm/")
9
+ # create_makefile('libsvm_ext')
10
+
11
+ LIBDIR = Config::CONFIG['libdir']
12
+ INCLUDEDIR = Config::CONFIG['includedir']
13
+
14
+ HEADER_DIRS = [
15
+ # First search /opt/local for macports
16
+ '/opt/local/include',
17
+
18
+ # Then search /usr/local for people that installed from source
19
+ '/usr/local/include',
20
+
21
+ # Check the ruby install locations
22
+ INCLUDEDIR,
23
+
24
+ # Finally fall back to /usr
25
+ '/usr/include',
26
+ ]
27
+
28
+ LIB_DIRS = [
29
+ # First search /opt/local for macports
30
+ '/opt/local/lib',
31
+
32
+ # Then search /usr/local for people that installed from source
33
+ '/usr/local/lib',
34
+
35
+ # Check the ruby install locations
36
+ LIBDIR,
37
+
38
+ # Finally fall back to /usr
39
+ '/usr/lib',
40
+ ]
41
+
42
+ dir_config('rb-libsvm',HEADER_DIRS,LIB_DIRS)
43
+
44
+ # Don't think I need to search the dirs for the header file
45
+
46
+ create_makefile('rb-libsvm/libsvm')
@@ -0,0 +1,489 @@
1
+ #include "ruby.h"
2
+ #include "svm.h"
3
+ #include "ruby-ext.h"
4
+ #include <string.h>
5
+
6
+ VALUE mLibsvm;
7
+
8
+ VALUE cNode;
9
+ VALUE cProblem;
10
+ VALUE cSvmParameter;
11
+ VALUE cModel;
12
+
13
+ VALUE mKernelType;
14
+ VALUE mSvmType;
15
+
16
+ const struct svm_node TERMINATOR = (struct svm_node) { -1, 0.0 };
17
+
18
+ /* Libsvm::Node */
19
+ static struct svm_node *node_new() {
20
+ struct svm_node *n;
21
+ n = (struct svm_node *) calloc(1,sizeof(struct svm_node));
22
+ if(n == NULL)
23
+ return NULL;
24
+ return n;
25
+ }
26
+
27
+ static void node_free(struct svm_node *n) {
28
+ free(n);
29
+ }
30
+
31
+ static VALUE node_alloc(VALUE cls) {
32
+ struct svm_node *n;
33
+ n = node_new();
34
+ if(n == NULL)
35
+ rb_raise(rb_eNoMemError, "Not enough memory for allocating Node.");
36
+
37
+ return Data_Wrap_Struct(cls, 0, node_free, n);
38
+ }
39
+
40
+ rx_def_accessor(cNode,struct svm_node,int,index);
41
+ rx_def_accessor(cNode,struct svm_node,double,value);
42
+
43
+ /* Libsvm::Problem */
44
+ static struct svm_problem *problem_new() {
45
+ struct svm_problem *n;
46
+ n = (struct svm_problem *) calloc(1,sizeof(struct svm_problem));
47
+ if(n == NULL)
48
+ return NULL;
49
+ return n;
50
+ }
51
+
52
+ static void problem_free(struct svm_problem *n) {
53
+ /*
54
+ Deliberate no-op, because of this note from the README:
55
+
56
+ `*NOTE* Because svm_model contains pointers to svm_problem, you can
57
+ not free the memory used by svm_problem if you are still using the
58
+ svm_model produced by svm_train().'
59
+ */
60
+ }
61
+
62
+ static VALUE problem_alloc(VALUE cls) {
63
+ struct svm_problem *n;
64
+ n = problem_new();
65
+ if(n == NULL)
66
+ rb_raise(rb_eNoMemError, "Not enough memory for allocating Libsvm::Problem.");
67
+ return Data_Wrap_Struct(cls, 0, problem_free, n);
68
+ }
69
+
70
+ rx_def_accessor(cProblem,struct svm_problem,int,l);
71
+
72
+ static struct svm_node *example_to_internal(VALUE example_ary)
73
+ {
74
+ struct svm_node *x, *node_struct;
75
+ int example_ary_len, j;
76
+ VALUE node;
77
+
78
+ /* allocate memory for it */
79
+ example_ary_len = rx_ary_size(example_ary);
80
+ x = (struct svm_node *)calloc(example_ary_len+1,sizeof(struct svm_node));
81
+ if(x == 0) {
82
+ rb_raise(rb_eNoMemError, "on Libsvm::Node allocation" " %s:%i", __FILE__,__LINE__);
83
+ }
84
+ /* loop it's element nodes */
85
+ for(j = 0; j < example_ary_len; ++j) {
86
+ node = rb_ary_entry(example_ary,j);
87
+ Data_Get_Struct(node,struct svm_node,node_struct);
88
+ memcpy(x+j,node_struct,sizeof(struct svm_node));
89
+ }
90
+ /* add terminator */
91
+ memcpy(x+example_ary_len,&TERMINATOR,sizeof(struct svm_node));
92
+
93
+ return x;
94
+ }
95
+
96
+ static struct svm_node **examples_ary_to_internal(VALUE examples_ary)
97
+ {
98
+ struct svm_node **x;
99
+ struct svm_node *node_struct;
100
+ VALUE nodes_ary, node;
101
+ int nodes_ary_len, i;
102
+
103
+ int num = rx_ary_size(examples_ary);
104
+
105
+ x = (struct svm_node **)calloc(num,sizeof(struct svm_node *));
106
+ if(x == 0) {
107
+ rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__);
108
+ }
109
+
110
+ for(i = 0; i < num; ++i) {
111
+ nodes_ary = rb_ary_entry(examples_ary,i);
112
+ *(x+i) = example_to_internal(nodes_ary);
113
+ }
114
+
115
+ return x;
116
+ }
117
+
118
+ /*
119
+ call-seq:
120
+ problem.set_examples(labels, examples_array)
121
+
122
+ double *y; // class (aka. label) of the example
123
+ struct svm_node **x; // examples
124
+
125
+ This method sets the contents of an SVM Problem, which consists
126
+ of lables (or classifications) and examples (or feature vectors).
127
+ If those 2 don't match in length and ArgumentError is raised.
128
+ */
129
+ static VALUE cProblem_examples_set(VALUE obj,VALUE labels_ary,VALUE examples_ary)
130
+ {
131
+ struct svm_problem *prob;
132
+ struct svm_node *node_struct;
133
+ /* VALUE num;*/
134
+ int i, nodes_ary_len;
135
+ VALUE label, node, nodes_ary;
136
+
137
+ int num = rx_ary_size(labels_ary);
138
+
139
+ if(num != rx_ary_size(examples_ary)) {
140
+ rb_raise(rb_eArgError, "Number of labels (%i) does not match number of features (%i).", num, rx_ary_size(examples_ary));
141
+ }
142
+
143
+ Data_Get_Struct(obj, struct svm_problem, prob);
144
+
145
+ if(prob->l > 0) {
146
+ free(prob->y);
147
+ for(i = 0; i < num; ++i) {
148
+ free(*(prob->x+i));
149
+ }
150
+ free(prob->x);
151
+ }
152
+
153
+ prob->y = (double *)calloc(num,sizeof(double));
154
+ if(prob->y == 0) {
155
+ rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__);
156
+ }
157
+
158
+ for(i = 0; i < num; ++i) {
159
+ *(prob->y+i) = NUM2DBL(rb_ary_entry(labels_ary,i));
160
+ }
161
+
162
+ prob->x = examples_ary_to_internal(examples_ary);
163
+ prob->l = num;
164
+
165
+ return INT2FIX(num);
166
+ }
167
+
168
+ /*
169
+ call-seq:
170
+ labels, array_of_arrays = problem.examples
171
+
172
+ double *y; // class/label of the example
173
+ struct svm_node **x;
174
+ */
175
+ static VALUE cProblem_examples(VALUE problem) {
176
+ struct svm_problem *prob;
177
+ struct svm_node *node, *node_copy;
178
+ double label;
179
+ struct svm_node *features;
180
+ VALUE labels_ary, examples_ary, example_ary, v_node, result;
181
+ int i,n;
182
+
183
+ Data_Get_Struct(problem, struct svm_problem, prob);
184
+
185
+ labels_ary = rb_ary_new2(prob->l);
186
+ examples_ary = rb_ary_new2(prob->l);
187
+
188
+ features = (struct svm_node *)calloc(prob->l, sizeof(struct svm_node));
189
+ if(features == 0) {
190
+ rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__);
191
+ }
192
+
193
+ for(i = 0; i < prob->l; ++i) {
194
+ label = *(prob->y+i);
195
+ rb_ary_push(labels_ary,rb_float_new(label));
196
+
197
+ node = *(prob->x+i); /* example start pointer */
198
+ example_ary = rb_ary_new();
199
+ while(node->index != -1) {
200
+ node_copy = (struct svm_node *)malloc(sizeof(struct svm_node));
201
+ if(node_copy == 0) {
202
+ rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__);
203
+ }
204
+ memcpy(node_copy,node,sizeof(struct svm_node));
205
+ v_node = Data_Wrap_Struct(cNode,0,node_free,node_copy);
206
+ rb_ary_push(example_ary,v_node);
207
+ ++node;
208
+ }
209
+ rb_ary_push(examples_ary,example_ary);
210
+ }
211
+
212
+ result = rb_ary_new2(2);
213
+ rb_ary_push(result,labels_ary);
214
+ rb_ary_push(result,examples_ary);
215
+
216
+ return result;
217
+ }
218
+
219
+ /* SvmParameter */
220
+
221
+ static struct svm_parameter *parameter_new() {
222
+ struct svm_parameter *n;
223
+ n = (struct svm_parameter *) calloc(1,sizeof(struct svm_parameter));
224
+ if(n == NULL)
225
+ return NULL;
226
+ return n;
227
+ }
228
+
229
+ static void parameter_free(struct svm_parameter *n) {
230
+ // svm_destroy_param(n);
231
+ free(n);
232
+ }
233
+
234
+ static VALUE parameter_alloc(VALUE cls) {
235
+ struct svm_parameter *n;
236
+ n = parameter_new();
237
+ if(n == NULL)
238
+ rb_raise(rb_eNoMemError, "Not enough memory for allocating SvmParameter.");
239
+
240
+ return Data_Wrap_Struct(cls, 0, parameter_free, n);
241
+ }
242
+
243
+ rx_def_accessor(cSvmParameter,struct svm_parameter,int,svm_type)
244
+ rx_def_accessor(cSvmParameter,struct svm_parameter,int,kernel_type);
245
+ rx_def_accessor(cSvmParameter,struct svm_parameter,int,degree);
246
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,gamma);
247
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,coef0);
248
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,cache_size);
249
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,eps);
250
+ rx_def_accessor_as(cSvmParameter,struct svm_parameter,double,C,c);
251
+
252
+ /* Label weight.
253
+
254
+ nr_weight, weight_label, and weight are used to change the penalty
255
+ for some classes (If the weight for a class is not changed, it is
256
+ set to 1). This is useful for training classifier using unbalanced
257
+ input data or with asymmetric misclassification cost.
258
+
259
+ nr_weight is the number of elements in the array weight_label and
260
+ weight. Each weight[i] corresponds to weight_label[i], meaning that
261
+ the penalty of class weight_label[i] is scaled by a factor of weight[i].
262
+
263
+ If you do not want to change penalty for any of the classes,
264
+ just set nr_weight to 0.
265
+
266
+ */
267
+ static VALUE cSvmParameter_label_weights_set(VALUE obj,VALUE weight_hash) {
268
+ struct svm_parameter *param;
269
+ int i,len,weight_label;
270
+ double weight;
271
+ VALUE keys,key,val;
272
+
273
+ Data_Get_Struct(obj,struct svm_parameter,param);
274
+
275
+ if(param->nr_weight > 0) {
276
+ free(param->weight);
277
+ free(param->weight_label);
278
+ }
279
+
280
+ param->nr_weight = rx_hash_size(weight_hash);
281
+ param->weight = (double *)calloc(param->nr_weight,sizeof(double));
282
+ param->weight_label = (int *)calloc(param->nr_weight,sizeof(int));
283
+
284
+ keys = rb_funcall(weight_hash, rb_intern("keys"),0);
285
+
286
+ for(i = 0; i < param->nr_weight; ++i) {
287
+ key = rb_ary_entry(keys,i);
288
+ val = rb_hash_aref(weight_hash,key);
289
+
290
+ param->weight_label[i] = NUM2INT(key);
291
+ param->weight[i] = NUM2DBL(val);
292
+ }
293
+
294
+ return Qnil;
295
+ }
296
+
297
+ static VALUE cSvmParameter_label_weights(VALUE obj) {
298
+ struct svm_parameter *param;
299
+ int i;
300
+ VALUE hash,key,val;
301
+
302
+ Data_Get_Struct(obj,struct svm_parameter,param);
303
+
304
+ hash = rb_hash_new();
305
+
306
+ for(i = 0; i < param->nr_weight; ++i) {
307
+ key = INT2NUM(param->weight_label[i]);
308
+ val = rb_float_new(param->weight[i]);
309
+ rb_hash_aset(hash,key,val);
310
+ }
311
+
312
+ return hash;
313
+ }
314
+
315
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,nu);
316
+ rx_def_accessor(cSvmParameter,struct svm_parameter,double,p);
317
+ rx_def_accessor(cSvmParameter,struct svm_parameter,int,shrinking);
318
+ rx_def_accessor(cSvmParameter,struct svm_parameter,int,probability);
319
+
320
+ /* Libsvm::Model */
321
+
322
+ static VALUE cModel_class_train(VALUE obj,VALUE problem,VALUE parameter) {
323
+ const struct svm_problem *prob;
324
+ const struct svm_parameter *param;
325
+ struct svm_model *model;
326
+ const char *check_error;
327
+
328
+ Data_Get_Struct(problem, struct svm_problem, prob);
329
+ Data_Get_Struct(parameter, struct svm_parameter, param);
330
+
331
+ check_error = svm_check_parameter(prob, param);
332
+ if(check_error != NULL) {
333
+ rb_raise(rb_eArgError, "Parameters not valid for Problem: '%s'", check_error);
334
+ }
335
+ model = svm_train(prob,param);
336
+
337
+ return Data_Wrap_Struct(cModel, 0, svm_free_and_destroy_model, model);
338
+ }
339
+
340
+ static VALUE cModel_predict(VALUE obj,VALUE example) {
341
+ struct svm_node *x;
342
+ struct svm_model *model;
343
+ double class;
344
+
345
+ x = example_to_internal(example);
346
+ Data_Get_Struct(obj, struct svm_model, model);
347
+ class = svm_predict(model, x);
348
+
349
+ return rb_float_new(class);
350
+ }
351
+
352
+ static VALUE cModel_save(VALUE obj, VALUE filename)
353
+ {
354
+ const struct svm_model *model;
355
+ const char *path;
356
+ int rc;
357
+
358
+ Data_Get_Struct(obj, struct svm_model, model);
359
+ path = StringValueCStr(filename);
360
+
361
+ if(rc = svm_save_model(path, model)) {
362
+ rb_raise(rb_eStandardError, "Error on saving model, code: %i", rc);
363
+ }
364
+
365
+ return Qnil;
366
+ }
367
+
368
+ static VALUE cModel_svm_type(VALUE obj)
369
+ {
370
+ const struct svm_model *model;
371
+ Data_Get_Struct(obj, struct svm_model, model);
372
+ return INT2NUM(svm_get_svm_type(model));
373
+ }
374
+
375
+ static VALUE cModel_classes(VALUE obj)
376
+ {
377
+ const struct svm_model *model;
378
+ Data_Get_Struct(obj, struct svm_model, model);
379
+ return INT2NUM(svm_get_nr_class(model));
380
+ }
381
+
382
+ static VALUE cModel_class_load(VALUE cls, VALUE filename)
383
+ {
384
+ struct svm_model *model;
385
+ char *path;
386
+ path = StringValueCStr(filename);
387
+ model = svm_load_model(path);
388
+ return Data_Wrap_Struct(cModel, 0, svm_free_and_destroy_model, model);
389
+ }
390
+
391
+ static VALUE cModel_class_cross_validation(VALUE cls, VALUE problem, VALUE parameter, VALUE num_fold)
392
+ {
393
+ const struct svm_problem *prob;
394
+ const struct svm_parameter *param;
395
+ int nr_fold, i;
396
+ double *target_ptr;
397
+ VALUE target;
398
+
399
+ Data_Get_Struct(problem, struct svm_problem, prob);
400
+ Data_Get_Struct(parameter, struct svm_parameter, param);
401
+
402
+ nr_fold = NUM2INT(num_fold);
403
+
404
+ target = rb_ary_new2(prob->l);
405
+ target_ptr = (double *)calloc(prob->l, sizeof(double));
406
+ if(target_ptr == 0) {
407
+ rb_raise(rb_eNoMemError, "on cross-validation result allocation" " %s:%i", __FILE__,__LINE__);
408
+ }
409
+
410
+ svm_cross_validation(prob, param, nr_fold, target_ptr);
411
+
412
+ for(i = 0; i < prob->l; ++i) {
413
+ rb_ary_push(target, rb_float_new(*(target_ptr+i)));
414
+ }
415
+
416
+ free(target_ptr);
417
+
418
+ return target;
419
+ }
420
+
421
+ void Init_libsvm() {
422
+ mLibsvm = rb_define_module("Libsvm");
423
+
424
+ /* Libsvm::Problem */
425
+ cProblem = rb_define_class_under(mLibsvm, "Problem", rb_cObject);
426
+ rb_define_alloc_func(cProblem, problem_alloc);
427
+ rx_reg_accessor(cProblem, l);
428
+ rb_define_method(cProblem, "set_examples", cProblem_examples_set, 2);
429
+ rb_define_method(cProblem, "examples", cProblem_examples, 0);
430
+
431
+ /* Libsvm::SvmParameter */
432
+ cSvmParameter = rb_define_class_under(mLibsvm, "SvmParameter", rb_cObject);
433
+ rb_define_alloc_func(cSvmParameter, parameter_alloc);
434
+ rx_reg_accessor(cSvmParameter,svm_type);
435
+ rx_reg_accessor(cSvmParameter,kernel_type);
436
+ rx_reg_accessor(cSvmParameter,degree);
437
+ rx_reg_accessor(cSvmParameter,gamma);
438
+ rx_reg_accessor(cSvmParameter,coef0);
439
+ rx_reg_accessor(cSvmParameter,cache_size);
440
+ rx_reg_accessor(cSvmParameter,eps);
441
+ rx_reg_accessor_as(cSvmParameter,C,c);
442
+ rb_define_method(cSvmParameter,"label_weights=",cSvmParameter_label_weights_set,1);
443
+ rb_define_method(cSvmParameter,"label_weights",cSvmParameter_label_weights,0);
444
+ rx_reg_accessor(cSvmParameter,nu);
445
+ rx_reg_accessor(cSvmParameter,p);
446
+ rx_reg_accessor(cSvmParameter,shrinking);
447
+ rx_reg_accessor(cSvmParameter,probability);
448
+
449
+ /* Libsvm::Node */
450
+ cNode = rb_define_class_under(mLibsvm, "Node", rb_cObject);
451
+ rb_define_alloc_func(cNode, node_alloc);
452
+ rx_reg_accessor(cNode,index);
453
+ rx_reg_accessor(cNode,value);
454
+
455
+ /* Libsvm::Model */
456
+ cModel = rb_define_class_under(mLibsvm, "Model", rb_cObject);
457
+ // model_alloc not necessary, since we don't ever create, only wrap it.
458
+ rb_define_singleton_method(cModel, "train", cModel_class_train, 2);
459
+ rb_define_singleton_method(cModel, "cross_validation", cModel_class_cross_validation, 3);
460
+ rb_define_singleton_method(cModel, "load", cModel_class_load, 1);
461
+ rb_define_method(cModel, "save", cModel_save, 1);
462
+ rb_define_method(cModel, "svm_type", cModel_svm_type, 0);
463
+ rb_define_method(cModel, "classes", cModel_classes, 0);
464
+ rb_define_method(cModel, "predict", cModel_predict, 1);
465
+
466
+ /*
467
+ Not covered, for various reasons:
468
+ TODO - void svm_get_labels(const struct svm_model *model, int *label);
469
+ SVR? - double svm_get_svr_probability(const struct svm_model *model);
470
+ SVR? - double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates);
471
+ Model holds reference to this, so when to use it?
472
+ void svm_destroy_param(struct svm_parameter *param);
473
+ SVR? - int svm_check_probability_model(const struct svm_model *model);
474
+ */
475
+
476
+ mKernelType = rb_define_module_under(mLibsvm, "KernelType");
477
+ rb_define_const(mKernelType, "LINEAR", INT2NUM(LINEAR));
478
+ rb_define_const(mKernelType, "POLY", INT2NUM(POLY));
479
+ rb_define_const(mKernelType, "RBF", INT2NUM(RBF));
480
+ rb_define_const(mKernelType, "SIGMOID", INT2NUM(SIGMOID));
481
+ rb_define_const(mKernelType, "PRECOMPUTED", INT2NUM(PRECOMPUTED));
482
+
483
+ mSvmType = rb_define_module_under(mLibsvm,"SvmType");
484
+ rb_define_const(mSvmType, "C_SVC", INT2NUM(C_SVC));
485
+ rb_define_const(mSvmType, "NU_SVC", INT2NUM(NU_SVC));
486
+ rb_define_const(mSvmType, "ONE_CLASS", INT2NUM(ONE_CLASS));
487
+ rb_define_const(mSvmType, "EPSILON_SVR", INT2NUM(EPSILON_SVR));
488
+ rb_define_const(mSvmType, "NU_SVR", INT2NUM(NU_SVR));
489
+ }