Кластеризация K-средних — это алгоритм обучения без учителя, который группирует данные на основе евклидова расстояния каждой точки до центральной точки, называемой центроида. Центроиды определяются посредством всех точек, находящихся в одном кластере. Алгоритм сначала выбирает случайные точки в качестве центроидов, а затем повторяет их корректировку до полной сходимости.
При использовании K-средних важно помнить, что количество кластеров — это гиперпараметр, он будет определен перед запуском модели.
Метод K-средних можно реализовать с помощью Scikit-Learn, написав всего 3 строки кода. В Scikit-learn также уже есть метод оптимизации центроидов, k означает ++, что помогает модели быстрее сходиться.
Чтобы применить алгоритм кластеризации K-средних, давайте загрузим Палмер Пингвинз набор данных, выберите столбцы, которые будут сгруппированы, и используйте Seaborn, чтобы построить диаграмму рассеяния с кластерами, закодированными цветом.
Внимание: Вы можете загрузить набор данных отсюда. ссылке.
Давайте импортируем библиотеки и загрузим набор данных Penguins, обрезав его до выбранных столбцов и удалив строки с отсутствующими данными (их было всего 2):
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
df = pd.read_csv('penguins.csv')
print(df.shape)
df = df[['bill_length_mm', 'flipper_length_mm']]
df = df.dropna(axis=0)
Мы можем использовать метод локтя, чтобы указать кластеры для наших данных. Он заключается в интерпретации линейного сюжета с формой локтя. Количество кластеров – на локтевых сгибах. Ось x графика — это количество кластеров, а ось y — сумма квадратов внутри кластеров (WCSS) для каждого количества кластеров:
wcss = []
for i in range(1, 11):
clustering = KMeans(n_clusters=i, init='k-means++', random_state=42)
clustering.fit(df)
wcss.append(clustering.inertia_)
ks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sns.lineplot(x = ks, y = wcss);
Метод локтя указывает, что наши данные имеют 2 кластера. Давайте построим данные до и после кластеризации:
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15,5))
sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm').set_title('Without clustering')
sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering.labels_).set_title('Using the elbow method');
В этом примере показано, как метод локтя является только ссылкой при использовании для выбора количества кластеров. Мы уже знаем, что у нас есть 3 типа пингвинов в наборе данных, но если бы мы определили их количество с помощью метода локтя, нашим результатом было бы 2 кластера.
Поскольку K-средние чувствительны к дисперсии данных, давайте посмотрим на описательную статистику столбцов, которые мы кластеризуем:
df.describe().T
Это приводит к:
count mean std min 25% 50% 75% max
bill_length_mm 342.0 43.921930 5.459584 32.1 39.225 44.45 48.5 59.6
flipper_length_mm 342.0 200.915205 14.061714 172.0 190.000 197.00 213.0 231.0
Обратите внимание, что среднее значение далеко от стандартного отклонения (std), это указывает на высокую дисперсию. Попробуем уменьшить его, масштабируя данные с помощью Standard Scaler:
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
scaled = ss.fit_transform(df)
Теперь давайте повторим процесс метода Elbow для масштабированных данных:
wcss_sc = []
for i in range(1, 11):
clustering_sc = KMeans(n_clusters=i, init='k-means++', random_state=42)
clustering_sc.fit(scaled)
wcss_sc.append(clustering_sc.inertia_)
ks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sns.lineplot(x = ks, y = wcss_sc);
Ознакомьтесь с нашим практическим руководством по изучению Git с рекомендациями, принятыми в отрасли стандартами и прилагаемой памяткой. Перестаньте гуглить команды Git и на самом деле изучить это!
На этот раз предлагаемое количество кластеров равно 3. Мы можем снова построить данные с метками кластеров вместе с двумя предыдущими графиками для сравнения:
fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(15,5))
sns.scatterplot(ax=axes[0], data=df, x='bill_length_mm', y='flipper_length_mm').set_title('Without cliustering')
sns.scatterplot(ax=axes[1], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering.labels_).set_title('With the Elbow method')
sns.scatterplot(ax=axes[2], data=df, x='bill_length_mm', y='flipper_length_mm', hue=clustering_sc.labels_).set_title('With the Elbow method and scaled data');
При использовании K-means Clustering необходимо заранее определить количество кластеров. Как мы видели при использовании метода для выбора нашего k количество кластеров, результат является только предположением, и на него может повлиять величина дисперсии данных. Важно провести глубокий анализ и сгенерировать более одной модели с разными _k_s при кластеризации.
Если нет предварительного указания на количество кластеров в данных, визуализируйте их, протестируйте и интерпретируйте, чтобы увидеть, имеют ли смысл результаты кластеризации. Если нет, сгруппируйте снова. Кроме того, просмотрите более одной метрики и создайте экземпляры разных моделей кластеризации — для K-средних посмотрите на оценку силуэта и, возможно, на иерархическую кластеризацию, чтобы увидеть, останутся ли результаты прежними.