rb-libsvm 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50ef30c4d3cfe8e3785f6c408a48a34b5ff585b2
4
- data.tar.gz: 80bbaef88fe9e9738b61fde4804c592e4e053367
3
+ metadata.gz: 430498716ebb529469fa73ece0ffe044bac7c04a
4
+ data.tar.gz: d1effb4c07f3fa77418991d79ddf58ed5887ee8c
5
5
  SHA512:
6
- metadata.gz: 1b8a9ff101bdc72026634f744583f858f1963b7241a18068a22fdd3ac0d84413937ed23093a34507a10f42052e9a73b79c396e85bf6e4b542c8c6c96249ea79a
7
- data.tar.gz: 13de67e9c95836e814cc88077f8e9c59977f27dd9fa4e4171591c60f93059216046676a4ecc933ab9e37a47fb2e6b795e1aed45ccf82e0b0a8ef29bb8abd3ebb
6
+ metadata.gz: 6546735dc65a8bff5215960cec78755eab7ddd4ecffe047bd1e4a6db485bfbcb970fed54b61581b259478b0451cbcca21b936ed2bc01f3c48af32240bd0be553
7
+ data.tar.gz: 07c833fd03503d38e4b9a5c0a6ac6958e32b3ffcf8983f6ffe8663dd1914d9de9ee164f8725373d3957b9e264708783811929d49d69fce5bbfa461560d36400d
data/.travis.yml CHANGED
@@ -4,5 +4,4 @@ rvm:
4
4
  - 1.9.3
5
5
  - 2.0.0
6
6
  - 2.1.1
7
- - rbx
8
7
  - ruby-head
