rb-libsvm 1.1.5 → 1.2.0

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.
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: