1
$\begingroup$

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

The plot after 100k iterations; shouldn't the centroids be more in the middle of the datapoints?

(above) why after 100k iterations arent the centroids in the middle of the datapoints? The red one is but the green one isnt

$\endgroup$
  • $\begingroup$ How about showing the plot? $\endgroup$ – CalZ Sep 1 '17 at 15:44
  • $\begingroup$ done. added above @CalZ $\endgroup$ – Finn Williams Sep 1 '17 at 17:42
3
$\begingroup$

The centroid is likely correct, you have a display error

The line

plt.scatter(centroid2[0][0], centroid1[0][1], color = "green")

should be

plt.scatter(centroid2[0][0], centroid2[0][1], color = "green")

That's just one of those things that happens when you implement an algorithm from scratch in order to learn it . . . I bet you've spent hours looking at the top part of your script :-)

$\endgroup$
  • $\begingroup$ Hahaha thank you very much. Sometimes all it is is Just an annoying little bug $\endgroup$ – Finn Williams Sep 1 '17 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.