ai4ruby 1.11
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/README.rdoc +47 -0
- data/examples/classifiers/id3_data.csv +121 -0
- data/examples/classifiers/id3_example.rb +29 -0
- data/examples/classifiers/naive_bayes_data.csv +11 -0
- data/examples/classifiers/naive_bayes_example.rb +16 -0
- data/examples/classifiers/results.txt +31 -0
- data/examples/genetic_algorithm/genetic_algorithm_example.rb +37 -0
- data/examples/genetic_algorithm/travel_cost.csv +16 -0
- data/examples/neural_network/backpropagation_example.rb +67 -0
- data/examples/neural_network/patterns_with_base_noise.rb +68 -0
- data/examples/neural_network/patterns_with_noise.rb +66 -0
- data/examples/neural_network/training_patterns.rb +68 -0
- data/examples/neural_network/xor_example.rb +35 -0
- data/examples/som/som_data.rb +156 -0
- data/examples/som/som_multi_node_example.rb +22 -0
- data/examples/som/som_single_example.rb +24 -0
- data/lib/ai4r.rb +33 -0
- data/lib/ai4r/classifiers/classifier.rb +62 -0
- data/lib/ai4r/classifiers/hyperpipes.rb +118 -0
- data/lib/ai4r/classifiers/ib1.rb +121 -0
- data/lib/ai4r/classifiers/id3.rb +326 -0
- data/lib/ai4r/classifiers/multilayer_perceptron.rb +135 -0
- data/lib/ai4r/classifiers/naive_bayes.rb +259 -0
- data/lib/ai4r/classifiers/one_r.rb +110 -0
- data/lib/ai4r/classifiers/prism.rb +197 -0
- data/lib/ai4r/classifiers/zero_r.rb +73 -0
- data/lib/ai4r/clusterers/average_linkage.rb +59 -0
- data/lib/ai4r/clusterers/bisecting_k_means.rb +93 -0
- data/lib/ai4r/clusterers/centroid_linkage.rb +66 -0
- data/lib/ai4r/clusterers/clusterer.rb +61 -0
- data/lib/ai4r/clusterers/complete_linkage.rb +67 -0
- data/lib/ai4r/clusterers/diana.rb +139 -0
- data/lib/ai4r/clusterers/k_means.rb +126 -0
- data/lib/ai4r/clusterers/median_linkage.rb +61 -0
- data/lib/ai4r/clusterers/single_linkage.rb +194 -0
- data/lib/ai4r/clusterers/ward_linkage.rb +64 -0
- data/lib/ai4r/clusterers/ward_linkage_hierarchical.rb +31 -0
- data/lib/ai4r/clusterers/weighted_average_linkage.rb +61 -0
- data/lib/ai4r/data/data_set.rb +266 -0
- data/lib/ai4r/data/parameterizable.rb +64 -0
- data/lib/ai4r/data/proximity.rb +100 -0
- data/lib/ai4r/data/statistics.rb +77 -0
- data/lib/ai4r/experiment/classifier_evaluator.rb +95 -0
- data/lib/ai4r/genetic_algorithm/genetic_algorithm.rb +270 -0
- data/lib/ai4r/neural_network/backpropagation.rb +326 -0
- data/lib/ai4r/neural_network/hopfield.rb +149 -0
- data/lib/ai4r/som/layer.rb +68 -0
- data/lib/ai4r/som/node.rb +96 -0
- data/lib/ai4r/som/som.rb +155 -0
- data/lib/ai4r/som/two_phase_layer.rb +90 -0
- data/test/classifiers/hyperpipes_test.rb +84 -0
- data/test/classifiers/ib1_test.rb +78 -0
- data/test/classifiers/id3_test.rb +208 -0
- data/test/classifiers/multilayer_perceptron_test.rb +79 -0
- data/test/classifiers/naive_bayes_test.rb +43 -0
- data/test/classifiers/one_r_test.rb +62 -0
- data/test/classifiers/prism_test.rb +85 -0
- data/test/classifiers/zero_r_test.rb +49 -0
- data/test/clusterers/average_linkage_test.rb +51 -0
- data/test/clusterers/bisecting_k_means_test.rb +66 -0
- data/test/clusterers/centroid_linkage_test.rb +53 -0
- data/test/clusterers/complete_linkage_test.rb +57 -0
- data/test/clusterers/diana_test.rb +69 -0
- data/test/clusterers/k_means_test.rb +100 -0
- data/test/clusterers/median_linkage_test.rb +53 -0
- data/test/clusterers/single_linkage_test.rb +122 -0
- data/test/clusterers/ward_linkage_hierarchical_test.rb +61 -0
- data/test/clusterers/ward_linkage_test.rb +53 -0
- data/test/clusterers/weighted_average_linkage_test.rb +53 -0
- data/test/data/data_set_test.rb +96 -0
- data/test/data/proximity_test.rb +81 -0
- data/test/data/statistics_test.rb +65 -0
- data/test/experiment/classifier_evaluator_test.rb +76 -0
- data/test/genetic_algorithm/chromosome_test.rb +58 -0
- data/test/genetic_algorithm/genetic_algorithm_test.rb +81 -0
- data/test/neural_network/backpropagation_test.rb +82 -0
- data/test/neural_network/hopfield_test.rb +72 -0
- data/test/som/som_test.rb +97 -0
- metadata +168 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# Author:: Sergio Fierens (implementation)
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/clusterers/median_linkage'
|
12
|
+
|
13
|
+
class Ai4r::Clusterers::MedianLinkage
|
14
|
+
attr_accessor :data_set, :number_of_clusters, :clusters, :distance_matrix, :index_clusters
|
15
|
+
end
|
16
|
+
|
17
|
+
class Ai4r::Clusterers::MedianLinkageTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Ai4r::Clusterers
|
20
|
+
include Ai4r::Data
|
21
|
+
|
22
|
+
@@data = [ [10, 3], [3, 10], [2, 8], [2, 5], [3, 8], [10, 3],
|
23
|
+
[1, 3], [8, 1], [2, 9], [2, 5], [3, 3], [9, 4]]
|
24
|
+
|
25
|
+
@@expected_distance_matrix = [
|
26
|
+
[98.0],
|
27
|
+
[89.0, 5.0],
|
28
|
+
[68.0, 26.0, 9.0],
|
29
|
+
[74.0, 4.0, 1.0, 10.0],
|
30
|
+
[0.0, 98.0, 89.0, 68.0, 74.0],
|
31
|
+
[81.0, 53.0, 26.0, 5.0, 29.0, 81.0],
|
32
|
+
[8.0, 106.0, 85.0, 52.0, 74.0, 8.0, 53.0],
|
33
|
+
[100.0, 2.0, 1.0, 16.0, 2.0, 100.0, 37.0, 100.0],
|
34
|
+
[68.0, 26.0, 9.0, 0.0, 10.0, 68.0, 5.0, 52.0, 16.0],
|
35
|
+
[49.0, 49.0, 26.0, 5.0, 25.0, 49.0, 4.0, 29.0, 37.0, 5.0],
|
36
|
+
[2.0, 72.0, 65.0, 50.0, 52.0, 2.0, 65.0, 10.0, 74.0, 50.0, 37.0]]
|
37
|
+
|
38
|
+
def setup
|
39
|
+
Ai4r::Clusterers::MedianLinkage.send(:public,
|
40
|
+
*Ai4r::Clusterers::MedianLinkage.protected_instance_methods)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_linkage_distance
|
44
|
+
clusterer = Ai4r::Clusterers::MedianLinkage.new
|
45
|
+
clusterer.data_set = DataSet.new :data_items => @@data
|
46
|
+
clusterer.index_clusters = clusterer.create_initial_index_clusters
|
47
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
48
|
+
assert_equal 92.25, clusterer.linkage_distance(0,1,2)
|
49
|
+
assert_equal 15.25, clusterer.linkage_distance(4,2,5)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# Author:: Sergio Fierens (implementation)
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/clusterers/single_linkage'
|
12
|
+
|
13
|
+
class Ai4r::Clusterers::SingleLinkage
|
14
|
+
attr_accessor :data_set, :number_of_clusters, :clusters, :distance_matrix
|
15
|
+
end
|
16
|
+
|
17
|
+
class SingleLinkageTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Ai4r::Clusterers
|
20
|
+
include Ai4r::Data
|
21
|
+
|
22
|
+
@@data = [ [10, 3], [3, 10], [2, 8], [2, 5], [3, 8], [10, 3],
|
23
|
+
[1, 3], [8, 1], [2, 9], [2, 5], [3, 3], [9, 4]]
|
24
|
+
|
25
|
+
@@expected_distance_matrix = [
|
26
|
+
[98.0],
|
27
|
+
[89.0, 5.0],
|
28
|
+
[68.0, 26.0, 9.0],
|
29
|
+
[74.0, 4.0, 1.0, 10.0],
|
30
|
+
[0.0, 98.0, 89.0, 68.0, 74.0],
|
31
|
+
[81.0, 53.0, 26.0, 5.0, 29.0, 81.0],
|
32
|
+
[8.0, 106.0, 85.0, 52.0, 74.0, 8.0, 53.0],
|
33
|
+
[100.0, 2.0, 1.0, 16.0, 2.0, 100.0, 37.0, 100.0],
|
34
|
+
[68.0, 26.0, 9.0, 0.0, 10.0, 68.0, 5.0, 52.0, 16.0],
|
35
|
+
[49.0, 49.0, 26.0, 5.0, 25.0, 49.0, 4.0, 29.0, 37.0, 5.0],
|
36
|
+
[2.0, 72.0, 65.0, 50.0, 52.0, 2.0, 65.0, 10.0, 74.0, 50.0, 37.0]]
|
37
|
+
|
38
|
+
def setup
|
39
|
+
SingleLinkage.send(:public, *SingleLinkage.protected_instance_methods)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_build
|
43
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
44
|
+
clusterer.build(DataSet.new(:data_items => @@data), 4)
|
45
|
+
#draw_map(clusterer)
|
46
|
+
assert_equal 4, clusterer.clusters.length
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_eval
|
50
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
51
|
+
clusterer.build(DataSet.new(:data_items => @@data), 4)
|
52
|
+
assert_equal 2, clusterer.eval([0,8])
|
53
|
+
assert_equal 0, clusterer.eval([8,0])
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_create_distance_matrix
|
57
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
58
|
+
clusterer.create_distance_matrix(DataSet.new(:data_items => @@data))
|
59
|
+
assert clusterer.distance_matrix
|
60
|
+
clusterer.distance_matrix.each_with_index do |row, row_index|
|
61
|
+
assert_equal row_index+1, row.length
|
62
|
+
end
|
63
|
+
assert_equal @@expected_distance_matrix, clusterer.distance_matrix
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_read_distance_matrix
|
67
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
68
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
69
|
+
assert_equal 9.0, clusterer.read_distance_matrix(3, 2)
|
70
|
+
assert_equal 9.0, clusterer.read_distance_matrix(2, 3)
|
71
|
+
assert_equal 0, clusterer.read_distance_matrix(5, 5)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_linkage_distance
|
75
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
76
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
77
|
+
assert_equal 89, clusterer.linkage_distance(0,1,2)
|
78
|
+
assert_equal 1, clusterer.linkage_distance(4,2,5)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_get_closest_clusters
|
82
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
83
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
84
|
+
assert_equal [1,0], clusterer.get_closest_clusters([[0,1], [3,4]])
|
85
|
+
assert_equal [2,1], clusterer.get_closest_clusters([[3,4], [0,1], [5,6]])
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_create_initial_index_clusters
|
89
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
90
|
+
clusterer.data_set = DataSet.new :data_items => @@data
|
91
|
+
index_clusters = clusterer.create_initial_index_clusters
|
92
|
+
assert_equal @@data.length, index_clusters.length
|
93
|
+
assert_equal 0, index_clusters.first.first
|
94
|
+
assert_equal @@data.length-1, index_clusters.last.first
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_merge_clusters
|
98
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
99
|
+
clusters = clusterer.merge_clusters(1,2, [[1,2],[3,4],[5,6]])
|
100
|
+
assert_equal [[1,2], [3,4,5,6]], clusters.collect {|x| x.sort}
|
101
|
+
clusters = clusterer.merge_clusters(2,1, [[1,2],[3,4],[5,6]])
|
102
|
+
assert_equal [[1,2], [3,4,5,6]], clusters.collect {|x| x.sort}
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_distance_between_item_and_cluster
|
106
|
+
clusterer = Ai4r::Clusterers::SingleLinkage.new
|
107
|
+
assert_equal 8.0, clusterer.distance_between_item_and_cluster([1,2],
|
108
|
+
DataSet.new(:data_items => [[3,4],[5,6]]))
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
def draw_map(clusterer)
|
113
|
+
map = Array.new(11) {Array.new(11, 0)}
|
114
|
+
clusterer.clusters.each_index do |i|
|
115
|
+
clusterer.clusters[i].data_items.each do |point|
|
116
|
+
map[point.first][point.last]=(i+1)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
map.each { |row| puts row.inspect}
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Author:: Sergio Fierens (implementation)
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/clusterers/ward_linkage_hierarchical'
|
12
|
+
|
13
|
+
class Ai4r::Clusterers::WardLinkageHierarchical
|
14
|
+
attr_accessor :data_set, :number_of_clusters, :clusters, :distance_matrix, :index_clusters
|
15
|
+
end
|
16
|
+
|
17
|
+
class Ai4r::Clusterers::WardLinkageHierarchicalTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Ai4r::Clusterers
|
20
|
+
include Ai4r::Data
|
21
|
+
|
22
|
+
@@data = [ [10, 3], [3, 10], [2, 8], [2, 5], [3, 8], [10, 3],
|
23
|
+
[1, 3], [8, 1], [2, 9], [2, 5], [3, 3], [9, 4]]
|
24
|
+
|
25
|
+
@@expected_distance_matrix = [
|
26
|
+
[98.0],
|
27
|
+
[89.0, 5.0],
|
28
|
+
[68.0, 26.0, 9.0],
|
29
|
+
[74.0, 4.0, 1.0, 10.0],
|
30
|
+
[0.0, 98.0, 89.0, 68.0, 74.0],
|
31
|
+
[81.0, 53.0, 26.0, 5.0, 29.0, 81.0],
|
32
|
+
[8.0, 106.0, 85.0, 52.0, 74.0, 8.0, 53.0],
|
33
|
+
[100.0, 2.0, 1.0, 16.0, 2.0, 100.0, 37.0, 100.0],
|
34
|
+
[68.0, 26.0, 9.0, 0.0, 10.0, 68.0, 5.0, 52.0, 16.0],
|
35
|
+
[49.0, 49.0, 26.0, 5.0, 25.0, 49.0, 4.0, 29.0, 37.0, 5.0],
|
36
|
+
[2.0, 72.0, 65.0, 50.0, 52.0, 2.0, 65.0, 10.0, 74.0, 50.0, 37.0]]
|
37
|
+
|
38
|
+
def setup
|
39
|
+
Ai4r::Clusterers::WardLinkageHierarchical.send(:public,
|
40
|
+
*Ai4r::Clusterers::WardLinkageHierarchical.protected_instance_methods)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_linkage_distance
|
44
|
+
clusterer = Ai4r::Clusterers::WardLinkageHierarchical.new
|
45
|
+
clusterer.data_set = DataSet.new :data_items => @@data
|
46
|
+
clusterer.index_clusters = clusterer.create_initial_index_clusters
|
47
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
48
|
+
assert_in_delta 123.4166, clusterer.linkage_distance(0,1,2), 0.0001
|
49
|
+
assert_equal 27.75, clusterer.linkage_distance(4,2,5)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_cluster_tree
|
53
|
+
clusterer = Ai4r::Clusterers::WardLinkageHierarchical.new
|
54
|
+
clusterer.build(DataSet.new(:data_items => @@data), 1)
|
55
|
+
|
56
|
+
assert_equal clusterer.cluster_tree.length, @@data.length - 1
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Author:: Sergio Fierens (implementation)
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/clusterers/ward_linkage'
|
12
|
+
|
13
|
+
class Ai4r::Clusterers::WardLinkage
|
14
|
+
attr_accessor :data_set, :number_of_clusters, :clusters, :distance_matrix, :index_clusters
|
15
|
+
end
|
16
|
+
|
17
|
+
class Ai4r::Clusterers::WardLinkageTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Ai4r::Clusterers
|
20
|
+
include Ai4r::Data
|
21
|
+
|
22
|
+
@@data = [ [10, 3], [3, 10], [2, 8], [2, 5], [3, 8], [10, 3],
|
23
|
+
[1, 3], [8, 1], [2, 9], [2, 5], [3, 3], [9, 4]]
|
24
|
+
|
25
|
+
@@expected_distance_matrix = [
|
26
|
+
[98.0],
|
27
|
+
[89.0, 5.0],
|
28
|
+
[68.0, 26.0, 9.0],
|
29
|
+
[74.0, 4.0, 1.0, 10.0],
|
30
|
+
[0.0, 98.0, 89.0, 68.0, 74.0],
|
31
|
+
[81.0, 53.0, 26.0, 5.0, 29.0, 81.0],
|
32
|
+
[8.0, 106.0, 85.0, 52.0, 74.0, 8.0, 53.0],
|
33
|
+
[100.0, 2.0, 1.0, 16.0, 2.0, 100.0, 37.0, 100.0],
|
34
|
+
[68.0, 26.0, 9.0, 0.0, 10.0, 68.0, 5.0, 52.0, 16.0],
|
35
|
+
[49.0, 49.0, 26.0, 5.0, 25.0, 49.0, 4.0, 29.0, 37.0, 5.0],
|
36
|
+
[2.0, 72.0, 65.0, 50.0, 52.0, 2.0, 65.0, 10.0, 74.0, 50.0, 37.0]]
|
37
|
+
|
38
|
+
def setup
|
39
|
+
Ai4r::Clusterers::WardLinkage.send(:public,
|
40
|
+
*Ai4r::Clusterers::WardLinkage.protected_instance_methods)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_linkage_distance
|
44
|
+
clusterer = Ai4r::Clusterers::WardLinkage.new
|
45
|
+
clusterer.data_set = DataSet.new :data_items => @@data
|
46
|
+
clusterer.index_clusters = clusterer.create_initial_index_clusters
|
47
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
48
|
+
assert_in_delta 123.4166, clusterer.linkage_distance(0,1,2), 0.0001
|
49
|
+
assert_equal 27.75, clusterer.linkage_distance(4,2,5)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Author:: Sergio Fierens (implementation)
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/clusterers/weighted_average_linkage'
|
12
|
+
|
13
|
+
class Ai4r::Clusterers::WeightedAverageLinkage
|
14
|
+
attr_accessor :data_set, :number_of_clusters, :clusters, :distance_matrix, :index_clusters
|
15
|
+
end
|
16
|
+
|
17
|
+
class Ai4r::Clusterers::WeightedAverageLinkageTest < Test::Unit::TestCase
|
18
|
+
|
19
|
+
include Ai4r::Clusterers
|
20
|
+
include Ai4r::Data
|
21
|
+
|
22
|
+
@@data = [ [10, 3], [3, 10], [2, 8], [2, 5], [3, 8], [10, 3],
|
23
|
+
[1, 3], [8, 1], [2, 9], [2, 5], [3, 3], [9, 4]]
|
24
|
+
|
25
|
+
@@expected_distance_matrix = [
|
26
|
+
[98.0],
|
27
|
+
[89.0, 5.0],
|
28
|
+
[68.0, 26.0, 9.0],
|
29
|
+
[74.0, 4.0, 1.0, 10.0],
|
30
|
+
[0.0, 98.0, 89.0, 68.0, 74.0],
|
31
|
+
[81.0, 53.0, 26.0, 5.0, 29.0, 81.0],
|
32
|
+
[8.0, 106.0, 85.0, 52.0, 74.0, 8.0, 53.0],
|
33
|
+
[100.0, 2.0, 1.0, 16.0, 2.0, 100.0, 37.0, 100.0],
|
34
|
+
[68.0, 26.0, 9.0, 0.0, 10.0, 68.0, 5.0, 52.0, 16.0],
|
35
|
+
[49.0, 49.0, 26.0, 5.0, 25.0, 49.0, 4.0, 29.0, 37.0, 5.0],
|
36
|
+
[2.0, 72.0, 65.0, 50.0, 52.0, 2.0, 65.0, 10.0, 74.0, 50.0, 37.0]]
|
37
|
+
|
38
|
+
def setup
|
39
|
+
Ai4r::Clusterers::WeightedAverageLinkage.send(:public,
|
40
|
+
*Ai4r::Clusterers::WeightedAverageLinkage.protected_instance_methods)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_linkage_distance
|
44
|
+
clusterer = Ai4r::Clusterers::WeightedAverageLinkage.new
|
45
|
+
clusterer.data_set = DataSet.new :data_items => @@data
|
46
|
+
clusterer.index_clusters = clusterer.create_initial_index_clusters
|
47
|
+
clusterer.distance_matrix = @@expected_distance_matrix
|
48
|
+
assert_equal 93.5, clusterer.linkage_distance(0,1,2)
|
49
|
+
assert_equal 37.5, clusterer.linkage_distance(4,2,5)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Author:: Sergio Fierens
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/data/data_set'
|
12
|
+
|
13
|
+
module Ai4r
|
14
|
+
module Data
|
15
|
+
class DataSetTest < Test::Unit::TestCase
|
16
|
+
|
17
|
+
def test_load_csv_with_labels
|
18
|
+
set = DataSet.new.load_csv_with_labels("#{File.dirname(__FILE__)}/data_set.csv")
|
19
|
+
assert_equal 120, set.data_items.length
|
20
|
+
assert_equal ["zone", "rooms", "size", "price"], set.data_labels
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_build_domains
|
24
|
+
domains = [ Set.new(["New York", "Chicago"]),
|
25
|
+
Set.new(["M", "F"]),
|
26
|
+
[5, 85],
|
27
|
+
Set.new(["Y", "N"]) ]
|
28
|
+
data = [ [ "New York", "M", 23, "Y"],
|
29
|
+
[ "Chicago", "M", 85, "Y"],
|
30
|
+
[ "New York", "F", 32, "Y"],
|
31
|
+
[ "New York", "M", 5, "N"],
|
32
|
+
[ "Chicago", "M", 15, "N"],
|
33
|
+
[ "Chicago", "F", 45, "Y"] ]
|
34
|
+
labels = ["city", "gender", "age", "result"]
|
35
|
+
set = DataSet.new({:data_items => data, :data_labels => labels})
|
36
|
+
assert_equal domains, set.build_domains
|
37
|
+
assert_equal domains[0], set.build_domain("city")
|
38
|
+
assert_equal domains[1], set.build_domain(1)
|
39
|
+
assert_equal domains[2], set.build_domain("age")
|
40
|
+
assert_equal domains[3], set.build_domain("result")
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_set_data_labels
|
44
|
+
labels = ["A", "B"]
|
45
|
+
set = DataSet.new.set_data_labels(labels)
|
46
|
+
assert_equal labels, set.data_labels
|
47
|
+
set = DataSet.new(:data_labels => labels)
|
48
|
+
assert_equal labels, set.data_labels
|
49
|
+
set = DataSet.new(:data_items => [[ 1, 2, 3]])
|
50
|
+
assert_raise(ArgumentError) { set.set_data_labels(labels) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_set_data_items
|
54
|
+
items = [ [ "New York", "M", "Y"],
|
55
|
+
[ "Chicago", "M", "Y"],
|
56
|
+
[ "New York", "F", "Y"],
|
57
|
+
[ "New York", "M", "N"],
|
58
|
+
[ "Chicago", "M", "N"],
|
59
|
+
[ "Chicago", "F", "Y"] ]
|
60
|
+
set = DataSet.new.set_data_items(items)
|
61
|
+
assert_equal items, set.data_items
|
62
|
+
assert_equal 3, set.data_labels.length
|
63
|
+
items << items.first[0..-2]
|
64
|
+
assert_raise(ArgumentError) { set.set_data_items(items) }
|
65
|
+
assert_raise(ArgumentError) { set.set_data_items(nil) }
|
66
|
+
assert_raise(ArgumentError) { set.set_data_items([1]) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_get_mean_or_mode
|
70
|
+
items = [ [ "New York", 25, "Y"],
|
71
|
+
[ "New York", 55, "Y"],
|
72
|
+
[ "Chicago", 23, "Y"],
|
73
|
+
[ "Boston", 23, "N"],
|
74
|
+
[ "Chicago", 12, "N"],
|
75
|
+
[ "Chicago", 87, "Y"] ]
|
76
|
+
set = DataSet.new.set_data_items(items)
|
77
|
+
assert_equal ["Chicago", 37.5, "Y"], set.get_mean_or_mode
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_index
|
81
|
+
items = [ [ "New York", 25, "Y"],
|
82
|
+
[ "New York", 55, "Y"],
|
83
|
+
[ "Chicago", 23, "Y"],
|
84
|
+
[ "Boston", 23, "N"],
|
85
|
+
[ "Chicago", 12, "N"],
|
86
|
+
[ "Chicago", 87, "Y"] ]
|
87
|
+
set = DataSet.new.set_data_items(items)
|
88
|
+
assert_equal set.data_labels, set[0].data_labels
|
89
|
+
assert_equal [[ "New York", 25, "Y"]], set[0].data_items
|
90
|
+
assert_equal [[ "Chicago", 23, "Y"],[ "Boston", 23, "N"]], set[2..3].data_items
|
91
|
+
assert_equal items[1..-1], set[1..-1].data_items
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Author:: Sergio Fierens
|
2
|
+
# License:: MPL 1.1
|
3
|
+
# Project:: ai4r
|
4
|
+
# Url:: http://ai4r.rubyforge.org/
|
5
|
+
#
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Mozilla Public License version 1.1 as published by the
|
8
|
+
# Mozilla Foundation at http://www.mozilla.org/MPL/MPL-1.1.txt
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require File.dirname(__FILE__) + '/../../lib/ai4r/data/proximity'
|
12
|
+
|
13
|
+
module Ai4r
|
14
|
+
module Data
|
15
|
+
class ProximityTest < Test::Unit::TestCase
|
16
|
+
|
17
|
+
@@delta = 0.0001
|
18
|
+
@@data1 = [rand*10, rand*10, rand*-10]
|
19
|
+
@@data2 = [rand*10, rand*-10, rand*10]
|
20
|
+
|
21
|
+
def test_squared_euclidean_distance
|
22
|
+
assert_equal 0, Proximity.squared_euclidean_distance(@@data1, @@data1)
|
23
|
+
assert_equal Proximity.squared_euclidean_distance(@@data1, @@data2),
|
24
|
+
Proximity.squared_euclidean_distance(@@data2, @@data1)
|
25
|
+
assert 0 <= Proximity.squared_euclidean_distance(@@data1, @@data1)
|
26
|
+
assert_equal 2, Proximity.squared_euclidean_distance([1,1], [2,2])
|
27
|
+
assert_equal 9, Proximity.squared_euclidean_distance([3], [0])
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_euclidean_distance
|
31
|
+
assert_equal 0, Proximity.euclidean_distance(@@data1, @@data1)
|
32
|
+
assert_equal Proximity.euclidean_distance(@@data1, @@data2),
|
33
|
+
Proximity.euclidean_distance(@@data2, @@data1)
|
34
|
+
assert 0 <= Proximity.euclidean_distance(@@data1, @@data1)
|
35
|
+
assert_equal Math.sqrt(2), Proximity.euclidean_distance([1,1], [2,2])
|
36
|
+
assert_equal 3, Proximity.euclidean_distance([3], [0])
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_manhattan_distance
|
40
|
+
assert_equal 0, Proximity.manhattan_distance(@@data1, @@data1)
|
41
|
+
assert_equal Proximity.manhattan_distance(@@data1, @@data2),
|
42
|
+
Proximity.manhattan_distance(@@data2, @@data1)
|
43
|
+
assert 0 <= Proximity.manhattan_distance(@@data1, @@data1)
|
44
|
+
assert_equal 2, Proximity.manhattan_distance([1,1], [2,2])
|
45
|
+
assert_equal 9, Proximity.manhattan_distance([1,10], [2,2])
|
46
|
+
assert_equal 3, Proximity.manhattan_distance([3], [0])
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_sup_distance
|
50
|
+
assert_equal 0, Proximity.sup_distance(@@data1, @@data1)
|
51
|
+
assert_equal Proximity.sup_distance(@@data1, @@data2),
|
52
|
+
Proximity.sup_distance(@@data2, @@data1)
|
53
|
+
assert 0 <= Proximity.sup_distance(@@data1, @@data1)
|
54
|
+
assert_equal 1, Proximity.sup_distance([1,1], [2,2])
|
55
|
+
assert_equal 8, Proximity.sup_distance([1,10], [2,2])
|
56
|
+
assert_equal 3, Proximity.sup_distance([3], [0])
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_hamming_distance
|
60
|
+
assert_equal 0, Proximity.hamming_distance(@@data1, @@data1)
|
61
|
+
assert_equal Proximity.hamming_distance(@@data1, @@data2),
|
62
|
+
Proximity.hamming_distance(@@data2, @@data1)
|
63
|
+
assert 0 <= Proximity.hamming_distance(@@data1, @@data1)
|
64
|
+
assert_equal 1, Proximity.hamming_distance([1,1], [0,1])
|
65
|
+
assert_equal 2, Proximity.hamming_distance([1,10], [2,2])
|
66
|
+
assert_equal 1, Proximity.hamming_distance([3], [0])
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_simple_matching_distance
|
70
|
+
assert_equal 0, Proximity.simple_matching_distance(@@data1, @@data1)
|
71
|
+
assert_equal Proximity.simple_matching_distance(@@data1, @@data2),
|
72
|
+
Proximity.simple_matching_distance(@@data2, @@data1)
|
73
|
+
assert 0 <= Proximity.simple_matching_distance(@@data1, @@data1)
|
74
|
+
assert_equal 1, Proximity.simple_matching_distance([1,2], [0,1])
|
75
|
+
assert_equal 1.0/0, Proximity.simple_matching_distance([1,10], [2,2])
|
76
|
+
assert_equal 1.0/0, Proximity.simple_matching_distance([3], [0])
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|