class Ai4r::Som::Som

Introduction

This is an implementation of a Kohonen Self-Organizing Maps

Features

Parameters

About the project

Author

Thomas Kern

License

MPL 1.1

Url

ai4r.org

Public Class Methods

new(dim, number_of_nodes, layer) click to toggle source
# File lib/ai4r/som/som.rb, line 61
def initialize(dim, number_of_nodes, layer)
  @layer = layer
  @dimension = dim
  @number_of_nodes = number_of_nodes
  @nodes = Array.new(number_of_nodes * number_of_nodes)
  @epoch = 0
  @cache = {}
end

Public Instance Methods

adjust_nodes(input, bmu, radius, learning_rate) click to toggle source

adjusts all nodes within a certain radius to the bmu

# File lib/ai4r/som/som.rb, line 87
def adjust_nodes(input, bmu, radius, learning_rate)
  @nodes.each do |node|
    dist = node.distance_to_node(bmu[0])
    next unless dist < radius

    influence = @layer.influence_decay dist, radius
    node.weights.each_with_index do |weight, index|
      node.weights[index] +=  influence * learning_rate * (input[index] - weight)
    end
  end
end
find_bmu(input) click to toggle source

finds the best matching unit (bmu) of a certain input in all the @nodes returns an array of length 2 => [node, distance] (distance is of eucledian type, not a neighborhood distance)

# File lib/ai4r/som/som.rb, line 73
def find_bmu(input)
  bmu = @nodes.first
  dist = bmu.distance_to_input input
  @nodes[1..-1].each do |node|
    tmp_dist = node.distance_to_input(input)
    if tmp_dist <= dist
      dist = tmp_dist
      bmu = node
    end
  end
  [bmu, dist]
end
get_node(x, y) click to toggle source

returns the node at position (x,y) in the square map

# File lib/ai4r/som/som.rb, line 131
def get_node(x, y)
  raise(Exception.new) if check_param_for_som(x,y)
  @nodes[y + x * @number_of_nodes]
end
global_error(data) click to toggle source

calculates the global distance error for all data entries

# File lib/ai4r/som/som.rb, line 107
def global_error(data)
  data.inject(0) {|sum,entry| sum + find_bmu(entry)[1]**2 }
 end
initiate_map() click to toggle source

intitiates the map by creating (@number_of_nodes * @number_of_nodes) nodes

# File lib/ai4r/som/som.rb, line 137
def initiate_map
  @nodes.each_with_index do |node, i|
    @nodes[i] = Node.create i, @number_of_nodes, @dimension
  end
end
train(data) click to toggle source

main method for the som. trains the map with the passed data vector calls #train_step as long as #train_step returns false

# File lib/ai4r/som/som.rb, line 101
def train(data)
  while !train_step(data)
  end
end
train_step(data) click to toggle source

trains the map with the data as long as the @epoch is smaller than the epoch-value of @layer returns true if @epoch is greater than the fixed epoch-value in @layer, otherwise false 1 is added to @epoch at each method call the radius and learning rate is decreased at each method call/epoch as well

# File lib/ai4r/som/som.rb, line 116
def train_step(data)
  return true if @epoch >= @layer.epochs

  radius = @layer.radius_decay @epoch
  learning_rate = @layer.learning_rate_decay @epoch

  data.each do |entry|
    adjust_nodes entry, find_bmu(entry), radius, learning_rate
  end

  @epoch += 1
  false
end

Private Instance Methods

check_param_for_som(x, y) click to toggle source

checks whether or not there is a node in the map at the coordinates (x,y). x is the row, y the column indicator

# File lib/ai4r/som/som.rb, line 147
def check_param_for_som(x, y)
  y > @number_of_nodes - 1 || x > @number_of_nodes - 1  || x < 0 || y < 0
end