Sklearn Cluster KMeans: мощный алгоритм кластеризации данных

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Для кого эта статья:

  • Студенты и начинающие специалисты в области аналитики данных и машинного обучения
  • Практикующие data scientists и аналитики, желающие углубить свои знания в кластеризации
  • Профессионалы бизнеса, интересующиеся использованием алгоритмов кластеризации для анализа данных и принятия решений

    KMeans из библиотеки Scikit-learn — это не просто алгоритм, а настоящий золотой стандарт кластеризации данных в Python. Разработанный для раскрытия скрытых структур в наборах данных без предварительной разметки, KMeans стал незаменимым инструментом в арсенале каждого data scientist. От сегментации клиентов до обработки изображений — этот алгоритм молниеносно разделяет данные на группы, выявляя закономерности там, где человеческий глаз бессилен. Погружаясь в математические принципы и практические тонкости KMeans, вы приобретаете мощный инструмент интерпретации данных, способный трансформировать хаос информации в чёткую и действенную аналитику. 🔍

Хотите овладеть алгоритмами кластеризации и другими инструментами анализа данных на профессиональном уровне? Курс «Аналитик данных» с нуля от Skypro даст вам не только теоретическую базу по KMeans, но и практические навыки его применения в реальных проектах. Вы научитесь выбирать оптимальные параметры, визуализировать результаты и интерпретировать кластеры — всё, что нужно для принятия data-driven решений в бизнесе и науке.

Основы Sklearn Cluster KMeans: принципы работы и математика

KMeans — это итеративный алгоритм кластеризации, который стремится разделить n наблюдений на k кластеров, где каждое наблюдение принадлежит кластеру с ближайшим средним значением. Математически задача сводится к минимизации функции:

J = Σ Σ ||x_i^(j) – c_j||^2

где:
- x_i^(j) — i-ое наблюдение, принадлежащее j-му кластеру
- c_j — центроид j-го кластера
- ||x_i^(j) – c_j||^2 — квадрат евклидова расстояния

Алгоритм KMeans в scikit-learn работает следующим образом:

  1. Инициализация: Выбор k начальных центроидов (по умолчанию используется метод k-means++)
  2. Назначение кластеров: Каждая точка данных назначается кластеру с ближайшим центроидом
  3. Обновление центроидов: Пересчёт центроидов как среднего всех точек в кластере
  4. Повторение: Шаги 2-3 повторяются до сходимости (центроиды перестают значительно изменяться или достигнуто максимальное число итераций)

Ключевое преимущество KMeans — его вычислительная эффективность, особенно при обработке больших наборов данных. Временная сложность алгоритма составляет O(t k n * d), где:

ПараметрОписаниеВлияние на производительность
tКоличество итерацийЛинейное
kКоличество кластеровЛинейное
nКоличество образцовЛинейное
dРазмерность данныхЛинейное

Реализация KMeans в scikit-learn включает оптимизации, такие как использование треугольного неравенства для ускорения вычислений расстояний и метод k-means++ для более эффективной инициализации центроидов, что существенно улучшает сходимость алгоритма. 🧮

Пример базового использования KMeans в Python:

Python
Скопировать код
from sklearn.cluster import KMeans
import numpy as np

# Создаем синтетические данные
X = np.array([[1, 2], [1, 4], [1, 0], [10, 2], [10, 4], [10, 0]])

# Создаем и обучаем модель
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)

# Получаем метки кластеров для исходных данных
labels = kmeans.labels_

# Получаем координаты центроидов
centroids = kmeans.cluster_centers_

# Предсказываем кластеры для новых данных
new_data = np.array([[0, 0], [12, 3]])
new_labels = kmeans.predict(new_data)
Кинга Идем в IT: пошаговый план для смены профессии

Настройка гиперпараметров KMeans для оптимальных результатов

Михаил Дроздов, Lead Data Scientist

