som 0.0.3 → 0.0.4
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 +19 -1
- data/VERSION +1 -1
- data/examples/example.rb +4 -5
- data/lib/som.rb +28 -3
- data/som.gemspec +3 -2
- data/spec/db/som.som +0 -0
- data/spec/som_spec.rb +32 -0
- metadata +3 -2
data/README.rdoc
CHANGED
@@ -32,13 +32,31 @@ A pure Ruby implementation of the Self Organising Map machine learning algorithm
|
|
32
32
|
a.inspect
|
33
33
|
#=> [[0, [1, 0...]], [1, [99, 84...]], [2, [11, 23...]]]
|
34
34
|
|
35
|
+
You can also save your SOM and load a previously save SOM:
|
36
|
+
|
37
|
+
require 'rubygems'
|
38
|
+
require 'som'
|
39
|
+
|
40
|
+
data = [[1,2,3], [4,5,6]...]
|
41
|
+
|
42
|
+
a = SOM.new(data, :number_of_nodes => 4,
|
43
|
+
:dimensions => 3,
|
44
|
+
:save_to => 'file_path/to/here.som')
|
45
|
+
|
46
|
+
a.train # Saves it
|
47
|
+
|
48
|
+
b = SOM.load('file_path/to/here.som') # Loads it
|
49
|
+
|
50
|
+
b.classify(new_data) # etc...
|
51
|
+
|
35
52
|
== Options
|
36
53
|
|
37
54
|
SOM.new(data, :number_of_nodes => 1, #Default: 5
|
38
55
|
:learning_rate => 0.7, #Default: 0.5
|
39
56
|
:radius => 1, #Default: number_of_nodes / 2
|
40
57
|
:max_iterations => 100, #Default: 100
|
41
|
-
:verbose => true
|
58
|
+
:verbose => true, #Default: false
|
59
|
+
:save_to => 'file_path') #Default: nil
|
42
60
|
|
43
61
|
== Copyright
|
44
62
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/examples/example.rb
CHANGED
@@ -17,17 +17,16 @@ SOM_DATA.each do |n|
|
|
17
17
|
data << normalizer.normalize(n)
|
18
18
|
end
|
19
19
|
|
20
|
-
a = SOM.new(data, :nodes => 8
|
21
|
-
:radius => 0.8)
|
20
|
+
a = SOM.new(data, :nodes => 8)
|
22
21
|
|
23
|
-
puts a.global_distance_error
|
22
|
+
#puts a.global_distance_error
|
24
23
|
|
25
24
|
times = Benchmark.measure do
|
26
25
|
a.train
|
27
26
|
end
|
28
27
|
|
29
|
-
puts a.global_distance_error
|
28
|
+
#puts a.global_distance_error
|
30
29
|
|
31
30
|
#puts a.nodes.inspect
|
32
31
|
|
33
|
-
puts times
|
32
|
+
#puts times
|
data/lib/som.rb
CHANGED
@@ -2,6 +2,18 @@ require File.expand_path(File.dirname(__FILE__) + '/som/node')
|
|
2
2
|
|
3
3
|
class SOM
|
4
4
|
|
5
|
+
class << self
|
6
|
+
def load(db_filepath)
|
7
|
+
data = ""
|
8
|
+
File.open(db_filepath) do |f|
|
9
|
+
while line = f.gets
|
10
|
+
data << line
|
11
|
+
end
|
12
|
+
end
|
13
|
+
Marshal.load(data)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
5
17
|
def initialize(training_data, options={})
|
6
18
|
@training_data = training_data
|
7
19
|
@dimensions = training_data[0].size
|
@@ -9,9 +21,10 @@ class SOM
|
|
9
21
|
|
10
22
|
# Options
|
11
23
|
@number_of_nodes = options[:nodes] || 5
|
12
|
-
@learning_rate = options[:learning_rate] || 0.
|
24
|
+
@learning_rate = options[:learning_rate] || 0.7
|
13
25
|
@radius = options[:radius] || @number_of_nodes / 2
|
14
26
|
@max_iterations = options[:max_iterations] || 100
|
27
|
+
@db_filepath = options[:save_to]
|
15
28
|
|
16
29
|
# TODO: Allow a lambda so we can use different neighborhood functions
|
17
30
|
@neighborhood_function = 1 #options[:neighborhood_function] || 1
|
@@ -30,6 +43,7 @@ class SOM
|
|
30
43
|
# Place the data in the nodes buckets so we can see how
|
31
44
|
# The data has been clustered
|
32
45
|
place_data_into_buckets(@training_data)
|
46
|
+
save
|
33
47
|
end
|
34
48
|
|
35
49
|
# Returns an array of buckets containing the index of the training data
|
@@ -56,6 +70,14 @@ class SOM
|
|
56
70
|
|
57
71
|
private
|
58
72
|
|
73
|
+
def save
|
74
|
+
if @db_filepath
|
75
|
+
File.open(@db_filepath, "w+") do |f|
|
76
|
+
f.write Marshal.dump(self)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
59
81
|
def train_it!(data)
|
60
82
|
return false if @iteration_count >= @max_iterations
|
61
83
|
|
@@ -73,9 +95,12 @@ class SOM
|
|
73
95
|
# Update nodes that closer than the radius
|
74
96
|
other_nodes = nodes - [closest_node]
|
75
97
|
other_nodes.each_with_index do |node, index|
|
76
|
-
|
98
|
+
distance_from_node = node.distance_from(closest_node.weights)
|
99
|
+
print_message("\t\tDistance from node: #{distance_from_node}")
|
100
|
+
|
101
|
+
next if distance_from_node > decayed_radius
|
77
102
|
|
78
|
-
print_message("\t\tUpdating other nodes: #{index+1}/#{other_nodes.size}")
|
103
|
+
print_message("\t\t\tUpdating other nodes: #{index+1}/#{other_nodes.size}")
|
79
104
|
|
80
105
|
node.update_weight(@learning_rate, input, neighborhood_function)
|
81
106
|
end
|
data/som.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{som}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["reddavis"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-05}
|
13
13
|
s.description = %q{A Self Organising Map}
|
14
14
|
s.email = %q{reddavis@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
"lib/som.rb",
|
29
29
|
"lib/som/node.rb",
|
30
30
|
"som.gemspec",
|
31
|
+
"spec/db/som.som",
|
31
32
|
"spec/node_spec.rb",
|
32
33
|
"spec/som_spec.rb",
|
33
34
|
"spec/spec.opts",
|
data/spec/db/som.som
ADDED
Binary file
|
data/spec/som_spec.rb
CHANGED
@@ -89,4 +89,36 @@ describe "Som" do
|
|
89
89
|
@a.global_distance_error.should be_a(Float)
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
describe "Saving" do
|
94
|
+
before do
|
95
|
+
data = [[0,0], [999,999]]
|
96
|
+
@a = SOM.new(data, :nodes => 5, :save_to => save_to_filepath)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should save the SOM where specified" do
|
100
|
+
FileUtils.rm(save_to_filepath, :force => true)
|
101
|
+
@a.train
|
102
|
+
File.exists?(save_to_filepath).should be_true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "Loading" do
|
107
|
+
before do |variable|
|
108
|
+
data = [[0,0], [999,999]]
|
109
|
+
a = SOM.new(data, :nodes => 5, :save_to => save_to_filepath)
|
110
|
+
a.train
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should have 5 nodes" do
|
114
|
+
a = SOM.load(save_to_filepath)
|
115
|
+
a.nodes.size.should == 5
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def save_to_filepath
|
122
|
+
File.expand_path(File.dirname(__FILE__) + '/db/som.som')
|
123
|
+
end
|
92
124
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: som
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- reddavis
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date:
|
12
|
+
date: 2010-01-05 00:00:00 +00:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -43,6 +43,7 @@ files:
|
|
43
43
|
- lib/som.rb
|
44
44
|
- lib/som/node.rb
|
45
45
|
- som.gemspec
|
46
|
+
- spec/db/som.som
|
46
47
|
- spec/node_spec.rb
|
47
48
|
- spec/som_spec.rb
|
48
49
|
- spec/spec.opts
|