mirlo 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.
@@ -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