Однажды мой команде поручили сегментировать клиентскую базу крупного интернет-магазина — более 2 миллионов записей с 15 характеристиками покупательского поведения. Первый запуск KMeans с настройками по умолчанию дал результат, но клиентские сегменты казались неоднородными. Мы провели тщательную настройку параметров: перебрали различные n_clusters от 3 до 12, тестировали разные методы init и значения n_init. После экспериментов с предварительной стандартизацией и PCA для снижения размерности мы добились 5 чётких клиентских сегментов, которые прекрасно интерпретировались с бизнес-точки зрения. Особенно показательным был момент настройки max_iter — увеличение с 300 до 500 дало более стабильные результаты, хотя и потребовало дополнительных вычислительных ресурсов. Именно тонкая настройка параметров превратила KMeans из обычного алгоритма в мощный инструмент бизнес-инсайтов.

Эффективность KMeans существенно зависит от правильной настройки гиперпараметров. Рассмотрим ключевые параметры, доступные в реализации scikit-learn (версия 2025): 🔧

ПараметрОписаниеРекомендации по выбору
n_clustersКоличество кластеровОпределяйте с помощью метода локтя или силуэтного анализа
initМетод инициализации центроидов'k-means++' (по умолчанию) обычно превосходит случайную инициализацию
n_initКоличество запусков с разными центроидамиУвеличивайте для более стабильных результатов (стоит компромисс со временем)
max_iterМаксимальное количество итерацийУвеличивайте для сложных dataset, следя за сходимостью
tolПорог для определения сходимостиУменьшайте для более точных результатов
algorithmРеализация алгоритма ('auto', 'full', 'elkan')'elkan' быстрее для небольшого числа кластеров и размерностей

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

  1. Метод локтя (Elbow Method): Построение графика изменения инерции (суммы квадратов расстояний от точек до их центроидов) в зависимости от числа кластеров. Оптимальное число кластеров соответствует точке перегиба («локтю») на графике.
  2. Силуэтный анализ (Silhouette Analysis): Измерение качества кластеризации через оценку сплоченности внутри кластеров и разделения между ними.
  3. Gap-статистика: Сравнение изменения внутрикластерной дисперсии с ожидаемым изменением при равномерном распределении данных.

Пример кода для определения оптимального числа кластеров методом локтя:

Python
Скопировать код
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

inertia = []
k_range = range(1, 11)

for k in k_range:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
inertia.append(kmeans.inertia_)

plt.figure(figsize=(10, 6))
plt.plot(k_range, inertia, 'bx-')
plt.xlabel('Количество кластеров')
plt.ylabel('Инерция')
plt.title('Метод локтя для определения оптимального k')
plt.show()

При работе с реальными данными критически важна предварительная обработка. KMeans чувствителен к масштабированию признаков, поэтому стандартизация или нормализация часто необходима перед применением алгоритма:

Python
Скопировать код
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
kmeans = KMeans(n_clusters=3).fit(X_scaled)

Также следует учитывать влияние выбросов на результаты кластеризации — KMeans чувствителен к ним. В случае наличия выбросов стоит рассмотреть их удаление или использование более устойчивых алгоритмов кластеризации, таких как DBSCAN или KMedoids.

Применение Sklearn KMeans в бизнес-аналитике и науке

KMeans из библиотеки scikit-learn нашёл широкое применение в различных областях бизнеса и науки благодаря своей эффективности и интерпретируемости. Рассмотрим наиболее популярные и эффективные применения этого алгоритма: 📊

  • Сегментация клиентов — разделение клиентской базы на группы со схожим поведением для таргетированного маркетинга
  • Анализ рыночной корзины — определение групп товаров, часто покупаемых вместе
  • Обнаружение аномалий — выявление отклоняющихся образцов путем анализа расстояний до центроидов
  • Сжатие изображений — уменьшение цветовой палитры путем кластеризации цветов
  • Биоинформатика — кластеризация генетических данных для выявления групп генов со схожими паттернами экспрессии
  • Астрономия — классификация небесных объектов по их спектральным характеристикам

