libsvmffi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2011 by Robert Berry
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,37 @@
1
+ == Introduction
2
+
3
+ This is alpha grade software.
4
+
5
+ Under development. But simple use cases may be worth checking out.
6
+
7
+ http://www.csie.ntu.edu.tw/~cjlin/libsvm/
8
+
9
+ libsvm version 310
10
+
11
+
12
+ == Installation
13
+
14
+ 1. download (see url above)
15
+ 2. make lib
16
+ 3. place .so in load path
17
+
18
+ gem install libsvmffi
19
+
20
+ == Usage
21
+
22
+ #> require 'libsvmffi'
23
+
24
+ #> m = Libsvmffi::Model.new
25
+ #> m.add :good, {:height => 1, :width => 1, :length => 1}
26
+ #> m.add :bad, {:height => 10, :width => 3, :length => 6}
27
+ #> m.train
28
+
29
+ #> m.classify({:height => 1, :width => 1.1, :length => 1})
30
+ #=> :good
31
+
32
+
33
+ == Source Code
34
+
35
+ https://github.com/bdigital/libsvmffi
36
+
37
+ Assistance developing is welcome.
@@ -0,0 +1,156 @@
1
+ module Libsvmffi
2
+ #
3
+ #
4
+ #
5
+ class Model
6
+
7
+ attr_accessor :parameters, :problem, :svm_model
8
+ attr_accessor :examples
9
+ attr_accessor :labels, :features
10
+ attr_accessor :elements, :x_space
11
+
12
+ attr_accessor :nodes, :x
13
+
14
+ def initialize(options = {})
15
+
16
+ @parameters = Parameters.new
17
+
18
+ # TODO merge defaults options hash.
19
+ @parameters[:svm_type] = C_SVC;
20
+ @parameters[:kernel_type] = RBF;
21
+ @parameters[:degree] = 3;
22
+ @parameters[:gamma] = 0; # 1/num_features
23
+ @parameters[:coef0] = 0;
24
+ @parameters[:nu] = 0.5;
25
+ @parameters[:cache_size] = 100;
26
+ @parameters[:C] = 1;
27
+ @parameters[:eps] = 0.001;
28
+ @parameters[:p] = 0.1;
29
+ @parameters[:shrinking] = 1;
30
+ @parameters[:probability] = 0;
31
+ @parameters[:nr_weight] = 0;
32
+ @parameters[:weight_label] = nil;
33
+ @parameters[:weight] = nil;
34
+
35
+ @elements = 0
36
+ @examples, @labels, @features = [], [], []
37
+
38
+ @nodes = []
39
+ end
40
+
41
+ #
42
+ # Adds an example which will be used upon trainining
43
+ #
44
+ def add(label, features)
45
+ @labels.push label unless @labels.include? label
46
+ indexed_features = {}
47
+ features.each do |k, v|
48
+ @features.push k unless @features.include? k
49
+ indexed_features[@features.index(k)] = v
50
+ end
51
+
52
+ @examples.push({@labels.index(label) => indexed_features})
53
+
54
+ @elements += features.length + 1 # also -1 terminator, see libsvm readme.
55
+ end
56
+
57
+ #
58
+ # Build libsvm model
59
+ #
60
+ def train
61
+
62
+ @problem = Problem.new
63
+ @problem[:l] = @examples.length
64
+ @problem[:y] = FFI::MemoryPointer.new(:double, @problem[:l])
65
+ @x = FFI::MemoryPointer.new(:pointer, @problem[:l])
66
+ @problem[:x] = x.address #FFI::MemoryPointer.new(:pointer, @problem[:l])
67
+ @x_space = FFI::MemoryPointer.new(Node, @elements)
68
+
69
+ y = @examples.map {|e| e.keys.first}
70
+ @problem[:y].put_array_of_double 0, y
71
+
72
+ i = 0
73
+ space_index = 0
74
+ examples.each do |ex| #TODO clean up this hash structure
75
+ ex.each do |e|
76
+ @x[i].write_pointer @x_space[space_index]
77
+ i += 1
78
+
79
+ features = e.last.merge({-1 => 0}) #terminator
80
+ features.each do |k, v|
81
+ n = Node.new @x_space[space_index]
82
+ n[:index] = k
83
+ n[:value] = v
84
+ space_index += 1
85
+
86
+ @nodes.push n
87
+ end
88
+ end
89
+ end
90
+
91
+ @parameters[:gamma] = 1 / @features.length.to_f
92
+
93
+ @svm_model = Libsvmffi.svm_train @problem.pointer, @parameters.pointer
94
+
95
+ end
96
+
97
+ #
98
+ #
99
+ #
100
+ def classify(features)
101
+ nodes = fton(features)
102
+ label_index = Libsvmffi.svm_predict @svm_model, nodes
103
+ @labels[label_index.to_i]
104
+ end
105
+
106
+
107
+ #
108
+ # Save to file
109
+ #
110
+ def save(filename = "model.out")
111
+ Libsvmffi.svm_save_model FFI::MemoryPointer.from_string(filename), @svm_model
112
+ end
113
+
114
+ #
115
+ # Add training examples from a libsvm training format file
116
+ #
117
+ def add_from_file(filename)
118
+ f = File.open filename, 'r'
119
+ f.lines.each do |l|
120
+ tokens = l.split " "
121
+ label = tokens.shift
122
+ features = {}
123
+ tokens.each do |t|
124
+ index, value = t.split(":")
125
+ features[index.to_i] = value.to_f
126
+ end
127
+ self.add label, features
128
+ end
129
+ end
130
+
131
+ #
132
+ # Features to array of node struct (currently factored just for debugging, only used in predict)
133
+ #
134
+ def fton(features)
135
+
136
+ indexed_features = {}
137
+ features.each do |k, v|
138
+ indexed_features[@features.index(k)] = v unless !@features.include? k
139
+ end
140
+
141
+ nodes = FFI::MemoryPointer.new(Node, indexed_features.length + 1)
142
+ indexed_features = indexed_features.merge({-1 => 0}) #terminator
143
+ i = 0
144
+ indexed_features.each do |k, v|
145
+ n = Node.new nodes[i]
146
+ n[:index] = k
147
+ n[:value] = v
148
+ i += 1
149
+ end
150
+
151
+ return nodes
152
+
153
+ end
154
+
155
+ end
156
+ end
@@ -0,0 +1,6 @@
1
+ module Libsvmffi
2
+ class Node < FFI::Struct
3
+ layout :index, :int,
4
+ :value, :double
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ module Libsvmffi
2
+ class Parameters < FFI::Struct
3
+ layout :svm_type, :int,
4
+ :kernel_type, :int,
5
+ :degree, :int, # for poly
6
+ :gamma, :double, # for poly/rbf/sigmoid
7
+ :coef0, :double, # for poly/sigmoid
8
+ :cache_size, :double , # in MB
9
+ :eps, :double, # stopping criteria
10
+ :C, :double, # for C_SVC, EPSILON_SVR and NU_SVR
11
+ :nr_weight, :int, # for C_SVC
12
+ :weight_label, :pointer, # int for C_SVC
13
+ :weight, :pointer, # double for C_SVC
14
+ :nu, :double, # for NU_SVC, ONE_CLASS, and NU_SVR
15
+ :p, :double, # for EPSILON_SVR
16
+ :shrinking, :int, # use the shrinking heuristics
17
+ :probability, :int # do probability estimates
18
+ end
19
+ end
@@ -0,0 +1,7 @@
1
+ module Libsvmffi
2
+ class Problem < FFI::Struct
3
+ layout :l, :int,
4
+ :y, :pointer,
5
+ :x, :pointer # svm_node
6
+ end
7
+ end
data/lib/libsvmffi.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'ffi'
2
+ require 'libsvmffi/problem'
3
+ require 'libsvmffi/parameters'
4
+ require 'libsvmffi/node'
5
+ require 'libsvmffi/model'
6
+
7
+
8
+ module Libsvmffi
9
+
10
+ extend FFI::Library
11
+ ffi_lib 'svm' # REVIEW
12
+
13
+ C_SVC, NU_SVC, ONE_CLASS, EPSILON_SVR, NU_SVR = 0, 1, 2, 3, 4 # SVM Type
14
+ LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED = 0, 1, 2, 3, 4 # Kernel Type
15
+
16
+ attach_function 'svm_train', [:pointer, :pointer], :pointer
17
+
18
+ attach_function 'svm_cross_validation', [:pointer, :pointer, :int, :pointer], :void
19
+
20
+ attach_function 'svm_save_model', [:pointer, :pointer], :int
21
+ attach_function 'svm_load_model', [:pointer], :pointer
22
+
23
+ attach_function 'svm_get_svm_type', [:pointer], :int
24
+ attach_function 'svm_get_nr_class', [:pointer], :int
25
+ attach_function 'svm_get_labels', [:pointer, :pointer], :void
26
+ attach_function 'svm_get_svr_probability', [:pointer], :double
27
+
28
+ attach_function 'svm_predict', [:pointer, :pointer], :double
29
+ attach_function 'svm_predict_values', [:pointer, :pointer, :pointer], :void
30
+ attach_function 'svm_predict_probability', [:pointer, :pointer, :pointer], :double
31
+
32
+ attach_function 'svm_free_and_destroy_model', [:pointer], :void
33
+ attach_function 'svm_destroy_param', [:pointer], :void
34
+
35
+ attach_function 'svm_check_parameter', [:pointer, :pointer], :pointer
36
+ attach_function 'svm_check_probability_model', [:pointer], :int
37
+
38
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: libsvmffi
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Robert Berry
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-05-01 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: SVM operations.
17
+ email: berrydigital@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/libsvmffi.rb
26
+ - lib/libsvmffi/problem.rb
27
+ - lib/libsvmffi/node.rb
28
+ - lib/libsvmffi/parameters.rb
29
+ - lib/libsvmffi/model.rb
30
+ - README
31
+ - LICENSE
32
+ homepage: http://github.com/bdigital/libsvmffi
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ requirements: []
53
+
54
+ rubyforge_project:
55
+ rubygems_version: 1.7.2
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: Libsvm ffi bindings
59
+ test_files: []
60
+
61
+ has_rdoc: false