rsvm 0.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/.gitignore +6 -0
- data/Gemfile +6 -0
- data/README.md +89 -0
- data/Rakefile +41 -0
- data/ext/libsvm/COPYRIGHT +31 -0
- data/ext/libsvm/FAQ.html +1837 -0
- data/ext/libsvm/README +748 -0
- data/ext/libsvm/extconf.rb +3 -0
- data/ext/libsvm/svm.cpp +3213 -0
- data/ext/libsvm/svm.h +102 -0
- data/lib/svm.rb +119 -0
- data/lib/svm/cross_validation.rb +39 -0
- data/lib/svm/debug.rb +12 -0
- data/lib/svm/model.rb +68 -0
- data/lib/svm/options.rb +69 -0
- data/lib/svm/problem.rb +151 -0
- data/lib/svm/scaler.rb +82 -0
- data/lib/svm/version.rb +3 -0
- data/rsvm.gemspec +25 -0
- data/test/fixtures/heart_scale.csv +270 -0
- data/test/fixtures/unbalanced.csv +164 -0
- data/test/lib/cross_validation_test.rb +35 -0
- data/test/lib/model_test.rb +84 -0
- data/test/lib/problem_test.rb +39 -0
- data/test/lib/scaler_test.rb +57 -0
- data/test/test_helper.rb +3 -0
- metadata +101 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Svm::CrossValidation do
|
4
|
+
HEART_SCALE_CSV = File.join(File.dirname(__FILE__), '..', 'fixtures', 'heart_scale.csv')
|
5
|
+
UNBALANCED_CSV = File.join(File.dirname(__FILE__), '..', 'fixtures', 'unbalanced.csv')
|
6
|
+
|
7
|
+
it "can perfom cross validation" do
|
8
|
+
problem = Svm::Problem.load_from_csv(HEART_SCALE_CSV)
|
9
|
+
|
10
|
+
success_percentage = problem.results_for_cross_validation(3, :c => 10, :gamma => 0.01)
|
11
|
+
success_percentage.must_be :>, 0.8
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can find the best parameters for the problem" do
|
15
|
+
problem = Svm::Problem.load_from_csv(HEART_SCALE_CSV)
|
16
|
+
|
17
|
+
before = problem.results_for_cross_validation(3, :c => 1, :gamma => 0.001)
|
18
|
+
|
19
|
+
options = problem.find_best_parameters
|
20
|
+
|
21
|
+
after = problem.results_for_cross_validation(3, options)
|
22
|
+
|
23
|
+
before.must_be :<, after
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can cross validate unbalanced data" do
|
27
|
+
problem = Svm::Problem.load_from_csv(UNBALANCED_CSV)
|
28
|
+
|
29
|
+
options = problem.find_best_parameters(3)
|
30
|
+
|
31
|
+
success_percentage = problem.results_for_cross_validation(10, options)
|
32
|
+
|
33
|
+
success_percentage.must_be :>, 0.8
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
describe Svm::Model do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@problem = Svm::Problem.new
|
8
|
+
@problem.data = [
|
9
|
+
[1, 1, 0, 1],
|
10
|
+
[-1, -1, 0, -1]
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "stores the passed parameters" do
|
15
|
+
model = @problem.generate_model(:kernel_type => :linear, :c => 15)
|
16
|
+
|
17
|
+
param_struct = model.model_struct[:param]
|
18
|
+
|
19
|
+
param_struct[:kernel_type].must_equal(:linear)
|
20
|
+
param_struct[:c].must_equal(15)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can make a prediction for a sample" do
|
24
|
+
model = @problem.generate_model(:kernel_type => :linear, :c => 10)
|
25
|
+
|
26
|
+
model.predict([-1, 0, -1]).must_equal(-1)
|
27
|
+
model.predict([1, 0, 1]).must_equal(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "must raise an exception if training parameters are not valid" do
|
31
|
+
|
32
|
+
proc {
|
33
|
+
@problem.generate_model(:kernel_type => :linear, :c => -10)
|
34
|
+
}.must_raise Svm::ParameterError
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can be saved to a file" do
|
39
|
+
file = Tempfile.new('model')
|
40
|
+
|
41
|
+
begin
|
42
|
+
model = @problem.generate_model(:kernel_type => :linear, :c => 20)
|
43
|
+
model.save(file.path)
|
44
|
+
|
45
|
+
loaded_model = Svm::Model.load(file.path)
|
46
|
+
|
47
|
+
loaded_model.predict([-1, 0, -1]).must_equal(-1)
|
48
|
+
loaded_model.predict([1, 0, 1]).must_equal(1)
|
49
|
+
ensure
|
50
|
+
file.close
|
51
|
+
file.unlink # deletes the temp file
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "stores the number of classes" do
|
56
|
+
model = @problem.generate_model(:kernel_type => :linear, :c => 20)
|
57
|
+
model.number_of_classes.must_equal 2
|
58
|
+
end
|
59
|
+
|
60
|
+
it "stores the labels" do
|
61
|
+
model = @problem.generate_model(:kernel_type => :linear, :c => 10)
|
62
|
+
model.labels.sort.must_equal [-1, 1]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "can predict probabilities" do
|
66
|
+
csv_path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'heart_scale.csv')
|
67
|
+
problem = Svm::Problem.load_from_csv(csv_path)
|
68
|
+
|
69
|
+
problem.estimate_probabilities = true
|
70
|
+
|
71
|
+
model = problem.generate_model
|
72
|
+
|
73
|
+
sample = [60.0, 1.0, 3.0, 140.0, 185.0, 0.0, 2.0, 155.0, 0.0, 3.0, 2.0, 0.0, 3.0]
|
74
|
+
probs = model.predict_probabilities(sample)
|
75
|
+
|
76
|
+
probs.values.each do |p|
|
77
|
+
p.must_be :>=, 0
|
78
|
+
p.must_be :<=, 1
|
79
|
+
end
|
80
|
+
|
81
|
+
probs.values.inject(&:+).must_be_close_to 1, 0.01
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Svm::Problem do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@problem = Svm::Problem.new(:scale => false)
|
7
|
+
@problem.data = [
|
8
|
+
[1, 1, 0, 1],
|
9
|
+
[-1, -1, 0, -1],
|
10
|
+
[-1, -1, -1, -1]
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "stores the samples length" do
|
15
|
+
@problem.length.must_equal(3)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "stores problem values" do
|
19
|
+
@problem.value(0).must_equal(1.0)
|
20
|
+
@problem.value(1).must_equal(-1)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "stores samples features" do
|
24
|
+
@problem.sample(0).must_equal([1, 0, 1])
|
25
|
+
@problem.sample(1).must_equal([-1, 0, -1])
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can generate a model" do
|
29
|
+
model = @problem.generate_model
|
30
|
+
model.must_be_instance_of Svm::Model
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can suggets weights for labels" do
|
34
|
+
@problem.labels.sort.must_equal [-1, 1]
|
35
|
+
|
36
|
+
@problem.suggested_labels_weights[1].must_equal(1.0/3)
|
37
|
+
@problem.suggested_labels_weights[-1].must_equal(2.0/3)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe Svm::Scaler do
|
4
|
+
|
5
|
+
before do
|
6
|
+
data = [
|
7
|
+
[1, 12.0, -7.6, 100_000, 0],
|
8
|
+
[2, 30.0, 0, -100_000, 0],
|
9
|
+
[3, 36.0, 7.6, 0, 0]
|
10
|
+
]
|
11
|
+
|
12
|
+
@scaler = Svm::Scaler.new(data)
|
13
|
+
@scaler.scale!
|
14
|
+
end
|
15
|
+
|
16
|
+
it "doesn't scale the label data" do
|
17
|
+
@scaler.labels.must_equal([1, 2, 3])
|
18
|
+
end
|
19
|
+
|
20
|
+
it "finds the unit to scale" do
|
21
|
+
@scaler.unit[1].must_equal(12)
|
22
|
+
@scaler.unit[2].must_equal(7.6)
|
23
|
+
@scaler.unit[3].must_equal(100_000)
|
24
|
+
@scaler.unit[4].must_equal(0)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "finds the zero to scale" do
|
28
|
+
@scaler.zero[1].must_equal(24.0)
|
29
|
+
@scaler.zero[2].must_equal(0)
|
30
|
+
@scaler.zero[3].must_equal(0)
|
31
|
+
@scaler.zero[4].must_equal(0)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "scales the data" do
|
35
|
+
@scaler.values_for_feature(1).must_equal [-1, 0.5, 1]
|
36
|
+
@scaler.values_for_feature(2).must_equal [-1, 0, 1]
|
37
|
+
@scaler.values_for_feature(3).must_equal [1, -1, 0]
|
38
|
+
@scaler.values_for_feature(4).must_equal [0, 0, 0]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "can scale new input" do
|
42
|
+
@scaler.scale([36.0, -7.6, 10_000, 1]).must_equal [1, -1, 0.1, 1]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can be saved to a file" do
|
46
|
+
path = File.join(File.dirname(__FILE__), '..', 'fixtures', 'scaler.yml')
|
47
|
+
|
48
|
+
@scaler.save(path)
|
49
|
+
|
50
|
+
recovered = Svm::Scaler.load(path)
|
51
|
+
|
52
|
+
recovered.scale([36.0, -7.6, 10_000, 1]).must_equal [1, -1, 0.1, 1]
|
53
|
+
|
54
|
+
File.delete(path)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsvm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alberto Fernández Capel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
type: :runtime
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
name: ffi
|
23
|
+
prerelease: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: FFI Ruby wrapper around libsvm
|
31
|
+
email:
|
32
|
+
- afcapel@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions:
|
35
|
+
- ext/libsvm/extconf.rb
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- Gemfile
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- ext/libsvm/COPYRIGHT
|
43
|
+
- ext/libsvm/FAQ.html
|
44
|
+
- ext/libsvm/README
|
45
|
+
- ext/libsvm/extconf.rb
|
46
|
+
- ext/libsvm/svm.cpp
|
47
|
+
- ext/libsvm/svm.h
|
48
|
+
- lib/svm.rb
|
49
|
+
- lib/svm/cross_validation.rb
|
50
|
+
- lib/svm/debug.rb
|
51
|
+
- lib/svm/model.rb
|
52
|
+
- lib/svm/options.rb
|
53
|
+
- lib/svm/problem.rb
|
54
|
+
- lib/svm/scaler.rb
|
55
|
+
- lib/svm/version.rb
|
56
|
+
- rsvm.gemspec
|
57
|
+
- test/fixtures/heart_scale.csv
|
58
|
+
- test/fixtures/unbalanced.csv
|
59
|
+
- test/lib/cross_validation_test.rb
|
60
|
+
- test/lib/model_test.rb
|
61
|
+
- test/lib/problem_test.rb
|
62
|
+
- test/lib/scaler_test.rb
|
63
|
+
- test/test_helper.rb
|
64
|
+
homepage: https://github.com/afcapel/rsvm
|
65
|
+
licenses: []
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
hash: -3783083930879184987
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: -3783083930879184987
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project: rsvm
|
90
|
+
rubygems_version: 1.8.23
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: Support Vector Machine Gem
|
94
|
+
test_files:
|
95
|
+
- test/fixtures/heart_scale.csv
|
96
|
+
- test/fixtures/unbalanced.csv
|
97
|
+
- test/lib/cross_validation_test.rb
|
98
|
+
- test/lib/model_test.rb
|
99
|
+
- test/lib/problem_test.rb
|
100
|
+
- test/lib/scaler_test.rb
|
101
|
+
- test/test_helper.rb
|