Class: ClusterCalculator

Inherits:
Object
  • Object
show all
Defined in:
lib/quadtone/cluster_calculator.rb

Overview

after:

http://colinfdrake.com/2011/05/28/clustering-in-ruby.html
http://m635j520.blogspot.com/2013/02/implementing-k-means-clustering-in-ruby.html

Defined Under Namespace

Classes: Cluster

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ ClusterCalculator

Returns a new instance of ClusterCalculator.



51
52
53
54
55
56
57
# File 'lib/quadtone/cluster_calculator.rb', line 51

def initialize(params={})
  @delta = 0.001
  params.each { |k, v| send("#{k}=", v) }
  raise "Must specify samples" unless @samples
  raise "Must specify max_clusters" unless @max_clusters
  @max_clusters = @samples.length if @max_clusters > @samples.length
end

Instance Attribute Details

#clustersObject

Returns the value of attribute clusters.



49
50
51
# File 'lib/quadtone/cluster_calculator.rb', line 49

def clusters
  @clusters
end

#deltaObject

Returns the value of attribute delta.



48
49
50
# File 'lib/quadtone/cluster_calculator.rb', line 48

def delta
  @delta
end

#max_clustersObject

Returns the value of attribute max_clusters.



47
48
49
# File 'lib/quadtone/cluster_calculator.rb', line 47

def max_clusters
  @max_clusters
end

#samplesObject

Returns the value of attribute samples.



46
47
48
# File 'lib/quadtone/cluster_calculator.rb', line 46

def samples
  @samples
end

Instance Method Details

#cluster!Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/quadtone/cluster_calculator.rb', line 59

def cluster!
  @clusters = @max_clusters.times.map { Cluster.new(@samples.sample.output) }
  while @clusters.any?(&:moved)
    @clusters.each(&:clear_samples)
    @samples.each do |sample|
      shortest = Float::INFINITY
      cluster_found = nil
      @clusters.each do |cluster|
        distance = cluster.distance_to(sample)
        if distance < shortest
          cluster_found = cluster
          shortest = distance
        end
      end
      cluster_found.add_sample(sample) if cluster_found
    end
    @clusters.delete_if { |c| c.size == 0 }
    @clusters.each { |c| c.update_center(@delta) }
  end

end