mirlo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,77 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mirlo::Perceptron do
4
+
5
+ let(:perceptron) { Mirlo::Perceptron.new }
6
+
7
+ it 'intializes the matrix of weights' do
8
+ perceptron.train_set = Mirlo::DoubleMoonDataSet.new(n_points: 50)
9
+ expect(perceptron.weights).to be_kind_of(Matrix)
10
+
11
+ expect(perceptron.weights.column_count).to eq 1
12
+ expect(perceptron.weights.row_count).to eq 3
13
+
14
+ perceptron.weights.each do |weight|
15
+ expect(-0.05..0.05).to include(weight)
16
+ end
17
+ end
18
+
19
+ it 'can classify an OR dataset' do
20
+ data_set = Mirlo::OrDataSet.new
21
+
22
+ perceptron.train(data_set)
23
+
24
+ expect(perceptron.classify([0,0])).to eq [0]
25
+ expect(perceptron.classify([0,1])).to eq [1]
26
+ expect(perceptron.classify([1,0])).to eq [1]
27
+ expect(perceptron.classify([1,1])).to eq [1]
28
+
29
+ test_result = perceptron.test_with(data_set)
30
+ expect(test_result.mean_squared_error).to eq 0.0
31
+ end
32
+
33
+ it 'can classify an AND dataset' do
34
+ data_set = Mirlo::AndDataSet.new
35
+
36
+ perceptron.train(data_set)
37
+
38
+ expect(perceptron.classify([0,0])).to eq [0]
39
+ expect(perceptron.classify([0,1])).to eq [0]
40
+ expect(perceptron.classify([1,0])).to eq [0]
41
+ expect(perceptron.classify([1,1])).to eq [1]
42
+
43
+ test_result = perceptron.test_with(data_set)
44
+ expect(test_result.mean_squared_error).to eq 0.0
45
+ end
46
+
47
+ it 'can not classify an XOR dataset' do
48
+ data_set = Mirlo::XorDataSet.new
49
+
50
+ perceptron.train(data_set)
51
+
52
+ test_result = perceptron.test_with(data_set)
53
+ expect(test_result.mean_squared_error).to be > 0.0
54
+ end
55
+
56
+ it 'correctly classifies a linearly separable double moon data set' do
57
+ train_set = Mirlo::DoubleMoonDataSet.new(distance: 10)
58
+
59
+ perceptron.train_until(train_set, max_error: 0.0)
60
+ test_results = perceptron.test_with(train_set)
61
+
62
+ expect(test_results.error_percentage).to eq 0.00
63
+ end
64
+
65
+ it 'can not classify a non linearly separable double moon data set' do
66
+ train_set = Mirlo::DoubleMoonDataSet.new(distance: -2)
67
+
68
+ expect do
69
+ perceptron.train_until(train_set, max_error: 0.0)
70
+ end.to raise_error(Mirlo::ClassifyError)
71
+
72
+ test_results = perceptron.test_with(train_set)
73
+
74
+ expect(test_results.error_percentage).to be > 0.0
75
+ end
76
+
77
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'dataset' do
4
+ let(:samples) { [[0, 0], [0, 1], [1, 0], [1, 1]] }
5
+ let(:targets) { [ZERO, ONE, ONE, ONE] }
6
+
7
+ let(:dataset) { Mirlo::Dataset.new(samples: samples, targets: targets, feature_names: ['x', 'y']) }
8
+ let(:input_matrix) { dataset.input_matrix }
9
+ let(:target_matrix) { dataset.target_matrix }
10
+
11
+ it 'can be initialized with an array of samples and targets' do
12
+ first_sample = dataset.samples.first
13
+
14
+ first_sample.should be_kind_of(Mirlo::Sample)
15
+ first_sample.target.should == [0]
16
+ first_sample.features.should == [-1,0,0]
17
+
18
+ last_sample = dataset.samples.last
19
+
20
+ last_sample.should be_kind_of(Mirlo::Sample)
21
+ last_sample.target.should == ONE
22
+ last_sample.features.should == [-1,1,1]
23
+ end
24
+
25
+ it 'can collect the subset with a target' do
26
+ positives = dataset.subset_with_target(ONE)
27
+ positives.size.should eq 3
28
+ positives.each { |s| s.target.should == ONE }
29
+ end
30
+
31
+ it 'can collect the values for a feature' do
32
+ x_values = dataset.feature('x')
33
+ x_values.should eq [0, 0, 1, 1]
34
+
35
+ y_values = dataset.feature(1)
36
+ y_values.should eq [0, 1, 0, 1]
37
+ end
38
+
39
+ it 'can create a matrix of inputs' do
40
+ input_matrix.should be_kind_of(Matrix)
41
+ input_matrix.should == Matrix[[-1,0,0], [-1,0,1], [-1,1,0], [-1,1,1]]
42
+ input_matrix.row_count.should == samples.size
43
+ input_matrix.column_count.should == dataset.num_features
44
+ end
45
+
46
+ it 'can create a matrix of targets' do
47
+ target_matrix.should be_kind_of(Matrix)
48
+ target_matrix.should == Matrix[ZERO, ONE, ONE, ONE]
49
+ target_matrix.row_count.should == samples.size
50
+ target_matrix.column_count.should == dataset.num_outputs
51
+ end
52
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mirlo::AndDataSet do
4
+
5
+ let(:dataset) { Mirlo::AndDataSet.new }
6
+
7
+ it 'should contain datapoints with target ONE or ZERO' do
8
+ possible_targets = [Mirlo::ZERO, Mirlo::ONE]
9
+ dataset.size.should == 4
10
+ dataset.samples.each do |sample|
11
+ possible_targets.should include sample.target
12
+ end
13
+ end
14
+
15
+ it 'represents the AND logical function' do
16
+ dataset.targets_for([0,0]).should eq [Mirlo::ZERO]
17
+ dataset.targets_for([0,1]).should eq [Mirlo::ZERO]
18
+ dataset.targets_for([1,0]).should eq [Mirlo::ZERO]
19
+ dataset.targets_for([1,1]).should eq [Mirlo::ONE]
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'mirlo/datasets/double_moon_dataset'
3
+
4
+ describe Mirlo::DoubleMoonDataSet do
5
+
6
+ let(:dataset) { Mirlo::DoubleMoonDataSet.new(n_points: 1000) }
7
+
8
+ it 'should contain datapoints with target upper_moon or lower_moon' do
9
+ possible_targets = [DoubleMoonDataSet::UPPER_MOON, DoubleMoonDataSet::LOWER_MOON]
10
+ dataset.samples.size.should == 1000
11
+ dataset.samples.each do |sample|
12
+ sample.feature_size.should eq 3 # including bias
13
+ sample.target.should_not be_nil
14
+ possible_targets.should include sample.target
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Matrix' do
4
+ let(:matrix1) { Matrix[[0, 1], [2, 3]] }
5
+ let(:matrix2) { Matrix[[4, 5], [6, 7]] }
6
+
7
+ it "returns the shape of the matrices" do
8
+ expect(matrix1.shape).to eq [2, 2]
9
+ end
10
+
11
+ it "allows to perform operations elementwise" do
12
+ sum = matrix1.apply_elementwise(matrix2, &:+)
13
+ expect(sum).to eq Matrix[[4, 6], [8, 10]]
14
+
15
+ mult = matrix1.apply_elementwise(matrix2, &:*)
16
+ expect(mult).to eq Matrix[[0, 5], [12, 21]]
17
+ end
18
+ end
@@ -0,0 +1,100 @@
1
+ 22.699499219368683 -2.1666882286337446
2
+ -1.0238226173892873 -6.039752563327135
3
+ 5.183298314856746 -9.444625616257067
4
+ 8.966892970585487 -10.700411957633332
5
+ 18.326740061389646 -8.368561229794057
6
+ 1.7904888882645213 -4.746066150914222
7
+ 20.86225005856995 -8.57911516237401
8
+ 19.136363525601958 -5.008938500736759
9
+ 15.25689119604732 -11.875908552059297
10
+ -0.7994857812232876 -7.377668356669467
11
+ 9.623537863679964 -14.31699331577667
12
+ 16.836733433957143 -4.421577960065798
13
+ 17.528052750176904 -2.3970180772672713
14
+ 3.7016007314418866 -9.09746276623608
15
+ 18.79226570367281 -6.060457166531629
16
+ 12.078422155759819 -9.557447466911679
17
+ 15.459944757464385 -8.586428374856343
18
+ 18.29203308375591 -4.511518500039898
19
+ 3.7612328557682932 -9.250758398880315
20
+ 14.364255218636185 -12.021466215890603
21
+ 5.760384031876874 -10.926368718392357
22
+ 0.6128808114415119 -10.783439185742042
23
+ 12.623551730919115 -13.708353557641244
24
+ -0.4613487419834321 -2.521608973649391
25
+ -0.929747189731982 -8.932942560401399
26
+ 20.744726030865856 -6.656463368362586
27
+ 13.922285277193057 -7.8556270406772715
28
+ -0.2566933050582634 -3.453225880596812
29
+ 4.824164944384789 -8.907300113585485
30
+ 4.89551477862841 -7.3618846612250195
31
+ 15.560131310929716 -10.191438244690577
32
+ 15.02752070459389 -7.96718187268361
33
+ 2.0177947716913183 -6.146741506592753
34
+ 19.381038102611065 -10.822485472525052
35
+ 1.9537633239782721 -9.799888407015233
36
+ 14.195684458376261 -10.288766487556781
37
+ 11.491074070340396 -10.658680403957662
38
+ 8.654576547048924 -11.05580522877251
39
+ 14.127345409747765 -10.238888613870003
40
+ 2.651783995174843 -6.5921027025360965
41
+ 18.479267685452847 -2.5218303580734847
42
+ 14.3616244506985 -13.75712793745152
43
+ 11.400845515121791 -10.724444069525477
44
+ 18.051171546236652 -7.862781462877648
45
+ 1.7952147455168745 -7.114789363148967
46
+ 7.019493119501957 -12.06494523745483
47
+ 21.155474994012266 -6.348914606625215
48
+ 7.363278808753227 5.914225309021491
49
+ -6.632907338776547 6.222409548485236
50
+ -8.381509767830199 6.660826880199398
51
+ 1.2084017967122922 7.182604442758949
52
+ 0.9754183032001764 10.629059013068842
53
+ -7.78705550036493 1.403518609438154
54
+ -6.642021986762731 9.769386621759274
55
+ -0.511849405896763 11.548921748496783
56
+ -4.806374461961378 7.13188274955524
57
+ 8.346223096901891 6.124173979506412
58
+ -1.6303605767684457 11.058171698507655
59
+ -4.826790581394419 7.187106833249339
60
+ 2.820223087933491 6.939841052614711
61
+ -12.46086253273039 2.591962902212741
62
+ -6.839377930798852 7.878103849032446
63
+ -8.33776601524478 5.95650351466622
64
+ 12.881096874987644 1.430849137197838
65
+ 6.664261504216628 8.486277543798032
66
+ -3.738326888272411 10.402060373879662
67
+ 4.829866717679142 6.41150181645886
68
+ 6.422511326502259 4.160923000145747
69
+ -8.075707832367883 3.3699144364139912
70
+ -12.014913319486006 3.9327214396933683
71
+ 7.63005197896378 2.835080709005794
72
+ 0.4111356671256101 12.795114494305015
73
+ 8.83179121939622 1.9736187559728053
74
+ -8.3341562839948 2.0627110224232807
75
+ -8.655249982186694 5.151914514724507
76
+ 0.5504480690573699 9.848981464789638
77
+ -0.6661475805482877 7.068339384681492
78
+ 3.842923442173947 9.638616410959933
79
+ 6.332645352384603 9.17844543765685
80
+ 11.417903720238927 0.285247132908345
81
+ 10.71570293901256 5.832053398368492
82
+ 9.006942399098468 3.8861964134156284
83
+ 6.228082530193662 10.942375751754108
84
+ -3.8208847259529395 7.188113006568298
85
+ -11.143677615816511 4.379757857767416
86
+ -3.1738359480100784 11.44226165193353
87
+ -6.8836546251822925 6.797452149533816
88
+ 7.144605206238983 10.128058205298391
89
+ -7.073701731580115 0.7199340093624303
90
+ 9.042504374591765 7.6763460034548565
91
+ -0.49325064406428615 9.874179552732578
92
+ 9.610672183176028 0.2972108627618694
93
+ -9.775184465354398 2.895961520717171
94
+ -8.87887296218432 4.4965662760245575
95
+ -2.0599535221789322 7.030823103095841
96
+ -4.686958784984163 10.88046177468535
97
+ 12.240220396544853 4.257896362244819
98
+ 7.487804381113148 4.090819152617927
99
+ 9.24197260243927 2.148996687025518
100
+ 0.5059488780193738 7.000211538293668
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Plotting' do
4
+ let(:data_set) { Mirlo::DoubleMoonDataSet.new(n_points: 1000, distance: 5) }
5
+
6
+ it 'allows to plot a data set' do
7
+ data_set.plot
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../lib/mirlo'
2
+ include Mirlo
3
+
4
+ Dir.glob(File.expand_path('../lib/mirlo/datasets/*.rb', File.dirname(__FILE__))).each do |f|
5
+ require f
6
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mirlo::TestResult do
4
+ before do
5
+ @test_result = Mirlo::TestResult.new([ZERO, ONE])
6
+
7
+ positive_sample = Mirlo::Sample.new(target: ONE)
8
+ negative_sample = Mirlo::Sample.new(target: ZERO)
9
+
10
+ @test_result.add(positive_sample, ONE)
11
+ @test_result.add(positive_sample, ONE)
12
+ @test_result.add(positive_sample, ONE)
13
+
14
+ @test_result.add(negative_sample, ZERO)
15
+ @test_result.add(negative_sample, ZERO)
16
+ @test_result.add(negative_sample, ZERO)
17
+
18
+ # there are two errors classifiying positive samples
19
+
20
+ @test_result.add(positive_sample, ZERO)
21
+ @test_result.add(positive_sample, ZERO)
22
+ end
23
+
24
+ it "can show the confussion matrix" do
25
+ @test_result.confusion_matrix(ONE, ONE).should == 3
26
+ @test_result.confusion_matrix(ONE, ZERO).should == 2
27
+ @test_result.confusion_matrix(ZERO, ZERO).should == 3
28
+ @test_result.confusion_matrix(ZERO, ONE).should == 0
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mirlo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alberto F. Capel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: gnuplot
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Machine Learning experiments
70
+ email:
71
+ - afcapel@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/mirlo.rb
82
+ - lib/mirlo/ann/ann.rb
83
+ - lib/mirlo/ann/hidden_layer.rb
84
+ - lib/mirlo/ann/input_layer.rb
85
+ - lib/mirlo/ann/multilayer_perceptron.rb
86
+ - lib/mirlo/ann/neuron_layer.rb
87
+ - lib/mirlo/ann/output_layer.rb
88
+ - lib/mirlo/classifier.rb
89
+ - lib/mirlo/classifiers/perceptron.rb
90
+ - lib/mirlo/dataset.rb
91
+ - lib/mirlo/datasets/and_dataset.rb
92
+ - lib/mirlo/datasets/double_moon_dataset.rb
93
+ - lib/mirlo/datasets/or_dataset.rb
94
+ - lib/mirlo/datasets/xor_dataset.rb
95
+ - lib/mirlo/extensions/matrix.rb
96
+ - lib/mirlo/plotting.rb
97
+ - lib/mirlo/sample.rb
98
+ - lib/mirlo/sample_with_bias.rb
99
+ - lib/mirlo/test_result.rb
100
+ - lib/mirlo/version.rb
101
+ - mirlo.gemspec
102
+ - spec/ann/ann_spec.rb
103
+ - spec/ann/multilayer_percetron_spec.rb
104
+ - spec/ann/neuron_layer_spec.rb
105
+ - spec/classifiers/perceptron_spec.rb
106
+ - spec/dataset_spec.rb
107
+ - spec/datasets/and_dataset_spec.rb
108
+ - spec/datasets/double_moon_dataset_spec.rb
109
+ - spec/extensions/matrix_spec.rb
110
+ - spec/plots/double_moon.dat
111
+ - spec/plotting_spec.rb
112
+ - spec/spec_helper.rb
113
+ - spec/test_result_spec.rb
114
+ homepage: https://github.com/afcapel/mirlo
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 2.0.0
135
+ signing_key:
136
+ specification_version: 4
137
+ summary: Implementation of some Machine Learning algorithms
138
+ test_files:
139
+ - spec/ann/ann_spec.rb
140
+ - spec/ann/multilayer_percetron_spec.rb
141
+ - spec/ann/neuron_layer_spec.rb
142
+ - spec/classifiers/perceptron_spec.rb
143
+ - spec/dataset_spec.rb
144
+ - spec/datasets/and_dataset_spec.rb
145
+ - spec/datasets/double_moon_dataset_spec.rb
146
+ - spec/extensions/matrix_spec.rb
147
+ - spec/plots/double_moon.dat
148
+ - spec/plotting_spec.rb
149
+ - spec/spec_helper.rb
150
+ - spec/test_result_spec.rb