class MultiDimensionalKMeans

Attributes

centroids[RW]
clusters[RW]
dimension[RW]
old_centroids[RW]

Public Class Methods

new(inputs, dimen) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 31
def initialize(inputs, dimen)
        @dimension = dimen
        @centroids = Array.new
        for i in 0...inputs
                @centroids[i] = Point.new zeros()
        end
end

Public Instance Methods

build(points) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 60
def build(points)
        # Calcular centroides aleatorios
        kmeansPoints = generateKmeansPoints(points)
        # Modificar función initialize_random_centroids
        @old_centroids = Array.new @centroids
        initialize_random_centroids kmeansPoints
        while stop_condition
                @clusters = Array.new @centroids.length
                for i in 0...@clusters.length
                                clusters[i] = Array.new
                end
                # Meter cada punto a su cluster mas cercano
                for i in 0...points.length
                        clusters[eval(points[i])].push Point.new(points[i])
                        # clusters[eval(x[i], y[i], z[i])].push Point.new x[i], y[i], z[i]
                end
                @old_centroids = Array.new @centroids
                update_centroids kmeansPoints
        end
        cen, clus = @centroids, @clusters
end
eval(point) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 102
def eval(point)
        p = Point.new point
        distancias = Array.new @centroids.length
        for i in 0...distancias.length
                distancias[i] = p.distance @centroids[i]
        end
        min_dis = distancias.min
        min_idx = distancias.find_index min_dis
        ret = min_idx
end
generateKmeansPoints(points) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 47
def generateKmeansPoints(points)
        retArr = Array.new points[0].size
        for i in 0...retArr.size
                retArr[i] = Array.new
        end
        for i in 0...points[0].size
                for j in 0...points.size
                        retArr[i][j] = points[j][i]
                end
        end
        return retArr
end
initialize_random_centroids(points) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 94
def initialize_random_centroids(points)
        @old_centroids = Array.new @centroids
        for i in 0...@centroids.length
                arr = randomizeCentroid(points)
                @centroids[i] = Point.new arr
        end
end
randomizeCentroid(points) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 86
def randomizeCentroid(points)
        centroidArray = Array.new points.size
        for i in 0...points.size
                centroidArray[i] = randomizeSubarray points[i]
        end
        return centroidArray
end
randomizeSubarray(arr) click to toggle source
# File lib/MultiDimensional KMeans.rb, line 82
def randomizeSubarray(arr)
        random = rand(arr.max - arr.min) + arr.min
end
stop_condition() click to toggle source
# File lib/MultiDimensional KMeans.rb, line 174
def stop_condition
        ending = false
        for i in 0...@centroids.size
                fin = false
                if !@centroids[i].equals @old_centroids[i]
                        ending = true
                        break
                end
        end
        ret = ending
end
update_centroids(points) click to toggle source

Modificando

# File lib/MultiDimensional KMeans.rb, line 114
def update_centroids(points)
        @old_centroids = Array.new @centroids
        reinitialize = false
        for i in 0...@clusters.length
                puts "Cluster " + (i+1).to_s + " tiene " + @clusters[i].length.to_s
                if @clusters[i].length < 2
                        reinitialize = true
                end
        end
        if reinitialize
                initialize_random_centroids points
        else
                minimus = Array.new points.size
                maximus = Array.new points.size
                for i in 0...@centroids.length
                                for j in 0...minimus.size
                                        minimus[j] = Float::INFINITY
                                        maximus[j] = 0
                                end
                                # min_x = Float::INFINITY
                                # min_y = Float::INFINITY
                                # min_z = Float::INFINITY
                                # max_x = 0
                                # max_y = 0
                                # max_z = 0
                                for j in 0...@clusters[i].length
                                        # Verificar cada cluster para actualizar minimos y maximos
                                        for k in 0...minimus.size
                                                if @clusters[i][j].values[k] < minimus[k]
                                                        minimus[k] = @clusters[i][j].values[k]
                                                elsif @clusters[i][j].values[k] > maximus[k]
                                                        maximus[k] = @clusters[i][j].values[k]
                                                end
                                        end
                                        # if clusters[i][j].x < min_x
                                                # min_x = clusters[i][j].x
                                        # elsif clusters[i][j].x > max_x
                                                # max_x = clusters[i][j].x
                                        # end
                                        # if clusters[i][j].y < min_y
                                                # min_y = clusters[i][j].y
                                        # elsif clusters[i][j].y > max_y
                                                # max_y = clusters[i][j].y
                                        # end
                                        # if clusters[i][j].z < min_z
                                                # min_z = clusters[i][j].z
                                        # elsif clusters[i][j].z > max_z
                                                # max_z = clusters[i][j].z
                                        # end
                                end
                                newPoint = Array.new minimus.size
                                for x in 0...newPoint.size
                                        newPoint[x] = (maximus[x]-minimus[x])/2 + minimus[x]
                                end
                                @centroids[i] = Point.new newPoint
                                # @centroids[i] = Point.new (max_x-min_x)/2+min_x, (max_y-min_y)/2+min_y, (max_z-min_z)/2+min_z
                        end
        end
end
zeros() click to toggle source
# File lib/MultiDimensional KMeans.rb, line 39
def zeros()
        arr = Array.new
        for i in 0...@dimension
                arr[i] = 0
        end
        return arr
end