Простое объяснение и реализация метода локтя

Есть несколько способов выбрать K для K-средних. В этой статье метод локтя объясняется и реализуется очень простым способом.

Объяснение

Ниже наши данные. Легко видеть, что количество кластеров должно быть равно 4.

Мы попытаемся получить K = 4, наблюдая различные значения K.

Визуальное объяснение

На изображении ниже синие точки принадлежат нашему набору данных, а красные точки — это центры кластеров.

Как видите, от каждого центра к его кластеру идут фиолетовые линии. И метод локтя основан на сумме квадратов длин этих фиолетовых линий. Этот показатель называется инерцией.

В какой момент вы видите значительное уменьшение длины фиолетовых линий? В какой момент они начинают исчезать?

Пока K идет к размеру набора данных (N);

инерция уменьшается,

и когда К = N;

все элементы становятся центром,

и длина строк будет 0,

а инерция будет 0.

Важно наблюдать за последним большим изменением инерции.

В то время как при k = 3 есть длинные фиолетовые линии, после k = 4 длинной линии нет, и после этой точки нет больших изменений.

Поэтому мы выбираем первый K после последнего большого изменения, то есть 4.

Графическое объяснение

Вместо визуализации набора данных проще построить график. Действительно, не всегда возможно визуализировать набор данных.

Вот график уменьшения инерции при увеличении K.

Вы можете видеть угол, когда K = 4. Есть еще один угол, когда K = 2, но нам нужен последний угол как наш оптимальный K.

Вот формула для получения инерции.

Выполнение

Здесь я делюсь кодом для получения изображений выше. В конце концов, я добавил визуализацию кластера при K = 4.

  1. Импортируйте библиотеки, составляйте данные, визуализируйте их.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
# compose and visualize data
data = np.array([[20, 2], [20, 4], [21, 2], [23, 3], [8, 7], [8, 9], [7, 5], [7, 10], [25, 24], 
                 [24, 24], [25, 23], [25, 25],[13, 23], [11, 25],[12, 25], [12, 24]])
plt.scatter(*zip(*data), s=30)

2. Напишите функцию для построения линий между центрами и кластерами.

# function to plot lines between centers and clusters
def plot_clusters(data, k, ax):
    km = KMeans(n_clusters=k)
    clusters=km.fit_predict(data) 
    centroids = km.cluster_centers_
    
    x=0
    while x<k:
        for i in data[clusters==x]:
            ax.plot((centroids[x][0],i[0]), (centroids[x][1],i[1]), '-o', color='purple', mfc='c', mec='b', markersize=8)
            ax.title.set_text('k = ' + str(k))
            ax.plot(centroids[x][0], centroids[x][1], 'or')
        x+=1

3. Отображение центров, кластеров и расстояний.

# plotting centers, clusters and distances
fig, axs = plt.subplots(3,3,figsize=(16,12))
plot_clusters(data, 1, axs[0,0])
plot_clusters(data, 2, axs[0,1])
plot_clusters(data, 3, axs[0,2])
plot_clusters(data, 4, axs[1,0])
plot_clusters(data, 5, axs[1,1])
plot_clusters(data, 6, axs[1,2])
plot_clusters(data, 7, axs[2,0])
plot_clusters(data, 8, axs[2,1])
plot_clusters(data, 9, axs[2,2])

4. Получите инерцию и постройте график.

# obtaining and plotting intertia
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(data)
    wcss.append(kmeans.inertia_)
plt.plot(range(1, 11), wcss)
plt.xlabel('K Value')
plt.ylabel('Inertia')

5. Подгонка для K = 4 и построение только кластеров.

# plotting only clusters with k = 4
km = KMeans(n_clusters=4)
clusters=km.fit_predict(data) 
plt.scatter(*zip(*data),c=clusters,marker = "o")