How to set k-Means clustering labels from highest to lowest with Python?

Viewed 17584

I have a dataset of 38 apartments and their electricity consumption in the morning, afternoon and evening. I am trying to clusterize this dataset using the k-Means implementation from scikit-learn, and am getting some interesting results.

First clustering results: Img

This is all very well, and with 4 clusters I obviously get 4 labels associated to each apartment - 0, 1, 2 and 3. Using the random_state parameter of KMeans method, I can fix the seed in which the centroids are randomly initialized, so consistently I get the same labels attributed to the same apartments.

However, as this specific case is in regards of energy consumption, a measurable classification between the highest and the lowest consumers can be performed. I would like, thus, to assign the label 0 to the apartments with lowest consumption level, label 1 to apartments that consume a bit more and so on.

As of now, my labels are [2 1 3 0], or ["black", "green", "blue", "red"]; I would like them to be [0 1 2 3] or ["red", "green", "black", "blue"]. How should I proceed to do so, while still keeping the centroid initialization random (with fixed seed)?

Thank you very much for the help!

2 Answers

Maybe sort the centroids based on their vector magnitude is better, since you can use it to predict other data using the same model. Here is my implementation in my repo

from sklearn.cluster import KMeans

def sorted_cluster(x, model=None):
    if model == None:
        model = KMeans()
    model = sorted_cluster_centers_(model, x)
    model = sorted_labels_(model, x)
    return model

def sorted_cluster_centers_(model, x):
    model.fit(x)
    new_centroids = []
    magnitude = []
    for center in model.cluster_centers_:
        magnitude.append(np.sqrt(center.dot(center)))
    idx_argsort = np.argsort(magnitude)
    model.cluster_centers_ = model.cluster_centers_[idx_argsort]
    return model

def sorted_labels_(sorted_model, x):
    sorted_model.labels_ = sorted_model.predict(x)
    return sorted_model

Example:

import numpy as np
arr = np.vstack([
    100 + np.random.random((2,3)),
    np.random.random((2,3)),
    5 + np.random.random((3,3)),
    10 + np.random.random((2,3))
])
print('Data:')
print(arr)

cluster = KMeans(n_clusters=4)

print('\n Without sort:')
cluster.fit(arr)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))

print('\n With sort:')
cluster = sorted_cluster(arr, cluster)
print(cluster.cluster_centers_)
print(cluster.labels_)
print(cluster.predict([[5,5,5],[1,1,1]]))

Output:

Data:
[[100.52656263 100.57376566 100.63087757]
 [100.70144046 100.94095196 100.57095386]
 [  0.21284187   0.75623797   0.77349013]
 [  0.28241023   0.89878796   0.27965047]
 [  5.14328748   5.37025887   5.26064209]
 [  5.21030632   5.09597417   5.29507699]
 [  5.81531591   5.11629056   5.78542656]
 [ 10.25686526  10.64181304  10.45651994]
 [ 10.14153211  10.28765705  10.20653228]]

 Without sort:
[[ 10.19919868  10.46473505  10.33152611]
 [100.61400155 100.75735881 100.60091572]
 [  0.24762605   0.82751296   0.5265703 ]
 [  5.38963657   5.19417453   5.44704855]]
[1 1 2 2 3 3 3 0 0]
[3 2]

 With sort:
[[  0.24762605   0.82751296   0.5265703 ]
 [  5.38963657   5.19417453   5.44704855]
 [ 10.19919868  10.46473505  10.33152611]
 [100.61400155 100.75735881 100.60091572]]
[3 3 0 0 1 1 1 2 2]
[1 0]
Related