sklearn KMeans Clustering - which time series is in which cluster?

Viewed 97

I'm using the kmeans clustering from sklearn and it all works fine, I would just like to know which time series is in which cluster. Do you have experience with that? e.g. My clusters are in the attached picture, and I would like to know which time series is in which cluster (i have 143 time series). My time series are stored in this list: mySeries_2019_Jan So, within that list there are 143 np.arrays, therefore the elements in there look like this:

mySeries_2019_Jan[0]
Out[119]: 
array([0.14117647, 0.13936652, 0.14298643, 0.14570136, 0.14298643,
       0.14751131, 0.15475113, 0.160181  , 0.15384615, 0.1438914 ,
       0.15384615, 0.14660633, 0.1520362 , 0.18914027, 0.20769231,
...

So I want something simple with that logic, just to know which series is in which cluster:

cluster1_names = []
i = 0 
If mySeries_2019_Jan[i] in cluster 1:
cluster1_names.append(str("series" + i))
i+=1

here's my code I used (mostly copy pasted from the documentation (and I edited the kmeans source code to be able to input the dtw sakoe radius directly, in case you wonder) :

from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.ensemble import GradientBoostingClassifier


    n_clusters = math.ceil(math.sqrt(len(mySeries_2019_Jan))) 
    
    km = TimeSeriesKMeans(n_clusters = n_clusters, metric="dtw", max_iter=5, random_state=0,
                          global_constraint ="sakoe_chiba", sakoe_chiba_radius=2, verbose = 1 )
    
    labels = km.fit_predict(mySeries_2019_Jan)

To get the clustering pictures I also copy pasted some code which I don't really understand:

som_x = som_y = math.ceil(math.sqrt(math.sqrt(len(mySeries_2019_Jan))))
        plot_count = math.ceil(math.sqrt(n_clusters))
    
    fig, axs = plt.subplots(plot_count,plot_count,figsize=(25,25))
    fig.suptitle('Clusters')
    row_i=0
    column_j=0
    # For each label there is,
    # plots every series with that label
    for label in set(labels):
        cluster = []
        for i in range(len(labels)):
                if(labels[i]==label):
                    axs[row_i, column_j].plot(mySeries_2019_Jan[i],c="gray",alpha=0.4)
                    cluster.append(mySeries_2019_Jan[i])
        if len(cluster) > 0:
            axs[row_i, column_j].plot(np.average(np.vstack(cluster),axis=0),c="red")
        axs[row_i, column_j].set_title("Cluster "+str(row_i*som_y+column_j))
        column_j+=1
        if column_j%plot_count == 0:
            row_i+=1
            column_j=0
            
    plt.show()

Picture of Clusters

__

How can I now get the information which time series are in which cluster?

1 Answers

You can save the cluster groupings while retrieving them for plotting.

som_x = som_y = math.ceil(math.sqrt(math.sqrt(len(mySeries_2019_Jan))))
        plot_count = math.ceil(math.sqrt(n_clusters))
    
    fig, axs = plt.subplots(plot_count,plot_count,figsize=(25,25))
    fig.suptitle('Clusters')
    row_i=0
    column_j=0
    # For each label there is,
    # plots every series with that label
    cluster_names = dict()
    for label in set(labels):
        cluster = []
        for i in range(len(labels)):
                if(labels[i]==label):
                    axs[row_i, column_j].plot(mySeries_2019_Jan[i],c="gray",alpha=0.4)
                    cluster.append(mySeries_2019_Jan[i])
        if len(cluster) > 0:
            axs[row_i, column_j].plot(np.average(np.vstack(cluster),axis=0),c="red")
        axs[row_i, column_j].set_title("Cluster "+str(row_i*som_y+column_j))
        cluster_names[str(row_i*som_y+column_j)] = cluster
        column_j+=1
        if column_j%plot_count == 0:
            row_i+=1
            column_j=0
            
    plt.show()

And then

cluster_names["1"]

will be a list of the time series with label 1.

OR

for label in set(labels):
        cluster = []
        cluster_names[label] = []
        for i in range(len(labels)):
                if(labels[i]==label):
                    axs[row_i, column_j].plot(mySeries_2019_Jan[i],c="gray",alpha=0.4)
                    cluster.append(mySeries_2019_Jan[i])
                    cluster_names[str(label)].append("series" + str(i))

And then

cluster_names["1"]

will be a list of indices of the time series with label 1.

Related