my algortithm isnt working. The code seems to make sense and everything but im just not convinced with the results. I fell like the centroids should be amongst the data more, sort of central, but they arent doing that no matter how many iterations i set the algorithm too. Could someone run my code and give me some pointers? Ive labeled the code so you can understand it. Some main points:
- k = 2; 2 centroids
- centroid1 = Dark red, so datapoints in this cluster are light red
- centroid 2 = Dark green, so datapoints in this cluster are light green
- dogs are either 'big' or 'small' depending on their height and weight
- The euclidean distance is used to decide on which cluster to belong to
- Raw/main data stored in dictionary labeled 'x'; they are moved about into the dictionaries 'cluster1' and 'cluster2' depending on their distance to the centroids
code:
from matplotlib import pyplot as plt
import random, math
plt.title("Big Dogs and Small Dogs")
plt.ylabel("Height (cm)")
plt.xlabel("Weight (kg)")
def euclideandis(x, y, a, b): # Formula for euclidean distance
return math.sqrt((x-a)**2 + (x-a)**2)
x = {4.4:31,
3.2:19,
4.6:32, # Data- key = weight, value = height
4:25,
4.1:29,
2.90:17,
2.9:11}
centroid1 = [[random.uniform(min(x.keys()), max(x.keys())), random.uniform(max(x.values()), min(x.values()))]] # create random centroids that are between the datapoints
centroid2 = [[random.uniform(min(x.keys()), max(x.keys())), random.uniform(max(x.values()), min(x.values()))]]
for j in xrange(1): # keep updating colours, position of centroids
cluster1 = {} # Everything in cluster 1 is closest to the dark red spot, therefore gets included in this dict, and gets scattered in light red
cluster2 = {} # Everything in cluster 2 is closest to the dark green spot, therefore gets included in this dict, and gets scattered in light green
for key in x:
temp1 = 0 # works out euclidean distance for all data points in x, then compares them
temp2 = 0
temp1 = euclideandis(key, x[key], centroid1[0][0], centroid1[0][1]) # Dis betw data point, red centroid
temp2 = euclideandis(key, x[key], centroid2[0][0], centroid2[0][1]) # Dis betw data point, green centroid
if temp1 < temp2:
cluster1[key] = x[key] # if the euclidean distance between datapoint and red spot,
# smaller than the euclidean distance between datapoint and green spot,
# add the point to the red cluster, else add to green cluster
else:
cluster2[key] = x[key]
centroid1 = [[0, 0]] # Centroids reset as they will be changed
centroid2 = [[0, 0]]
iterable = 0
for key in cluster1: # works out mean coordinates of each cluster and changes the centroids coordinates to this
iterable = iterable + key
centroid1[0][0] = iterable/len(cluster1)
iterable = 0
for key in cluster1:
iterable = iterable + cluster1[key]
centroid1[0][1] = iterable/len(cluster1)
iterable = 0
for key in cluster2:
iterable = iterable + key
centroid2[0][0] = iterable/len(cluster2)
iterable = 0
for key in cluster2:
iterable = iterable + cluster2[key]
centroid2[0][1] = iterable/len(cluster2)
plt.scatter(cluster1.keys(), cluster1.values(), color = "red") # scatters everythning
plt.scatter(cluster2.keys(), cluster2.values(), color = "lime")
plt.scatter(centroid1[0][0], centroid1[0][1], color = "maroon")
plt.scatter(centroid2[0][0], centroid1[0][1], color = "green")
plt.show()
To sum up, there isn't a clear error with my program, only I'm not really convinced about the results
(above) why after 100k iterations arent the centroids in the middle of the datapoints? The red one is but the green one isnt