data/README.md CHANGED
@@ -9,7 +9,11 @@ popular free implementation of it, written by Chih-Chung Chang and
9
9
  Chih-Jen Lin, of National Taiwan University, Taipei. See the book ["Programming
10
10
  Collective Intelligence,"](http://books.google.com/books?id=fEsZ3Ey-Hq4C) among others, for a usage example.
11
11
 
12
- Note: There exist two other Ruby bindings for LIBSVM. One is named
12
+ There is a JRuby implementation of this gem named
13
+ [jrb-libsvm](https://github.com/sch1zo/jrb-libsvm) by
14
+ [Andreas Eger](https://github.com/sch1zo).
15
+
16
+ Note: There exist some other Ruby bindings for LIBSVM. One is named
13
17
  [Ruby SVM][ruby-svm], written by Rudi Cilibrasi. The other, more
14
18
  actively developed one is [libsvm-ruby-swig][svmrubyswig] by Tom Zeng,
15
19
  which is built using SWIG.
@@ -77,9 +81,6 @@ gem 'rb-libsvm', require: 'libsvm'
77
81
  This is because the loadable name (`libsvm`) is different from the
78
82
  gem's name (`rb-libsvm`).
79
83
 
80
- There is a JRuby variant of this gem named
81
- [jrb-libsvm](https://github.com/sch1zo/jrb-libsvm) by Andreas Eger.
82
-
83
84
  ## Author
84
85
 
85
86
  Written by [C. Florian Ebeling](https://github.com/febeling).
data/examples/iris.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'libsvm'
2
+ require 'set'
3
+
4
+ include Libsvm
5
+
6
+ if ARGV.size != 1
7
+ puts "Usage: ruby examples/iris.rb iris.data"
8
+ puts
9
+ puts "Needs the Iris data set"
10
+ puts " http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
11
+ exit 1
12
+ end
13
+
14
+ # Read data
15
+ lines = IO.readlines(ARGV.shift).map(&:strip).shuffle
16
+ instances = lines.map { |line| line.split(',') }
17
+
18
+ # Create array of feature nodes per instance
19
+ examples = instances.map { |instance|
20
+ sepal_length, sepal_width, petal_length, petal_width = *instance[0..3].map(&:to_f)
21
+ Node.features(sepal_length, sepal_width, petal_length, petal_width)
22
+ }
23
+
24
+ # Pluck class property (Iris name)
25
+ label_names = instances.map(&:last)
26
+
27
+ # Deduplicate and assign indexes
28
+ label_indexes = label_names.to_set.to_a
29
+
30
+ # Array of label indexes of instances
31
+ labels = label_names.map { |label_name| label_indexes.index(label_name) }
32
+
33
+ # Create problem traning set
34
+ problem = Problem.new
35
+ problem.set_examples(labels, examples)
36
+
37
+ # Use various kernel types
38
+ [:LINEAR, :POLY, :RBF, :SIGMOID].each do |type|
39
+
40
+ # Create some parameters
41
+ parameter = SvmParameter.new
42
+ parameter.cache_size = 10 # in megabytes
43
+ parameter.eps = 0.00001
44
+ parameter.degree = 5
45
+ parameter.gamma = 0.01
46
+ parameter.c = 100
47
+ parameter.kernel_type = KernelType.const_get(type)
48
+
49
+ # Different nfold sizes. It's the number of parts the data is
50
+ # split into.
51
+ [10, 20].each do |nfold|
52
+ result = Model.cross_validation(problem, parameter, nfold)
53
+ predicted_name = result.map { |label| label_indexes[label] }
54
+ correctness = predicted_name.map.with_index { |p, i| p == label_names[i] }
55
+
56
+ correct = correctness.select { |x| x }
57
+ accuracy = correct.size.to_f / correctness.size
58
+ acc_str = "%.2f" % accuracy
59
+ puts "Accuracy[type = #{type}, nfold = #{nfold}] : #{acc_str}"
60
+ end
61
+ end
@@ -2,6 +2,7 @@ require 'mkmf'
2
2
 
3
3
  $CFLAGS << " -save-temps -ggdb3 " if ENV['DEBUG']
4
4
  $LDFLAGS << " -lstdc++ "
5
+ $CPPFLAGS << " -DDEBUG " if ENV['DEBUG']
5
6
 
6
7
  HEADER_DIRS = []
7
8
  LIB_DIRS = []
data/ext/libsvm/libsvm.c CHANGED
@@ -411,6 +411,13 @@ static VALUE cModel_classes(VALUE obj)
411
411
  return INT2NUM(svm_get_nr_class(model));
412
412
  }
413
413
 
414
+ static VALUE cModel_support_vectors(VALUE obj)
415
+ {
416
+ const struct svm_model *model;
417
+ Data_Get_Struct(obj, struct svm_model, model);
418
+ return INT2NUM(svm_get_nr_sv(model));
419
+ }
420
+
414
421
  static VALUE cModel_class_load(VALUE cls, VALUE filename)
415
422
  {
416
423
  struct svm_model *model;
@@ -493,6 +500,7 @@ void Init_libsvm_ext() {
493
500
  rb_define_method(cModel, "save", cModel_save, 1);
494
501
  rb_define_method(cModel, "svm_type", cModel_svm_type, 0);
495
502
  rb_define_method(cModel, "classes", cModel_classes, 0);
503
+ rb_define_method(cModel, "support_vectors", cModel_support_vectors, 0);
496
504
  rb_define_method(cModel, "predict", cModel_predict, 1);
497
505
  rb_define_method(cModel, "predict_probability", cModel_predict_probability, 1);
498
506
 
@@ -1,3 +1,3 @@
1
1
  module Libsvm
2
- VERSION = "1.1.5"
2
+ VERSION = "1.2.0"
3
3
  end
data/rb-libsvm.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ["C. Florian Ebeling", "Rimas Silkaitis"]
9
9
  s.email = ["florian.ebeling@gmail.com", "neovintage@gmail.com"]
10
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}
11
+ s.summary = %q{Ruby bindings for LIBSVM}
12
+ s.description = %q{Self-contained LIBSVM package for Ruby (that doesn't use SWIG). LIBSVM is a popular implementation of SVM, a machine learning classifier.}
13
13
  s.required_ruby_version = '>= 1.8.7'
14
14
 
15
15
  s.rubyforge_project = "rb-libsvm"
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  s.add_development_dependency('rake-compiler')
23
- s.add_development_dependency('rspec', '>= 2.7.0')
23
+ s.add_development_dependency('rspec', '>= 3.0.0')
24
24
 
25
25
  s.extensions << 'ext/libsvm/extconf.rb'
26
26
  end
data/spec/model_spec.rb CHANGED
@@ -9,9 +9,9 @@ module ModelSpecHelper
9
9
  def create_problem
10
10
  problem = Problem.new
11
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])]
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
15
  problem.set_examples([1,2,1,2], features)
16
16
  problem
17
17
  end
@@ -39,13 +39,21 @@ describe "The Libsvm::Model class interface" do
39
39
  end
40
40
 
41
41
  it "results from training on a problem under a certain parameter set" do
42
- model = Model.train(@problem,@parameter)
43
- model.should_not be_nil
42
+ expect(Model.train(@problem, @parameter)).not_to be_nil
44
43
  end
45
44
 
45
+ let(:labels) { Model.cross_validation(@problem, @parameter, fold=2) }
46
+
46
47
  it "can do cross-validation" do
47
- labels = Model.cross_validation(@problem, @parameter, fold=2)
48
- labels.should == [anything, anything, anything, anything]
48
+ expect(labels).to contain_exactly(
49
+ an_instance_of(Float),
50
+ an_instance_of(Float),
51
+ an_instance_of(Float),
52
+ an_instance_of(Float))
53
+ end
54
+
55
+ it "number of labels" do
56
+ expect(labels.length).to eq(4)
49
57
  end
50
58
  end
51
59
 
@@ -59,8 +67,7 @@ describe "A saved model" do
59
67
  end
60
68
 
61
69
  it "can be loaded" do
62
- model = Model.load(@filename)
63
- model.should_not be_nil
70
+ expect(Model.load(@filename)).to be_an_instance_of(Model)
64
71
  end
65
72
 
66
73
  after(:each) do
@@ -68,7 +75,7 @@ describe "A saved model" do
68
75
  end
69
76
  end
70
77
 
71
- describe "An Libsvm model" do
78
+ describe "A Libsvm model" do
72
79
  include ModelSpecHelper
73
80
 
74
81
  before(:each) do
@@ -79,28 +86,51 @@ describe "An Libsvm model" do
79
86
  File.delete(@file_path) if File.exists?(@file_path)
80
87
  end
81
88
 
82
- it "can be saved to a file" do
83
- @model.save(@file_path)
84
- File.exist?(@file_path).should be_true
85
- end
89
+ describe "basic operations" do
90
+ it "can be saved to a file" do
91
+ expect {
92
+ @model.save(@file_path)
93
+ }.to change { File.exist?(@file_path) }.from(false).to(true)
94
+ end
86
95
 
87
- it "can be asked for it's svm_type" do
88
- @model.svm_type.should == SvmType::C_SVC
96
+ it "can be asked for its svm_type" do
97
+ expect(@model.svm_type).to eq SvmType::C_SVC
98
+ end
99
+
100
+ it "can be asked for its number of classes (aka. labels)" do
101
+ expect(@model.classes).to eq(2)
102
+ end
89
103
  end
90
104
 
91
- it "can be asked for it's number of classes (aka. labels)" do
92
- @model.classes.should == 2
105
+ describe "predict" do
106
+ it "returns floats" do
107
+ expect(@model.predict(create_example)).to be_an_instance_of(Float)
108
+ end
93
109
  end
94
110
 
95
- it "can predict" do
96
- prediction = @model.predict(create_example)
97
- prediction.should_not be_nil
111
+ describe "support_vectors" do
112
+ it "returns count" do
113
+ expect(@model.support_vectors).to eq(3)
114
+ end
98
115
  end
99
116
 
100
- it "can predict probability" do
101
- prediction, probabilities = @model.predict_probability(create_example)
102
- prediction.should_not be_nil
103
- probabilities.should have(@model.classes).items
104
- probabilities.each { |e| e.should_not be_nil }
117
+ describe "predict_probability" do
118
+ let(:result) { @model.predict_probability(create_example) }
119
+ let(:prediction) { result.first }
120
+ let(:probabilities) { result.last }
121
+
122
+ it "produces prediction" do
123
+ expect(prediction).not_to be_nil
124
+ end
125
+
126
+ it "produces probabilities for each class" do
127
+ expect(probabilities.length).to eq(@model.classes)
128
+ end
129
+
130
+ it "can predict probability" do
131
+ probabilities.each do |p|
132
+ expect(p).to be_an_instance_of(Float)
133
+ end
134
+ end
105
135
  end
106
136
  end
data/spec/node_spec.rb CHANGED
@@ -5,20 +5,20 @@ describe "construction of a Node" do
5
5
  n = Node.new
6
6
  n.index = 11
7
7
  n.value = 0.11
8
- n.index.should == 11
9
- n.value.should be_within(0.0001).of(0.11)
8
+ expect(n.index).to eq 11
9
+ expect(n.value).to be_within(0.0001).of(0.11)
10
10
  end
11
11
 
12
12
  it "using the :[] method" do
13
13
  n = Node[12, 0.12]
14
- n.index.should == 12
15
- n.value.should be_within(0.00001).of(0.12)
14
+ expect(n.index).to eq 12
15
+ expect(n.value).to be_within(0.00001).of(0.12)
16
16
  end
17
17
 
18
18
  it "using the constructor parameters" do
19
19
  n = Node.new(14, 0.14)
20
- n.index.should == 14
21
- n.value.should be_within(0.0001).of(0.14)
20
+ expect(n.index).to eq 14
21
+ expect(n.value).to be_within(0.0001).of(0.14)
22
22
  end
23
23
  end
24
24
 
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,5 @@ require 'libsvm'
5
5
  include Libsvm
6
6
 
7
7
  RSpec.configure do |config|
8
- config.color_enabled = true
9
- # config.formatter = 'documentation'
8
+ config.color = true
10
9
  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.1.5
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - C. Florian Ebeling
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-24 00:00:00.000000000 Z
12
+ date: 2014-11-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -31,15 +31,16 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 2.7.0
34
+ version: 3.0.0
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 2.7.0
42
- description: libsvm and ruby without using swig
41
+ version: 3.0.0
42
+ description: Self-contained LIBSVM package for Ruby (that doesn't use SWIG). LIBSVM
43
+ is a popular implementation of SVM, a machine learning classifier.
43
44
  email:
44
45
  - florian.ebeling@gmail.com
45
46
  - neovintage@gmail.com
@@ -57,6 +58,7 @@ files:
57
58
  - README.md
58
59
  - Rakefile
59
60
  - TODO.md
61
+ - examples/iris.rb
60
62
  - examples/text.rb
61
63
  - examples/toy.rb
62
64
  - ext/libsvm/extconf.rb
@@ -96,7 +98,7 @@ rubyforge_project: rb-libsvm
96
98
  rubygems_version: 2.2.2
97
99
  signing_key:
98
100
  specification_version: 4
99
- summary: Ruby language bindings for LIBSVM
101
+ summary: Ruby bindings for LIBSVM
100
102
  test_files:
101
103
  - spec/model_spec.rb
102
104
  - spec/node_spec.rb
@@ -104,4 +106,3 @@ test_files:
104
106
  - spec/problem_spec.rb
105
107
  - spec/spec_helper.rb
106
108
  - spec/usage_spec.rb
107
- has_rdoc: