Кластеризация K-means: как находить группы без ответов
K-means делит числовые объекты на заданное число кластеров, минимизируя расстояния до центров групп. Алгоритм работает без целевой переменной, поэтому результат не является…
K-means делит числовые объекты на заданное число кластеров, минимизируя расстояния до центров групп. Алгоритм работает без целевой переменной, поэтому результат не является готовой классификацией: смысл и полезность каждого кластера устанавливаются после обучения.
Что оптимизирует алгоритм
Сначала выбираются k центров. Каждый объект относится к ближайшему центру, затем центр пересчитывается как среднее точек своей группы. Назначение и обновление повторяются, пока изменения не станут достаточно малы.
Целевая величина inertia — сумма квадратов расстояний до ближайших центров. Она всегда уменьшается или остаётся прежней при росте k и достигает нуля, если дать отдельный кластер каждой уникальной точке. Поэтому минимальная inertia сама не выбирает разумное число групп.
Масштаб и форма кластеров
K-means опирается на евклидово расстояние и лучше всего находит компактные примерно сферические группы сопоставимого размера. Вытянутые области, вложенные кольца, разная плотность и сильные выбросы могут привести к искусственному разбиению.
Стандартизация нужна, когда единицы столбцов различаются. Но она выражает предположение, что стандартизованные направления имеют сопоставимую важность. Предметный смысл всё равно определяет, какие признаки должны участвовать.
Пример сегментации
import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
X, _ = make_blobs(
n_samples=500,
centers=4,
cluster_std=[1.0, 1.6, 0.8, 1.2],
random_state=42,
)
clusterer = make_pipeline(
StandardScaler(),
KMeans(n_clusters=4, n_init=10, random_state=42),
)
labels = clusterer.fit_predict(X)
scaled_X = clusterer.named_steps['standardscaler'].transform(X)
print('silhouette:', silhouette_score(scaled_X, labels))
print('sizes:', dict(zip(*np.unique(labels, return_counts=True))))Silhouette сравнивает компактность своей группы с расстоянием до соседней. Высокое значение полезно как диагностика геометрии, но не гарантирует, что сегменты помогают продуктовой задаче.
Как выбирать число кластеров
Метод локтя ищет точку, после которой уменьшение inertia замедляется. Silhouette позволяет сравнить несколько k. Оба критерия дополняются устойчивостью: повторите обучение на подвыборках и проверьте, сохраняются ли профили групп.
Финальный выбор включает внешнюю пользу. Если сегмент нельзя описать, отличить в будущем или связать с отдельным действием, красивое разбиение может не иметь практической ценности.
Номера не являются именами
Метка 0 не означает «лучший клиент», а после повторного обучения прежняя группа может получить другой номер. Сохраняйте центры и описывайте кластеры через распределения исходных признаков. Для сравнения запусков сопоставляйте группы по центрам или составу, а не по номеру.
Новый объект можно отнести к ближайшему центру через predict, но сильный сдвиг данных требует повторной проверки структуры.
Практика: проверьте устойчивость
Создайте две явно разделённые группы и несколько далёких выбросов. Сравните K-means для k от 2 до 5 до и после масштабирования. Удалите выбросы только в отдельной копии и объясните, как изменились центры. Дайте группам предметные описания без использования номеров.
Что важно запомнить
- K-means минимизирует квадраты расстояний объектов до центров.
- Число кластеров задаётся и проверяется несколькими способами.
- Масштабирование и выбросы заметно меняют геометрию.
- Номер кластера условен, а его смысл требует внешней интерпретации.