Машинное обучение можно разделить на две основные категории: машинное обучение с учителем и машинное обучение без учителя. В машинном обучении с учителем мы изначально предоставляем данные с соответствующей меткой для обучения модели, с помощью обученной модели мы можем найти метку для новых данных.

Но в неконтролируемом машинном обучении мы бросаем данные в модель без какой-либо маркировки, модель найдет в данных закономерности. В неконтролируемом машинном обучении мы не можем найти класс данных, но вместо этого мы можем сгруппировать схожие точки данных, этот процесс известен как кластеризация. Существует ряд алгоритмов кластеризации, в этой статье я расскажу о кластеризации KMeans.

Как работает кластеризация KMeans?

Давайте разберемся в этом шаг за шагом с помощью изображения ниже.

Этап (a) — Неконтролируемые исходные данные

Шаг (b) — выберите случайные начальные центроиды (центроиды — это центры кластеров). В этом примере нам нужно разделить набор данных на два разных кластера, красный или синий, поэтому у нас есть два центроида.

Шаг ©. Затем другие точки данных будут отмечены красным или синим цветом в зависимости от ближайшего центроида.

Шаг (d). После того, как точки отмечены красным или синим цветом, будут скорректированы координаты центроидов. Новые координаты центроидов будут рассчитаны по среднему значению всех точек, принадлежащих кластеру центроидов.

Шаг (e) — после настройки центроида другие точки данных в кластере снова будут изменены на основе ближайшего центроида (как вы можете видеть на изображении (e), некоторые синие точки изменились на красные точки и наоборот).

Шаг (d) и шаг (e) будут выполняться итеративно до тех пор, пока для каких-либо точек не будет изменений кластера. Другими словами, центроиды будут корректироваться до тех пор, пока мы не достигнем уровня, при котором ни одна из точек данных не изменится от одного кластера к другому. (см. изображение (f)). Если вы все еще запутались, посмотрите на гифку ниже.

Давайте сделаем это практически. В этом примере я собираюсь использовать набор данных о ежедневных месячных транзакциях продуктового магазина и хочу найти некоторую закономерность в продажах продуктов по сравнению с ценой продуктов.

Шаг 1 — Импортируйте данные и необходимые библиотеки.

import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('Data.csv')

В приведенном выше коде я импортировал необходимые библиотеки в данные. Если мы посмотрим на нашу переменную данных, она будет выглядеть примерно так.

Шаг 2 — Найдите оптимальное количество кластеров (значение K) для данных. Чтобы найти оптимальное количество кластеров, мы используем метод локтя вызова метода.

Что такое метод локтя?

Чтобы найти оптимальное количество кластеров или так называемое значение K, мы применим алгоритм KMeans к ряду различных значений K и вычислим ошибку (известную как внутри- сумма квадратов кластера) и изобразите ее на графике относительно значения k, и, наконец, примите решение о том, сколько выбрать.

Что такое WCSS или сумма квадратов внутри кластера?

Это сумма квадрата евклидова расстояния между центроидом и всеми точками кластера этого кластера. Проще говоря, он рассчитает расстояние между центроидом и каждой точкой, принадлежащей этому кластеру, и сложит все вместе.

X = data.iloc[:, 1:3]

# use elbow mwthod to find optimal number of clusters
from sklearn.cluster import KMeans

# with in cluster sum of squares
wcss = []
for i in range(1, 11):
    kmeans = KMeans(n_clusters =i, init="k-means++", max_iter=300, n_init=10)
    kmeans.fit(X)
    wcss.append(kmeans.inertia_)

plt.plot(range(1, 11), wcss);
plt.title("Elbow Method")
plt.xlabel("Number of Clusters")
plt.ylabel("WCSS")
plt.show()

В приведенном выше коде сначала мы выбираем поля в наборе данных, которые важны, нам нужны только проданное количество и цена за единицу. Затем мы выбрали другое количество кластеров (здесь мы тестируем значения от 1 до 10), применили алгоритм KMeans (пока игнорируем параметры в функции) и вычислили WCSS (значение WCSS получается с помощью kmeans.inertia_). Наконец, мы построили значения WCSS в зависимости от номера кластера и получили график (график выше).

Итак, у нас есть график, теперь нам нужно знать, как выбрать оптимальное значение k, на самом деле значение WCSS будет уменьшаться с увеличением количества кластеров (оно достигнет нуля, когда количество кластеров равно количеству точек данных, потому что центроиды и точка данных будут в одном и том же месте, поэтому ошибки нет вообще), но мы выберем точку, где происходит последнее большое различие в WCSS, здесь мы можем выбрать либо 3, либо 4. В этом Например, я выберу 4 кластера. Как только вы найдете оптимальное количество кластеров, вам не понадобится этот фрагмент кода в вашей программе, поэтому вы можете прокомментировать этот код.

Шаг 3 — Кластеризовать данные с выбранным значением k.

kmeans = KMeans(n_clusters=4, init="k-means++", max_iter=1000, n_init=10)
y_pred = kmeans.fit_predict(X)

Давайте пройдемся по аргументам в KMeans,

1. n_clusters — количество кластеров

2. init — Алгоритм KMeans имеет серьезную проблему, когда дело доходит до выбора случайного начального положения центроида. Например, на изображении ниже

На первом графике показаны правильные кластеры, на втором графике показана ловушка инициализации, о которой я говорил ранее. Как вы можете видеть на втором графике, несмотря на то, что центроиды правильно разделяют точки данных, это неправильные кластеры. Для преодоления ловушки инициализации можно использовать алгоритм KMeans++ (подробнее о kmean++).

3. max_iter — определяет максимальное количество итераций для настройки центроидов. Если мы не ограничим это значение, процесс корректировки центроидов будет выполняться снова и снова, что может занять очень много времени. .

4. n_init — количество раз, когда алгоритм k-средних будет запускаться с разными начальными центроидами. Это означает, что наша модель KMean проверит 10 различных местоположений центроидов и, наконец, среди 10 найдет оптимальное начальное положение.

Затем мы сохранили кластер записей в переменной y_pred.

Шаг 4 — Визуализируйте кластер

#plot the scatters
'''
X[y_pred==0] - will list records which belongs to cluster 0
output:
       Qty  UnitPrice
1     1911       3.39
'''
plt.scatter(X[y_pred == 0].iloc[:, 0], X[y_pred == 0].iloc[:, 1], s=5, c="red")
plt.scatter(X[y_pred == 1].iloc[:, 0], X[y_pred == 1].iloc[:, 1], s=5, c="green")
plt.scatter(X[y_pred == 2].iloc[:, 0], X[y_pred == 2].iloc[:, 1], s=5, c="blue")
plt.scatter(X[y_pred == 3].iloc[:, 0], X[y_pred == 3].iloc[:, 1], s=5, c="purple")
# centroids X, Y Coordinates can be get through kmeans.cluster_centers_
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=100, c="black", marker="*")
# I limit the y value to get rid of the outlier records
plt.ylim([0,20])
plt.xlabel("Sold Quantity")
plt.ylabel("Unit Price")
plt.show()

Окончательный результат выглядит так, как показано ниже. Вы можете видеть, как модель сгруппировала точки данных в 4 кластера, а звезды на графике указывают точки центроида.

Вот так 😉.

Примечание. Весь мой код доступен в Github, и вы можете подписаться на меня в Github 😉.