hexgnu-libsvm-ruby-swig 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/hex-svm.rb CHANGED
@@ -1,7 +1,7 @@
1
- require File.join(File.dirname(__FILE__), 'libsvm')
1
+ require File.join(File.dirname(__FILE__), '../ext/libsvm')
2
2
  include Libsvm
3
3
 
4
- %w[./libsvm/problem ./libsvm/model ./libsvm/parameter].each do |r|
4
+ %w[libsvm/problem libsvm/model libsvm/parameter].each do |r|
5
5
  require File.join(File.dirname(__FILE__), r)
6
6
  end
7
7
 
@@ -0,0 +1,140 @@
1
+ module SVM
2
+ class Model
3
+ attr_accessor :model
4
+
5
+ def initialize(arg1,arg2=nil)
6
+ if arg2 == nil
7
+ # create model from file
8
+ filename = arg1
9
+ @model = svm_load_model(filename)
10
+ else
11
+ # create model from problem and parameter
12
+ prob,param = arg1,arg2
13
+ @prob = prob
14
+ if param.gamma == 0
15
+ param.gamma = 1.0/prob.maxlen
16
+ end
17
+ msg = svm_check_parameter(prob.prob,param.param)
18
+ raise ::ArgumentError, msg if msg
19
+ @model = svm_train(prob.prob,param.param)
20
+ end
21
+
22
+ #setup some classwide variables
23
+ @nr_class = svm_get_nr_class(@model)
24
+ @svm_type = svm_get_svm_type(@model)
25
+ #create labels(classes)
26
+ intarr = new_int(@nr_class)
27
+ svm_get_labels(@model,intarr)
28
+ @labels = _int_array_to_list(intarr, @nr_class)
29
+ delete_int(intarr)
30
+ #check if valid probability model
31
+ @probability = svm_check_probability_model(@model)
32
+
33
+ end
34
+
35
+ def predict(x)
36
+ data = SVM.convert_to_svm_node_array(x)
37
+ ret = svm_predict(@model,data)
38
+ svm_node_array_destroy(data)
39
+ return ret
40
+ end
41
+
42
+
43
+ def get_nr_class
44
+ return @nr_class
45
+ end
46
+
47
+ def get_labels
48
+ if @svm_type == NU_SVR or @svm_type == EPSILON_SVR or @svm_type == ONE_CLASS
49
+ raise TypeError, "Unable to get label from a SVR/ONE_CLASS model"
50
+ end
51
+ return @labels
52
+ end
53
+
54
+ def predict_values_raw(x)
55
+ #convert x into svm_node, allocate a double array for return
56
+ n = (@nr_class*(@nr_class-1)/2).floor
57
+ data = _convert_to_svm_node_array(x)
58
+ dblarr = new_double(n)
59
+ svm_predict_values(@model, data, dblarr)
60
+ ret = _double_array_to_list(dblarr, n)
61
+ delete_double(dblarr)
62
+ svm_node_array_destroy(data)
63
+ return ret
64
+ end
65
+
66
+ def predict_values(x)
67
+ v=predict_values_raw(x)
68
+ #puts v.inspect
69
+ if @svm_type == NU_SVR or @svm_type == EPSILON_SVR or @svm_type == ONE_CLASS
70
+ return v[0]
71
+ else #self.svm_type == C_SVC or self.svm_type == NU_SVC
72
+ count = 0
73
+
74
+ # create a width x height array
75
+ width = @labels.size
76
+ height = @labels.size
77
+ d = Array.new(width)
78
+ d.map! { Array.new(height) }
79
+
80
+ for i in (0..@labels.size-1)
81
+ for j in (i+1..@labels.size-1)
82
+ d[@labels[i]][@labels[j]] = v[count]
83
+ d[@labels[j]][@labels[i]] = -v[count]
84
+ count += 1
85
+ end
86
+ end
87
+ return d
88
+ end
89
+ end
90
+
91
+ def predict_probability(x)
92
+ #c code will do nothing on wrong type, so we have to check ourself
93
+ if @svm_type == NU_SVR or @svm_type == EPSILON_SVR
94
+ raise TypeError, "call get_svr_probability or get_svr_pdf for probability output of regression"
95
+ elsif @svm_type == ONE_CLASS
96
+ raise TypeError, "probability not supported yet for one-class problem"
97
+ end
98
+ #only C_SVC,NU_SVC goes in
99
+ if not @probability
100
+ raise TypeError, "model does not support probabiliy estimates"
101
+ end
102
+
103
+ #convert x into svm_node, alloc a double array to receive probabilities
104
+ data = _convert_to_svm_node_array(x)
105
+ dblarr = new_double(@nr_class)
106
+ pred = svm_predict_probability(@model, data, dblarr)
107
+ pv = _double_array_to_list(dblarr, @nr_class)
108
+ delete_double(dblarr)
109
+ svm_node_array_destroy(data)
110
+ p = {}
111
+ for i in (0..@labels.size-1)
112
+ p[@labels[i]] = pv[i]
113
+ end
114
+ return pred, p
115
+ end
116
+
117
+ def get_svr_probability
118
+ #leave the Error checking to svm.cpp code
119
+ ret = svm_get_svr_probability(@model)
120
+ if ret == 0
121
+ raise TypeError, "not a regression model or probability information not available"
122
+ end
123
+ return ret
124
+ end
125
+
126
+ def get_svr_pdf
127
+ #get_svr_probability will handle error checking
128
+ sigma = get_svr_probability()
129
+ return Proc.new{|z| exp(-z.abs/sigma)/(2*sigma)} # TODO: verify this works
130
+ end
131
+
132
+ def save(filename)
133
+ svm_save_model(filename,@model)
134
+ end
135
+
136
+ def destroy
137
+ svm_destroy_model(@model)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,56 @@
1
+ module SVM
2
+ class Parameter
3
+ attr_accessor :param
4
+
5
+ def initialize(*args)
6
+ @param = Svm_parameter.new
7
+ @param.svm_type = C_SVC
8
+ @param.kernel_type = RBF
9
+ @param.degree = 3
10
+ @param.gamma = 0 # 1/k
11
+ @param.coef0 = 0
12
+ @param.nu = 0.5
13
+ @param.cache_size = 100
14
+ @param.C = 1
15
+ @param.eps = 1e-3
16
+ @param.p = 0.1
17
+ @param.shrinking = 1
18
+ @param.nr_weight = 0
19
+ #@param.weight_label = _int_array([])
20
+ #@param.weight = _double_array([])
21
+ @param.probability = 0
22
+
23
+ args[0].each {|k,v|
24
+ self.send("#{k}=",v)
25
+ } if !args[0].nil?
26
+ end
27
+
28
+ def method_missing(m, *args)
29
+ if m.to_s == 'weight_label='
30
+ @weight_label_len = args[0].size
31
+ pargs = _int_array(args[0])
32
+ _free_int_array(@param.weight_label)
33
+ elsif m.to_s == 'weight='
34
+ @weight_len = args[0].size
35
+ pargs = _double_array(args[0])
36
+ _free_double_array(@param.weight)
37
+ else
38
+ pargs = args[0]
39
+ end
40
+
41
+ if m.to_s.index('=')
42
+ @param.send("#{m}",pargs)
43
+ else
44
+ @param.send("#{m}")
45
+ end
46
+
47
+ end
48
+
49
+ def destroy
50
+ _free_int_array(@param.weight_label)
51
+ _free_double_array(@param.weight)
52
+ #delete_svm_parameter(@param)
53
+ @param = nil
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,44 @@
1
+ module SVM
2
+ class Problem
3
+ attr_accessor :prob, :maxlen, :size
4
+
5
+ def initialize(y, *x)
6
+ #assert y.size == x.size
7
+ @prob = prob = Svm_problem.new
8
+ @size = size = y.size
9
+
10
+ @y_array = y_array = new_double(size)
11
+ y.each_with_index do |label, i|
12
+ double_setitem(@y_array, i, label)
13
+ end
14
+
15
+ @x_matrix = x_matrix = svm_node_matrix(size)
16
+ @data = []
17
+ @maxlen = 0
18
+ x.each_with_index do |row, i|
19
+ #data = _convert_to_svm_node_array(row)
20
+ data = SVM.convert_to_svm_node_array(row)
21
+ @data << data
22
+ svm_node_matrix_set(x_matrix, i, data)
23
+ @maxlen = [@maxlen, row.size].max
24
+ end
25
+
26
+ prob.l = size
27
+ prob.y = y_array
28
+ prob.x = x_matrix
29
+ end
30
+
31
+ def inspect
32
+ return "Problem: size = #{size}"
33
+ end
34
+
35
+ def destroy
36
+ delete_svm_problem(@prob)
37
+ delete_double(@y_array)
38
+ for i in (0..size-1)
39
+ svm_node_array_destroy(@data[i])
40
+ end
41
+ svm_node_matrix_destroy(@x_matrix)
42
+ end
43
+ end
44
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexgnu-libsvm-ruby-swig
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 31
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 1
10
- version: 0.1.1
9
+ - 2
10
+ version: 0.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tom Zeng
@@ -53,6 +53,9 @@ files:
53
53
  - README.rdoc
54
54
  - Rakefile
55
55
  - lib/hex-svm.rb
56
+ - lib/libsvm/model.rb
57
+ - lib/libsvm/parameter.rb
58
+ - lib/libsvm/problem.rb
56
59
  - ext/libsvm_wrap.cxx
57
60
  - ext/svm.cpp
58
61
  - ext/svm.h