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.
@@ -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) #Default: false
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.3
1
+ 0.0.4
@@ -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.5
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
- next if node.distance_from(closest_node.weights) > decayed_radius
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
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{som}
8
- s.version = "0.0.3"
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{2009-11-30}
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",
Binary file
@@ -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.3
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: 2009-11-30 00:00:00 +00:00
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