rb-libsvm 1.0.1

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/lib/libsvm.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'rb-libsvm/version'
2
+ require 'rb-libsvm/libsvm'
3
+
4
+ module Libsvm
5
+
6
+ module CoreExtensions
7
+ module Collection
8
+ def to_example
9
+ Node.features(self)
10
+ end
11
+ end
12
+ end
13
+
14
+ class Node
15
+
16
+ class << self
17
+
18
+ def features(*vargs)
19
+ array_of_nodes = []
20
+ if vargs.size == 1
21
+ if vargs.first.class == Array
22
+ vargs.first.each_with_index do |value, index|
23
+ array_of_nodes << Node.new(index.to_i, value.to_f)
24
+ end
25
+ elsif vargs.first.class == Hash
26
+ vargs.first.each do |index, value|
27
+ array_of_nodes << Node.new(index.to_i, value.to_f)
28
+ end
29
+ else
30
+ raise(ArgumentError.new("Node features need to be a Hash, Array or Floats"))
31
+ end
32
+ else
33
+ vargs.each_with_index do |value, index|
34
+ array_of_nodes << Node.new(index.to_i, value.to_f)
35
+ end
36
+ end
37
+ array_of_nodes
38
+ end
39
+
40
+ def [](index, value)
41
+ new(index, value)
42
+ end
43
+ end
44
+
45
+ def initialize(index=0, value=0.0)
46
+ self.index = index
47
+ self.value = value
48
+ end
49
+
50
+ def ==(other)
51
+ index == other.index && value == other.value
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+
58
+ class Hash
59
+ include Libsvm::CoreExtensions::Collection
60
+ end
61
+ class Array
62
+ include Libsvm::CoreExtensions::Collection
63
+ end
@@ -0,0 +1,3 @@
1
+ module Libsvm
2
+ VERSION = "1.0.1"
3
+ end
data/rb-libsvm.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'rb-libsvm/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rb-libsvm"
7
+ s.version = Libsvm::VERSION
8
+ s.authors = ["C. Florian Ebeling", "Rimas Silkaitis"]
9
+ s.email = ["neovintage@gmail.com"]
10
+ s.homepage = "https://github.com/febeling/rb-libsvm"
11
+ s.summary = %q{Ruby language bindings for LIBSVM}
12
+ s.description = %q{libsvm and ruby without using swig}
13
+
14
+ s.rubyforge_project = "rb-libsvm"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rake-compiler"
23
+ s.add_development_dependency "rspec", "2.7.0"
24
+
25
+ s.extensions << 'ext/rb-libsvm/extconf.rb'
26
+ end
27
+
@@ -0,0 +1,95 @@
1
+ require "spec_helper"
2
+
3
+ module ModelSpecHelper
4
+
5
+ def create_example
6
+ Node.features(0.2, 0.3, 0.4, 0.5)
7
+ end
8
+
9
+ def create_problem
10
+ problem = Problem.new
11
+ features = [Node.features([0.2,0.3,0.4,0.4]),
12
+ Node.features([0.1,0.5,0.1,0.9]),
13
+ Node.features([0.2,0.2,0.6,0.5]),
14
+ Node.features([0.3,0.1,0.5,0.9])]
15
+ problem.set_examples([1,2,1,2], features)
16
+ problem
17
+ end
18
+
19
+ def create_parameter
20
+ parameter = SvmParameter.new
21
+ parameter.cache_size = 50 # mb
22
+ parameter.eps = 0.01
23
+ parameter.c = 10
24
+ parameter
25
+ end
26
+
27
+ end
28
+
29
+ describe "The Libsvm::Model class interface" do
30
+ include ModelSpecHelper
31
+
32
+ before(:each) do
33
+ @problem = create_problem
34
+ @parameter = create_parameter
35
+ end
36
+
37
+ it "results from training on a problem under a certain parameter set" do
38
+ model = Model.train(@problem,@parameter)
39
+ model.should_not be_nil
40
+ end
41
+
42
+ it "can do cross-validation" do
43
+ labels = Model.cross_validation(@problem, @parameter, fold=2)
44
+ labels.should == [anything, anything, anything, anything]
45
+ end
46
+ end
47
+
48
+ describe "A saved model" do
49
+ include ModelSpecHelper
50
+
51
+ before(:each) do
52
+ @filename = "svm_model.model"
53
+ model = Model.train(create_problem, create_parameter)
54
+ model.save(@filename)
55
+ end
56
+
57
+ it "can be loaded" do
58
+ model = Model.load(@filename)
59
+ model.should_not be_nil
60
+ end
61
+
62
+ after(:each) do
63
+ File.delete(@filename) rescue nil
64
+ end
65
+ end
66
+
67
+ describe "An Libsvm model" do
68
+ include ModelSpecHelper
69
+
70
+ before(:each) do
71
+ @problem = create_problem
72
+ @parameter = create_parameter
73
+ @model = Model.train(@problem, @parameter)
74
+ end
75
+
76
+ it "can be saved to a file" do
77
+ file_path = "svm_model.model"
78
+ @model.save(file_path)
79
+ File.exist?(file_path).should be_true
80
+ end
81
+
82
+ it "can be asked for it's svm_type" do
83
+ @model.svm_type.should == SvmType::C_SVC
84
+ end
85
+
86
+ it "can be asked for it's number of classes (aka. labels)" do
87
+ @model.classes.should == 2
88
+ end
89
+
90
+ it "can predict" do
91
+ prediction = @model.predict(create_example)
92
+ prediction.should_not be_nil
93
+ end
94
+ end
95
+
data/spec/node_spec.rb ADDED
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+
3
+ describe "construction of a Node" do
4
+ it "using the properties" do
5
+ n = Node.new
6
+ n.index = 11
7
+ n.value = 0.11
8
+ n.index.should == 11
9
+ n.value.should be_within(0.0001).of(0.11)
10
+ end
11
+
12
+ it "using the :[] method" do
13
+ n = Node[12, 0.12]
14
+ n.index.should == 12
15
+ n.value.should be_within(0.00001).of(0.12)
16
+ end
17
+
18
+ it "using the constructor parameters" do
19
+ n = Node.new(14, 0.14)
20
+ n.index.should == 14
21
+ n.value.should be_within(0.0001).of(0.14)
22
+ end
23
+ end
24
+
25
+ describe "A Node" do
26
+ before do
27
+ @node = Node.new
28
+ end
29
+
30
+ it "can be created" do
31
+ @node.should_not be_nil
32
+ end
33
+
34
+ it "does not segfault on setting properties" do
35
+ @node.index = 99
36
+ @node.index.should == 99
37
+ @node.value = 3.141
38
+ @node.value.should be_within(0.00001).of(3.141)
39
+ end
40
+
41
+ it "has inited properties" do
42
+ @node.index.should == 0
43
+ @node.value.should be_within(0.00001).of(0)
44
+ end
45
+
46
+ it "class can create nodes from an array" do
47
+ ary = Node.features([0.1, 0.2, 0.3, 0.4, 0.5])
48
+ ary.map {|n| n.class.should == Node}
49
+ ary.map {|n| n.value }.should == [0.1, 0.2, 0.3, 0.4, 0.5]
50
+ end
51
+
52
+ it "class can create nodes from variable parameters" do
53
+ ary = Node.features(0.1, 0.2, 0.3, 0.4, 0.5)
54
+ ary.map {|n| Node.should === n }
55
+ ary.map {|n| n.value }.should == [0.1, 0.2, 0.3, 0.4, 0.5]
56
+ end
57
+
58
+ it "class can create nodes from hash" do
59
+ ary = Node.features(3=>0.3, 5=>0.5, 6=>0.6, 10=>1.0)
60
+ ary.map {|n| n.class.should == Node}
61
+ ary.map {|n| n.value }.sort.should == [0.3, 0.5, 0.6, 1.0]
62
+ ary.map {|n| n.index }.sort.should == [3, 5, 6, 10]
63
+ end
64
+
65
+ it "implements a value-like equality, not identity-notion" do
66
+ Node[1, 0.1].should == Node[1, 0.1]
67
+ end
68
+ end
@@ -0,0 +1,76 @@
1
+ require "spec_helper"
2
+
3
+ describe "A Parameter has accessors for" do
4
+ before do
5
+ @p = Libsvm::SvmParameter.new
6
+ end
7
+ it "int svm_type" do
8
+ SvmType::C_SVC.should == 0
9
+ @p.svm_type = SvmType::C_SVC
10
+ @p.svm_type.should == SvmType::C_SVC
11
+ end
12
+
13
+ it "int kernel_type" do
14
+ KernelType::RBF.should == 2
15
+ @p.kernel_type = KernelType::RBF
16
+ @p.kernel_type.should == KernelType::RBF
17
+ end
18
+
19
+ it "int degree" do
20
+ @p.degree = 99
21
+ @p.degree.should == 99
22
+ end
23
+
24
+ it "double gamma" do
25
+ @p.gamma = 0.33
26
+ @p.gamma.should == 0.33
27
+ end
28
+
29
+ it "double coef0" do
30
+ @p.coef0 = 0.99
31
+ @p.coef0.should == 0.99
32
+ end
33
+
34
+ it "double cache_size" do
35
+ @p.cache_size = 0.77
36
+ @p.cache_size.should == 0.77
37
+ end
38
+
39
+ it "double eps" do
40
+ @p.eps = 0.111
41
+ @p.eps.should == 0.111
42
+ @p.eps = 0.112
43
+ @p.eps.should == 0.112
44
+ end
45
+
46
+ it "double C" do
47
+ @p.c = 3.141
48
+ @p.c.should == 3.141
49
+ end
50
+
51
+ it "can set and read weights (weight, weight_label, nr_weight members from struct)" do
52
+ @p.label_weights = {1=> 1.2, 3=>0.2, 5=>0.888}
53
+ @p.label_weights.should == {1=> 1.2, 3=>0.2, 5=>0.888}
54
+ end
55
+
56
+
57
+ it "double nu" do
58
+ @p.nu = 1.1
59
+ @p.nu.should == 1.1
60
+ end
61
+
62
+ it "double p" do
63
+ @p.p = 0.123
64
+ @p.p.should == 0.123
65
+ end
66
+
67
+ it "int shrinking" do
68
+ @p.shrinking = 22
69
+ @p.shrinking.should == 22
70
+ end
71
+
72
+ it "int probability" do
73
+ @p.probability = 35
74
+ @p.probability.should == 35
75
+ end
76
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe "A Problem" do
4
+ before(:each) do
5
+ @problem = Problem.new
6
+ @features = [ Node.features(0.2,0.3,0.4,0.4),
7
+ Node.features(0.1,0.5,0.1,0.9),
8
+ Node.features(0.2,0.2,0.6,0.5),
9
+ Node.features(0.3,0.1,0.5,0.9) ]
10
+ end
11
+
12
+ it "examples get stored and retrieved" do
13
+ @problem.set_examples([1,2,1,2], @features)
14
+ labels, examples = @problem.examples
15
+ labels.size.should == 4
16
+ examples.size.should == 4
17
+ examples.map {|x|x.size}.should == [4,4,4,4]
18
+ examples.first.map {|node| node.index}.should == [0,1,2,3]
19
+ examples.first.map {|node| node.value}.should == [0.2,0.3,0.4,0.4]
20
+ end
21
+
22
+ it "can be populated" do
23
+ examples = [Node.features(0.2,0.3,0.4,0.4),
24
+ Node.features(0.1,0.5,0.1,0.9),
25
+ Node.features(0.2,0.2,0.6,0.5),
26
+ Node.features(0.3,0.1,0.5,0.9)]
27
+ @problem.set_examples([1,2,1,2], examples)
28
+ end
29
+
30
+ it "can be set twice over" do
31
+ features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
32
+ @problem.set_examples([1,2], features)
33
+ features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
34
+ @problem.set_examples([8,2], features)
35
+ end
36
+
37
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'libsvm'
4
+
5
+ include Libsvm
6
+
7
+ RSpec.configure do |config|
8
+ config.color_enabled = true
9
+ # config.formatter = 'documentation'
10
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Basic usage" do
4
+ before do
5
+ @problem = Problem.new
6
+ @parameter = SvmParameter.new
7
+ @parameter.cache_size = 1 # mb
8
+
9
+ # "eps is the stopping criterion (we usually use 0.00001 in nu-SVC,
10
+ # 0.001 in others)." (from README)
11
+ @parameter.eps = 0.001
12
+
13
+ @parameter.c = 10
14
+ end
15
+
16
+ it "has a nice API" do
17
+ example = {11 => 0.11, 21 => 0.21, 101 => 0.99 }.to_example
18
+ example.should == Node.features({11 => 0.11, 21 => 0.21, 101 => 0.99 })
19
+ end
20
+
21
+ it "is as in [PCI,217]" do
22
+ examples = [ [1,0,1], [-1,0,-1] ].map {|ary| Node.features(ary) }
23
+ labels = [1, -1]
24
+ @problem.set_examples(labels, examples)
25
+
26
+ model = Model.train(@problem, @parameter)
27
+
28
+ pred = model.predict(Node.features(1, 1, 1))
29
+ pred.should == 1.0
30
+
31
+ pred = model.predict(Node.features(-1, 1, -1))
32
+ pred.should == -1.0
33
+
34
+ pred = model.predict(Node.features(-1, 55, -1))
35
+ pred.should == -1.0
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rb-libsvm
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - C. Florian Ebeling
9
+ - Rimas Silkaitis
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2011-11-07 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake-compiler
17
+ requirement: &2157654260 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *2157654260
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ requirement: &2157653760 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - =
32
+ - !ruby/object:Gem::Version
33
+ version: 2.7.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *2157653760
37
+ description: libsvm and ruby without using swig
38
+ email:
39
+ - neovintage@gmail.com
40
+ executables: []
41
+ extensions:
42
+ - ext/rb-libsvm/extconf.rb
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .gitignore
46
+ - .rvmrc
47
+ - Gemfile
48
+ - Gemfile.lock
49
+ - MIT-LICENSE
50
+ - README.textile
51
+ - Rakefile
52
+ - ext/rb-libsvm/extconf.rb
53
+ - ext/rb-libsvm/libsvm.c
54
+ - ext/rb-libsvm/ruby-ext.h
55
+ - ext/rb-libsvm/svm.cpp
56
+ - ext/rb-libsvm/svm.h
57
+ - ferret_valgrind.supp
58
+ - lib/libsvm.rb
59
+ - lib/rb-libsvm/version.rb
60
+ - rb-libsvm.gemspec
61
+ - spec/model_spec.rb
62
+ - spec/node_spec.rb
63
+ - spec/parameter_spec.rb
64
+ - spec/problem_spec.rb
65
+ - spec/spec_helper.rb
66
+ - spec/usage_spec.rb
67
+ homepage: https://github.com/febeling/rb-libsvm
68
+ licenses: []
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ requirements: []
86
+ rubyforge_project: rb-libsvm
87
+ rubygems_version: 1.8.9
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Ruby language bindings for LIBSVM
91
+ test_files:
92
+ - spec/model_spec.rb
93
+ - spec/node_spec.rb
94
+ - spec/parameter_spec.rb
95
+ - spec/problem_spec.rb
96
+ - spec/spec_helper.rb
97
+ - spec/usage_spec.rb