NDKMeans 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d4c4f0b227178a699448686ead2882ff579ecf74
4
+ data.tar.gz: 9438ccf1c1bbda0cf556671e779189cae0907150
5
+ SHA512:
6
+ metadata.gz: 1bdf489a238cf029f9fc2c674ae819486789b5e9b9b91403ced30d16b4758703f6c8570a0508392a153ea8a15ee5745d5b83b56c1854571c19d2066fd610807f
7
+ data.tar.gz: 9ce04af21cc3d7ff910ace41b1f57e00b2222170288b1d0ff253a3fca7067fc49cc6502b3f7eb586229777cd081194c77f46dc772ba8e018ba0dfa061f561b9f
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
@@ -0,0 +1,10 @@
1
+ #! /bin/ruby
2
+ require 'MultiDimensional KMeans'
3
+
4
+ test = MultiDimensionalKMeans.new 3, 4
5
+ points = [[0,0,0,0], [1,1,1,1], [2,2,2,2], [3,3,3,3], [4,4,4,4], [1,2,3,4], [4,3,2,1]]
6
+ centroids, clusters = test.build points
7
+ for i in 0...centroids.size
8
+ puts "CENTROID: " + centroids[i].to_s
9
+ puts "Cluster: " + clusters[i].to_s
10
+ end
@@ -0,0 +1,190 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require "gnuplot"
3
+ require "rubygems"
4
+ require 'csv'
5
+ require 'pp'
6
+
7
+ class Point
8
+ attr_accessor :values
9
+ def initialize(values)
10
+ @values = values
11
+ end
12
+ def to_s
13
+ return @values.to_s
14
+ end
15
+ def distance(p)
16
+ dis = 0
17
+ for i in 0...@values.length
18
+ dis = dis + (p.values[i] - @values[i])**2
19
+ end
20
+ ret = Math.sqrt(dis)
21
+ end
22
+ def equals(p)
23
+ eq = true
24
+ for i in 0...@values.size
25
+ if p.values[i] != @values[i]
26
+ eq = false
27
+ end
28
+ end
29
+ return eq
30
+ end
31
+ end
32
+
33
+ class MultiDimensionalKMeans
34
+ attr_accessor :centroids, :old_centroids, :clusters, :dimension
35
+ def initialize(inputs, dimen)
36
+ @dimension = dimen
37
+ @centroids = Array.new
38
+ for i in 0...inputs
39
+ @centroids[i] = Point.new zeros()
40
+ end
41
+ end
42
+
43
+ def zeros()
44
+ arr = Array.new
45
+ for i in 0...@dimension
46
+ arr[i] = 0
47
+ end
48
+ return arr
49
+ end
50
+
51
+ def generateKmeansPoints(points)
52
+ retArr = Array.new points[0].size
53
+ for i in 0...retArr.size
54
+ retArr[i] = Array.new
55
+ end
56
+ for i in 0...points[0].size
57
+ for j in 0...points.size
58
+ retArr[i][j] = points[j][i]
59
+ end
60
+ end
61
+ return retArr
62
+ end
63
+
64
+ def build(points)
65
+ # Calcular centroides aleatorios
66
+ kmeansPoints = generateKmeansPoints(points)
67
+ # Modificar función initialize_random_centroids
68
+ @old_centroids = Array.new @centroids
69
+ initialize_random_centroids kmeansPoints
70
+ while stop_condition
71
+ @clusters = Array.new @centroids.length
72
+ for i in 0...@clusters.length
73
+ clusters[i] = Array.new
74
+ end
75
+ # Meter cada punto a su cluster mas cercano
76
+ for i in 0...points.length
77
+ clusters[eval(points[i])].push Point.new(points[i])
78
+ # clusters[eval(x[i], y[i], z[i])].push Point.new x[i], y[i], z[i]
79
+ end
80
+ @old_centroids = Array.new @centroids
81
+ update_centroids kmeansPoints
82
+ end
83
+ cen, clus = @centroids, @clusters
84
+ end
85
+
86
+ def randomizeSubarray(arr)
87
+ random = rand(arr.max - arr.min) + arr.min
88
+ end
89
+
90
+ def randomizeCentroid(points)
91
+ centroidArray = Array.new points.size
92
+ for i in 0...points.size
93
+ centroidArray[i] = randomizeSubarray points[i]
94
+ end
95
+ return centroidArray
96
+ end
97
+
98
+ def initialize_random_centroids(points)
99
+ @old_centroids = Array.new @centroids
100
+ for i in 0...@centroids.length
101
+ arr = randomizeCentroid(points)
102
+ @centroids[i] = Point.new arr
103
+ end
104
+ end
105
+
106
+ def eval(point)
107
+ p = Point.new point
108
+ distancias = Array.new @centroids.length
109
+ for i in 0...distancias.length
110
+ distancias[i] = p.distance @centroids[i]
111
+ end
112
+ min_dis = distancias.min
113
+ min_idx = distancias.find_index min_dis
114
+ ret = min_idx
115
+ end
116
+
117
+ # Modificando
118
+ def update_centroids(points)
119
+ @old_centroids = Array.new @centroids
120
+ reinitialize = false
121
+ for i in 0...@clusters.length
122
+ puts "Cluster " + (i+1).to_s + " tiene " + @clusters[i].length.to_s
123
+ if @clusters[i].length < 2
124
+ reinitialize = true
125
+ end
126
+ end
127
+ if reinitialize
128
+ initialize_random_centroids points
129
+ else
130
+ minimus = Array.new points.size
131
+ maximus = Array.new points.size
132
+ for i in 0...@centroids.length
133
+ for j in 0...minimus.size
134
+ minimus[j] = Float::INFINITY
135
+ maximus[j] = 0
136
+ end
137
+ # min_x = Float::INFINITY
138
+ # min_y = Float::INFINITY
139
+ # min_z = Float::INFINITY
140
+ # max_x = 0
141
+ # max_y = 0
142
+ # max_z = 0
143
+ for j in 0...@clusters[i].length
144
+ # Verificar cada cluster para actualizar minimos y maximos
145
+ for k in 0...minimus.size
146
+ if @clusters[i][j].values[k] < minimus[k]
147
+ minimus[k] = @clusters[i][j].values[k]
148
+ elsif @clusters[i][j].values[k] > maximus[k]
149
+ maximus[k] = @clusters[i][j].values[k]
150
+ end
151
+ end
152
+ # if clusters[i][j].x < min_x
153
+ # min_x = clusters[i][j].x
154
+ # elsif clusters[i][j].x > max_x
155
+ # max_x = clusters[i][j].x
156
+ # end
157
+ # if clusters[i][j].y < min_y
158
+ # min_y = clusters[i][j].y
159
+ # elsif clusters[i][j].y > max_y
160
+ # max_y = clusters[i][j].y
161
+ # end
162
+ # if clusters[i][j].z < min_z
163
+ # min_z = clusters[i][j].z
164
+ # elsif clusters[i][j].z > max_z
165
+ # max_z = clusters[i][j].z
166
+ # end
167
+ end
168
+ newPoint = Array.new minimus.size
169
+ for x in 0...newPoint.size
170
+ newPoint[x] = (maximus[x]-minimus[x])/2 + minimus[x]
171
+ end
172
+ @centroids[i] = Point.new newPoint
173
+ # @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
174
+ end
175
+ end
176
+ end
177
+
178
+ def stop_condition
179
+ ending = false
180
+ for i in 0...@centroids.size
181
+ fin = false
182
+ if !@centroids[i].equals @old_centroids[i]
183
+ ending = true
184
+ break
185
+ end
186
+ end
187
+ ret = ending
188
+ end
189
+
190
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: NDKMeans
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Salvador Guerra Delgado
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-10-12 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Multi dimensional K-Means clustering algorithm
14
+ email: salvador.guerra.delgado2@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Rakefile
20
+ - bin/TestMultiDimension
21
+ - lib/MultiDimensional KMeans.rb
22
+ homepage: http://rubygems.org/gems/SEATC
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.5.2.1
43
+ signing_key:
44
+ specification_version: 3
45
+ summary: SEATC
46
+ test_files: []