web-dev-qa-db-fra.com

Sklearn: Distance moyenne du centre de gravité de chaque cluster

Comment puis-je trouver la distance moyenne entre le centroïde et tous les points de données de chaque groupe. Je suis en mesure de trouver la distance euclidienne de chaque point (dans mon jeu de données) par rapport au centroïde de chaque cluster. Maintenant, je veux trouver la distance moyenne entre le centroïde et tous les points de données de chaque groupe. Quel est un bon moyen de calculer la distance moyenne de chaque centroïde? Jusqu'ici j'ai fait ceci ..

def k_means(self):
    data = pd.read_csv('hdl_gps_Apple_20111220_130416.csv', delimiter=',')
    combined_data = data.iloc[0:, 0:4].dropna()
    #print combined_data
    array_convt = combined_data.values
    #print array_convt
    combined_data.head()


    t_data=PCA(n_components=2).fit_transform(array_convt)
    #print t_data
    k_means=KMeans()
    k_means.fit(t_data)
    #------------k means fit predict method for testing purpose-----------------
    clusters=k_means.fit_predict(t_data)
    #print clusters.shape
    cluster_0=np.where(clusters==0)
    print cluster_0

    X_cluster_0 = t_data[cluster_0]
    #print X_cluster_0


    distance = euclidean(X_cluster_0[0], k_means.cluster_centers_[0])
    print distance


    classified_data = k_means.labels_
    #print ('all rows forst column........')
    x_min = t_data[:, 0].min() - 5
    x_max = t_data[:, 0].max() - 1
    #print ('min is ')
    #print x_min
    #print ('max is ')
    #print x_max

    df_processed = data.copy()
    df_processed['Cluster Class'] = pd.Series(classified_data, index=df_processed.index)
    #print df_processed

    y_min, y_max = t_data[:, 1].min(), t_data[:, 1].max() + 5
    xx, yy = np.meshgrid(np.arange(x_min, x_max, 1), np.arange(y_min, y_max, 1))

    #print ('the mesh grid is: ')

    #print xx
    Z = k_means.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    plt.figure(1)
    plt.clf()
    plt.imshow(Z, interpolation='nearest',
               extent=(xx.min(), xx.max(), yy.min(), yy.max()),
               cmap=plt.cm.Paired,
               aspect='auto', Origin='lower')


    #print Z


    plt.plot(t_data[:, 0], t_data[:, 1], 'k.', markersize=20)
    centroids = k_means.cluster_centers_
    inert = k_means.inertia_
    plt.scatter(centroids[:, 0], centroids[:, 1],
                marker='x', s=169, linewidths=3,
                color='w', zorder=8)
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)
    plt.xticks(())
    plt.yticks(())
    plt.show()

En bref, je souhaite calculer la distance moyenne de tous les points de données d'une grappe particulière à partir du centre de gravité de cette grappe, car je dois nettoyer mes données sur la base de cette distance moyenne

6
Rezwan

Voici un moyen. Vous pouvez remplacer la fonction k_mean_distance() par une autre mesure de distance dans la fonction si vous souhaitez une autre métrique de distance autre que Euclidienne.

Calculez la distance entre les points de données pour chaque cluster et centre de cluster affectés et renvoyez la valeur moyenne.

Fonction de calcul de distance:

def k_mean_distance(data, cx, cy, i_centroid, cluster_labels):
    # Calculate Euclidean distance for each data point assigned to centroid 
    distances = [np.sqrt((x-cx)**2+(y-cy)**2) for (x, y) in data[cluster_labels == i_centroid]]
    # return the mean value
    return np.mean(distances)

Et pour chaque centroïde, utilisez la fonction pour obtenir la distance moyenne:

total_distance = []
for i, (cx, cy) in enumerate(centroids):
    # Function from above
    mean_distance = k_mean_distance(data, cx, cy, i, cluster_labels)
    total_dist.append(mean_distance)

Donc, dans le contexte de votre question:

def k_mean_distance(data, cx, cy, i_centroid, cluster_labels):
        distances = [np.sqrt((x-cx)**2+(y-cy)**2) for (x, y) in data[cluster_labels == i_centroid]]
        return np.mean(distances)

t_data=PCA(n_components=2).fit_transform(array_convt)
k_means=KMeans()
clusters=k_means.fit_predict(t_data)
centroids = km.cluster_centers_

c_mean_distances = []
for i, (cx, cy) in enumerate(centroids):
    mean_distance = k_mean_distance(t_data, cx, cy, i, clusters)
    c_mean_distances.append(mean_distance)

Si vous tracez les résultats plt.plot(c_mean_distances), vous devriez voir quelque chose comme ceci:

 kmeans clusters vs mean value

3
alphaleonis

alphaleonis a donné une réponse agréable. Pour le cas général des dimensions, voici quelques modifications nécessaires à sa réponse:

def k_mean_distance(data, cantroid_matrix, i_centroid, cluster_labels):
    # Calculate Euclidean distance for each data point assigned to centroid
    distances = [np.linalg.norm(x-cantroid_matrix) for x in data[cluster_labels == i_centroid]]
    # return the mean value
    return np.mean(distances)

for i, cent_features in enumerate(centroids):
            mean_distance = k_mean_distance(emb_matrix, centroid_matrix, i, kmeans_clusters)
            c_mean_distances.append(mean_distance)
1
Shay.G

Vous pouvez utiliser l'attribut KMeans suivant:

cluster_centers_ : array, [n_clusters, n_features]

Pour chaque point, testez le groupe auquel il appartient à l'aide de predict(X) et calculez ensuite la distance entre les rendements de prédiction de cluster (il renvoie l'index).

1
Farseer

Calcule toute la distance dans un tableau numpy.

Ensuite, utilisez nparray.mean() pour obtenir la moyenne.

0
Anony-Mousse