В бизнес-аналитике KMeans часто используется для Customer Relationship Management (CRM). Например, интернет-магазины применяют кластеризацию для сегментации клиентов на основе таких признаков, как частота покупок, средний чек, давность последней покупки и категории приобретаемых товаров.

Python
Скопировать код
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# Загружаем данные клиентов
customer_data = pd.read_csv('customer_data.csv')

# Выбираем признаки для кластеризации
features = customer_data[['recency', 'frequency', 'monetary', 'product_categories']]

# Стандартизация данных
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)

# Применяем KMeans
kmeans = KMeans(n_clusters=5, random_state=42)
customer_data['cluster'] = kmeans.fit_predict(features_scaled)

# Анализируем полученные сегменты
segment_analysis = customer_data.groupby('cluster').agg({
'recency': 'mean',
'frequency': 'mean',
'monetary': 'mean',
'product_categories': 'mean'
}).reset_index()

print(segment_analysis)

В области науки о данных KMeans часто служит промежуточным шагом в более сложных процессах анализа. Например, в обработке естественного языка (NLP) алгоритм используется для тематического моделирования или кластеризации документов:

Python
Скопировать код
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans

# Подготовка данных
documents = ["Machine learning is fascinating", 
"KMeans is a clustering algorithm",
"Python is great for data science",
"Clustering helps in data analysis",
"Programming in Python is fun"]

# Создание TF-IDF матрицы
vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(documents)

# Кластеризация документов
true_k = 2
model = KMeans(n_clusters=true_k, init='k-means++', max_iter=100, n_init=1)
model.fit(X)

# Анализ результатов
order_centroids = model.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names_out()

for i in range(true_k):
print(f"Cluster {i}:")
for ind in order_centroids[i, :5]:
print(f" {terms[ind]}")
print()

Реальные примеры успешного применения KMeans включают:

  1. Крупные ритейлеры используют KMeans для оптимизации ассортимента и планирования запасов, кластеризуя товары по показателям продаж
  2. Телекоммуникационные компании применяют кластеризацию для выявления групп пользователей с высоким риском оттока
  3. Страховые компании используют KMeans для сегментации страховых случаев и выявления потенциально мошеннических заявок
  4. В медицине алгоритм применяется для кластеризации пациентов по симптомам и реакции на лечение

Хотите научиться применять KMeans для решения практических задач в различных сферах бизнеса? Пройдите Тест на профориентацию от Skypro, чтобы определить, подходит ли вам карьера аналитика данных. Тест поможет оценить ваши предрасположенности к работе с алгоритмами машинного обучения и анализу данных, а также даст персонализированные рекомендации по развитию навыков в области кластеризации и других методов анализа.

Оценка качества кластеризации: метрики и визуализация

В отличие от задач с размеченными данными, оценка качества кластеризации представляет особую сложность, поскольку нет "правильных ответов" для сравнения. Однако существует ряд метрик и методов визуализации, позволяющих объективно оценить результаты работы KMeans. 📈

Основные метрики оценки качества кластеризации:

МетрикаОписаниеИнтерпретацияРеализация в scikit
Инерция (inertia)Сумма квадратов расстояний от точек до центроидов их кластеровМеньше = лучше; используется в методе локтяkmeans.inertia_
Силуэтный коэффициентОценивает, насколько объект похож на свой кластер по сравнению с другимиОт -1 до 1; выше = лучшеsklearn.metrics.silhouette_score
Davies-Bouldin индексСредняя "схожесть" между кластерамиНиже = лучшеsklearn.metrics.davies_bouldin_score
Calinski-Harabasz индексОтношение дисперсии между кластерами к дисперсии внутри кластеровВыше = лучшеsklearn.metrics.calinski_harabasz_score

Пример расчета метрик качества кластеризации:

Python
Скопировать код
from sklearn.metrics import (silhouette_score, davies_bouldin_score,
calinski_harabasz_score)
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import numpy as np

# Создаем синтетические данные
X, true_labels = make_blobs(n_samples=500, centers=4, 
cluster_std=0.70, random_state=0)

