Я хочу визуализировать свои кластеры.

Используя этот код:

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

X = np.array([[28, 7], [36, 5], [32, 2], [56, 8], [47, 5], [50,100], [100,100], [26,59], [19,71],
              [75, 9], [34, 4], [56, 9], [28, 1], [33, 6]])
col = ['blue', 'green', 'c', 'm', 'y', 'k', "violet", "indigo"]
ncluster = 2
kmeans = KMeans(n_clusters=ncluster, max_iter=500).fit(X)
y = kmeans.labels_
centroids = kmeans.cluster_centers_
clusters_centroids = dict()
clusters_radii = dict()
for cluster in range(ncluster):
    clusters_centroids[cluster] = list(
        zip(centroids[:, 0], centroids[:, 1]))[cluster]
    clusters_radii[cluster] = max([np.linalg.norm(np.subtract(
        i, clusters_centroids[cluster])) for i in zip(X[y == cluster, 0], X[y == cluster, 1])])

fig, ax = plt.subplots(1, figsize=(7, 5))

def drawclusters():
    for i in range(ncluster):
        plt.scatter(X[y == i, 0], X[y == i, 1], s=100,
                    c=col[i], label=f'Cluster {i + 1}')
        art = mpatches.Circle(
            clusters_centroids[i], clusters_radii[i], edgecolor=col[i], fill=False)
        ax.add_patch(art)
    plt.scatter(centroids[:, 0], centroids[:, 1], s=200,
                c='red', label='Centroids', marker='x')


drawclusters()
plt.legend()
plt.tight_layout()
plt.show()

Я получаю круги:

circular visualisation

Но я хочу визуализировать с помощью точек нечто подобное этому игнорировать часть данных, мне просто нужна часть визуализации (мне нужны формы):

non ciruclar

Мне нужен код на Python. В R. есть функция fviz_cluster .

1
saibhaskar 4 Окт 2020 в 16:46

1 ответ

Лучший ответ

Вы можете создать выпуклую оболочку каждого из кластеров, используя scipy.spatial.ConvexHull(). Обратите внимание, что X[y == i] необходимо преобразовать в новый массив, потому что ConvexHull() возвращает индексы в короткий массив. Возвращенные точки образуют многоугольник. Первую точку необходимо скопировать в конце, чтобы построить график, чтобы включить линейный сегмент, закрывающий многоугольник.

import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from scipy.spatial import ConvexHull

def drawclusters(ax):
    for i in range(ncluster):
        points = X[y == i]
        ax.scatter(points[:, 0], points[:, 1], s=100, c=col[i], label=f'Cluster {i + 1}')
        hull = ConvexHull(points)
        vert = np.append(hull.vertices, hull.vertices[0])  # close the polygon by appending the first point at the end
        ax.plot(points[vert, 0], points[vert, 1], '--', c=col[i])
        ax.fill(points[vert, 0], points[vert, 1], c=col[i], alpha=0.2)
    ax.scatter(centroids[:, 0], centroids[:, 1], s=200, c='red', label='Centroids', marker='x')

X = np.array([[28, 7], [36, 5], [32, 2], [56, 8], [47, 5], [50, 100], [100, 100], [26, 59], [19, 71],
              [75, 9], [34, 4], [56, 9], [28, 1], [33, 6]])
col = ['blue', 'green']
ncluster = 2
kmeans = KMeans(n_clusters=ncluster, max_iter=500).fit(X)
y = kmeans.labels_
centroids = kmeans.cluster_centers_
fig, ax = plt.subplots(1, figsize=(7, 5))
drawclusters(ax)
ax.legend()
plt.tight_layout()
plt.show()

resulting plot

2
JohanC 4 Окт 2020 в 14:46