import copy
import math
class obj_kMeans:
def __init__(self,init_centroid,k):
self.k = k
self.clusters = None
self.centroids = np.empty((self.k,2))
self.initial_centroid = init_centroid
def distance(self,x,y):
return np.linalg.norm(y-x, ord=2)
def init_centroids(self, x):
centroids = self.centroids
centroids[0] = self.initial_centroid
for i in range(1, self.k):
d_max = 0
d_max_cen = centroids[0]
for x_i in x:
if x_i in centroids:
continue
xi_distance = sum([self.distance(x_i, prev) for prev in centroids]
if xi_distance > d_max:
d_max = xi_distance
d_max_cen = x_i
centroids[i] = d_max_cen
return centroids
def cost_function(self,clusters):
squared_errors = list()
for i in range(self.k):
points = clusters[i][1]
centroid = clusters[i][0]
errors = [self.distance(centroid,point)**2 for point in points]
total_error = sum(errors)
squared_errors.append(total_error)
return sum(squared_errors)
def cluster(self,x):
centroids = self.init_centroids(x)
clusters = {}
for i in range(self.k):
cluster_list = (centroids[i],list())
clusters[i] = cluster_list
itr = 0
while True:
for point in x:
dist_min = self.distance(centroids[0],point)
num = 0
cls_point = 0
for centroid in centroids:
d = self.distance(centroid,point)
if d < dist_min:
cls_point = num
dist_min = d
num +=1
clusters[cls_point][1].append(point)
self.clusters = copy.deepcopy(clusters)
centroids = list()
converges = True
for i in range(self.k):
dp = clusters[i][1]
dp.append(clusters[i][0])
centroid_p = np.mean(np.array(dp), axis=0)
if not ((centroid_p == clusters[i][0]).all()):
converges = False
centroids.append(centroid_p)
cluster_list = (centroid_p,list())
clusters[i] = cluster_list
itr +=1
if converges:
break
self.centroids = centroids
kMeans_implement1 = obj_kMeans(k=k1, init_centroid = i_point1)
kMeans_implement2 = obj_kMeans(k=k2, init_centroid = i_point2)
kMeans_implement1.cluster(data)
kMeans_implement2.cluster(data)
cost_val1 = kMeans_implement1.cost_function(kMeans_implement1.clusters)
cost_val2 = kMeans_implement2.cost_function(kMeans_implement2.clusters)
print("centroid 1", kMeans_implement1.centroids)
print("centroid 2", kMeans_implement2.centroids)
print("cost 1", cost_val1)
print("cost 2", cost_val2)