# Применяем KMeans
kmeans = KMeans(n_clusters=4, random_state=0)
cluster_labels = kmeans.fit_predict(X)

# Рассчитываем метрики
silhouette = silhouette_score(X, cluster_labels)
db_score = davies_bouldin_score(X, cluster_labels)
ch_score = calinski_harabasz_score(X, cluster_labels)

print(f"Инерция: {kmeans.inertia_:.2f}")
print(f"Силуэтный коэффициент: {silhouette:.2f}")
print(f"Davies-Bouldin индекс: {db_score:.2f}")
print(f"Calinski-Harabasz индекс: {ch_score:.2f}")

Визуализация результатов кластеризации — мощный инструмент для интерпретации и оценки качества. Для двухмерных данных можно использовать простое scatter-plot с цветовым кодированием кластеров:

Python
Скопировать код
import matplotlib.pyplot as plt

plt.figure(figsize=(10, 6))
plt.scatter(X[:, 0], X[:, 1], c=cluster_labels, cmap='viridis', 
marker='o', edgecolors='black', s=50)
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], 
c='red', marker='*', s=200, label='Centroids')
plt.title('KMeans Clustering Results')
plt.legend()
plt.grid(True)
plt.show()

Для данных более высокой размерности необходимо применять методы снижения размерности перед визуализацией. Наиболее популярные подходы:

  1. PCA (Principal Component Analysis) — линейное преобразование, сохраняющее максимальную дисперсию
  2. t-SNE (t-distributed Stochastic Neighbor Embedding) — нелинейное преобразование, сохраняющее локальную структуру
  3. UMAP (Uniform Manifold Approximation and Projection) — более быстрый аналог t-SNE, лучше сохраняющий глобальную структуру

Пример визуализации высокоразмерных данных с помощью PCA и t-SNE:

Python
Скопировать код
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE

# PCA для визуализации
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

# t-SNE для визуализации
tsne = TSNE(n_components=2, random_state=0)
X_tsne = tsne.fit_transform(X)

# Создаем полотно с двумя графиками
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))

# График PCA
ax1.scatter(X_pca[:, 0], X_pca[:, 1], c=cluster_labels, cmap='viridis', 
marker='o', edgecolors='black', s=50)
ax1.set_title('PCA Projection')

# График t-SNE
ax2.scatter(X_tsne[:, 0], X_tsne[:, 1], c=cluster_labels, cmap='viridis', 
marker='o', edgecolors='black', s=50)
ax2.set_title('t-SNE Projection')

plt.show()

Силуэтный анализ также предоставляет информативную визуализацию для оценки качества кластеризации, показывая, насколько хорошо каждый объект вписывается в свой кластер:

Python
Скопировать код
from sklearn.metrics import silhouette_samples

# Рассчитываем силуэтные коэффициенты для каждого образца
silhouette_vals = silhouette_samples(X, cluster_labels)

# Создаем график силуэтов
plt.figure(figsize=(10, 6))
y_ticks = []
y_lower, y_upper = 0, 0

for i, cluster in enumerate(np.unique(cluster_labels)):
cluster_silhouette_vals = silhouette_vals[cluster_labels == cluster]
cluster_silhouette_vals.sort()

y_upper += len(cluster_silhouette_vals)
plt.barh(range(y_lower, y_upper), cluster_silhouette_vals, height=1.0)

y_ticks.append((y_lower + y_upper) / 2)
y_lower += len(cluster_silhouette_vals)

plt.yticks(y_ticks, np.unique(cluster_labels))
plt.xlabel('Silhouette Coefficient')
plt.axvline(silhouette, color='red', linestyle='--')
plt.title('Silhouette Analysis')
plt.show()

Продвинутые техники работы со Sklearn Cluster KMeans

Анна Ковалева, Data Science Lead

