Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Agglomerative Clustering "Centroid" in python Scikit-learn

This code is what I am using for silhouette_score. And in here I am using Agglomerative Clustering, linkage as Ward. I would like to get "Centroid" of Agglomerative Clustering, would it be possible from Agglomerative Clustering? I could only get K-mean's centroid and Fuzzy c-mean.

df1 
    Height  time_of_day resolution
272 1.567925    1.375000    0.594089
562 1.807508    1.458333    0.594089
585 2.693542    0.416667    0.594089
610 1.036305    1.458333    0.594089
633 1.117111    0.416667    0.594089
658 1.542407    1.458333    0.594089
681 1.930844    0.416667    0.594089
802 1.505548    1.458333    0.594089
808 1.009369    1.708333    0.594089


def clustering(df1):
    X = df1.iloc[:].values
    range_n_clusters = [2,3,4]
    for n_clusters in range_n_clusters:
        # Create a subplot with 1 row and 2 columns
        clusterer = AgglomerativeClustering(n_clusters=n_clusters, linkage='ward')  
        clusterer.fit_predict(X)
        cluster_labels = clusterer.labels_

        silhouette_avg = silhouette_score(X, cluster_labels)
        if silhouette_avg > 0.4:
            print("For n_clusters =", n_clusters,
                  "The average silhouette_score is :", silhouette_avg)
            fig, (ax1, ax2) = plt.subplots(1, 2)

            fig.set_size_inches(15, 5)

            ax1.set_xlim([-0.1, 1])
            ax1.set_ylim([0, len(X) + (n_clusters + 1) * 10])

            sample_silhouette_values = silhouette_samples(X, cluster_labels)

            y_lower = 10
            for i in range(n_clusters):
                ith_cluster_silhouette_values = \
                    sample_silhouette_values[cluster_labels == i]

                ith_cluster_silhouette_values.sort()

                size_cluster_i = ith_cluster_silhouette_values.shape[0]
                y_upper = y_lower + size_cluster_i

                color = cm.nipy_spectral(float(i) / n_clusters)
                ax1.fill_betweenx(np.arange(y_lower, y_upper),
                                  0, ith_cluster_silhouette_values,
                                  facecolor=color, edgecolor=color, alpha=0.7)
                ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
                y_lower = y_upper + 10  # 10 for the 0 samples

            ax1.set_title("The silhouette plot for the various clusters.")
            ax1.set_xlabel("The silhouette coefficient values")
            ax1.set_ylabel("Cluster label")
            ax1.axvline(x=silhouette_avg, color="red", linestyle="--")

            ax1.set_yticks([])  # Clear the yaxis labels / ticks
            ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
            ax = Axes3D(fig)
            colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
            ax.scatter(X[:, 1], X[:, 2], X[:, 0],marker='o', s=20, lw=0, alpha=0.7,
                        c=colors, edgecolor='k')

            plt.suptitle(("Silhouette analysis for HAC-ward clustering on sample data "
                          "with n_clusters = %d" % n_clusters),
                         fontsize=14, fontweight='bold')

    plt.show()  
    return



clusterer = AgglomerativeClustering(n_clusters=n_clusters, linkage='ward')  
clusterer.fit_predict(X)
cluster_labels = clusterer.labels_

This code is only for the Agglomerative Clustering method

from scipy.cluster.hierarchy import centroid, fcluster

from scipy.spatial.distance import pdist

cluster = AgglomerativeClustering(n_clusters=4, affinity='euclidean', linkage='ward')  
y = pdist(df1)

y

I Also have tried this code but I am not sure the 'y' is correct centroid.

from sklearn.neighbors.nearest_centroid import NearestCentroid
clf = NearestCentroid()
clf.fit(df1["Height"],df1["time_of_day"])
print(clf.centroids_)

For this I tried to use another method for X, Y centroids. And it shows error...

Please advice me whether I can get centroid from Agglomerative Clustering or I should stick to fuzzy-cmean

Thanks

like image 226
Pandalove Avatar asked Jun 05 '19 08:06

Pandalove


People also ask

How do you find the centroid in agglomerative clustering?

Divide the total by the number of members of the cluster. In the example above, 283 divided by four is 70.75, and 213 divided by four is 53.25, so the centroid of the cluster is (70.75, 53.25).


1 Answers

I believe you can use Agglomerative Clustering and you can get centroids using NearestCentroid, you just need to make some adjustment in your code, here is what worked for me:

from sklearn.neighbors import NearestCentroid

y_predict = clusterer.fit_predict(X)
#...
clf = NearestCentroid()
clf.fit(X, y_predict)
print(clf.centroids_)

The only thing I think was missing in your code is that you're not getting back the returned values from fit_predict(), you can also try the dendrogram for better visualization, full code can be found here.

like image 73
Ibrahim.H Avatar answered Sep 30 '22 11:09

Ibrahim.H