В 2024 году наша команда столкнулась с задачей кластеризации огромного набора текстовых данных — более 5 миллионов отзывов пользователей. Стандартный KMeans не справлялся из-за высокой размерности и объема данных. Мы применили MiniBatchKMeans, который позволил обрабатывать данные порциями. Настроив размер батча в 10000 образцов и используя инкрементальное обучение, мы снизили время выполнения с более чем 12 часов до 45 минут! Это был прорыв. Но настоящее волшебство произошло, когда мы добавили предобработку с помощью метода BFR (Bradley-Fayyad-Reina), сжав данные в микрокластеры перед применением MiniBatchKMeans. Точность немного снизилась, но вычислительная эффективность выросла в разы. Когда руководство увидело, как быстро мы можем теперь обновлять сегментацию пользовательских отзывов, это изменило всю стратегию работы с клиентским опытом в компании.

Хотя базовая версия KMeans — мощный инструмент, scikit-learn предлагает продвинутые техники, позволяющие преодолеть ограничения стандартной реализации и повысить эффективность анализа данных. 🚀

MiniBatchKMeans для больших наборов данных

Когда объем данных настолько велик, что не помещается в оперативной памяти или требует значительного времени обработки, MiniBatchKMeans становится незаменимым:

Python
Скопировать код
from sklearn.cluster import MiniBatchKMeans
import numpy as np
import time

# Генерируем большой набор данных
X = np.random.rand(100000, 50)

# Сравниваем стандартный KMeans и MiniBatchKMeans
start = time.time()
kmeans = KMeans(n_clusters=5, random_state=0, n_init=3).fit(X)
end = time.time()
print(f"Стандартный KMeans: {end – start:.2f} секунд")

start = time.time()
batch_size = 1000 # Размер мини-батча
mbk = MiniBatchKMeans(n_clusters=5, batch_size=batch_size, 
random_state=0, n_init=3).fit(X)
end = time.time()
print(f"MiniBatchKMeans: {end – start:.2f} секунд")

MiniBatchKMeans обрабатывает в каждой итерации только подмножество данных (мини-батч), что значительно снижает требования к памяти и ускоряет обработку. Подбор размера батча — ключевой фактор для балансировки между скоростью и качеством кластеризации.

Ансамблевая кластеризация

Ансамблевые методы повышают стабильность и качество кластеризации путем объединения множества отдельных моделей:

Python
Скопировать код
from sklearn.cluster import KMeans
import numpy as np
from sklearn.metrics import adjusted_rand_score

# Функция для создания ансамбля KMeans моделей
def kmeans_ensemble(X, n_clusters, n_estimators=10, subsample_ratio=0.8, 
random_state=None):
n_samples = X.shape[0]
subsample_size = int(n_samples * subsample_ratio)

# Генерируем базовые кластеризаторы
base_labels = np.zeros((n_samples, n_estimators))

for i in range(n_estimators):
rs = random_state + i if random_state else None
# Случайная подвыборка данных
indices = np.random.choice(n_samples, subsample_size, replace=False)
X_subsample = X[indices]

# Обучаем модель
kmeans = KMeans(n_clusters=n_clusters, random_state=rs)
kmeans.fit(X_subsample)

# Предсказываем для всего набора данных
base_labels[:, i] = kmeans.predict(X)

# Создаем матрицу совстречаемости
co_association = np.zeros((n_samples, n_samples))
for i in range(n_estimators):
labels = base_labels[:, i]
for j in range(n_samples):
for k in range(j+1, n_samples):
if labels[j] == labels[k]:
co_association[j, k] += 1
co_association[k, j] += 1

co_association /= n_estimators

# Финальная кластеризация матрицы совстречаемости
final_kmeans = KMeans(n_clusters=n_clusters, random_state=random_state)
final_labels = final_kmeans.fit_predict(co_association)

return final_labels

KMeans с пользовательскими метриками расстояния

Хотя стандартный KMeans использует евклидово расстояние, можно реализовать версии с другими метриками для особых типов данных:

Python
Скопировать код
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

class CosineKMeans:
def __init__(self, n_clusters=8, max_iter=300, random_state=None):
self.n_clusters = n_clusters
self.max_iter = max_iter
self.random_state = random_state
self.cluster_centers_ = None
self.labels_ = None

def fit(self, X):
n_samples = X.shape[0]

# Инициализация: случайно выбираем центроиды из данных
np.random.seed(self.random_state)
indices = np.random.choice(n_samples, self.n_clusters, replace=False)
self.cluster_centers_ = X[indices]

# Нормализация центроидов для косинусного сходства
self.cluster_centers_ = self.cluster_centers_ / np.linalg.norm(
self.cluster_centers_, axis=1, keepdims=True
)

for _ in range(self.max_iter):
# Вычисляем косинусное сходство между точками и центроидами
similarities = cosine_similarity(X, self.cluster_centers_)

# Назначаем точки ближайшим центроидам
new_labels = np.argmax(similarities, axis=1)

# Если назначения не изменились, прекращаем
if hasattr(self, 'labels_') and np.all(new_labels == self.labels_):
break

self.labels_ = new_labels

# Обновляем центроиды
for i in range(self.n_clusters):
if np.sum(self.labels_ == i) > 0:
self.cluster_centers_[i] = np.mean(
X[self.labels_ == i], axis=0
)
# Нормализация для косинусного расстояния
self.cluster_centers_[i] /= np.linalg.norm(
self.cluster_centers_[i]
)

return self

def predict(self, X):
similarities = cosine_similarity(X, self.cluster_centers_)
return np.argmax(similarities, axis=1

Обработка разреженных данных

Для анализа разреженных данных (например, в обработке текстов) важно использовать специальные оптимизации:

Python
Скопировать код
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import TruncatedSVD

# Подготовка текстовых данных
documents = [
"Machine learning algorithms are powerful tools",
"KMeans is popular for clustering tasks",
"Data science involves statistics and programming",
"Python is widely used in machine learning",
"Clustering helps in data segmentation",
"Natural language processing analyzes text"
]

# Создание разреженной TF-IDF матрицы
vectorizer = TfidfVectorizer(stop_words='english')
X_sparse = vectorizer.fit_transform(documents)

# Для больших разреженных матриц: снижение размерности перед кластеризацией
svd = TruncatedSVD(n_components=10)
X_reduced = svd.fit_transform(X_sparse)

# Применяем KMeans
kmeans = KMeans(n_clusters=2, random_state=0)
labels = kmeans.fit_predict(X_reduced)

# Выводим результаты
for i, doc in enumerate(documents):
print(f"Document {i+1} (Cluster {labels[i]}): {doc}")

Алгоритм KMeans продолжает совершенствоваться, и последние исследования предлагают инновационные подходы к улучшению его производительности и результатов:

  • KMeans++ с адаптивным выбором начальных центроидов на основе плотности данных
  • Интеграция с автоэнкодерами для работы с нелинейными структурами данных
  • Использование методов объяснимого ИИ (XAI) для интерпретации результатов кластеризации
  • Параллельные и распределенные реализации для обработки сверхбольших данных

Определить, в какой области анализа данных вы можете максимально реализовать свой потенциал, поможет Тест на профориентацию от Skypro. Пройдя тестирование, вы узнаете, подходит ли вам работа с алгоритмами кластеризации и другими методами машинного обучения, и получите рекомендации по развитию востребованных навыков в сфере data science, включая продвинутое применение KMeans для решения сложных аналитических задач.

KMeans из библиотеки Scikit-learn — это не просто инструмент, а своего рода швейцарский нож в арсенале каждого аналитика и Data Scientist. Освоив принципы работы, тонкую настройку параметров и продвинутые техники применения этого алгоритма, вы получаете возможность видеть структуры там, где другие видят лишь хаос данных. Именно эта способность превращать неструктурированную информацию в инсайты определяет разницу между рядовым специалистом и настоящим мастером анализа данных. Стоит помнить, что кластеризация — это не конечная точка, а отправная для дальнейшего осмысления данных, принятия решений и создания ценности для бизнеса и науки.