Ответ
K-Means — итеративный алгоритм кластеризации без учителя, который разбивает данные на K кластеров. Каждый кластер описывается своим центроидом (средней точкой).
Алгоритм (шаги):
- Инициализация: случайный выбор K точек как начальных центроидов
- Назначение: каждая точка назначается ближайшему центроиду
- Обновление: пересчет центроидов как среднего точек кластера
- Повторение: шаги 2-3 до сходимости (центроиды не меняются) или лимита итераций
Пример реализации на Python:
import numpy as np
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt
# Генерация синтетических данных
X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)
# Применение K-Means
kmeans = KMeans(n_clusters=4, init='k-means++', n_init=10, random_state=42)
kmeans.fit(X)
# Результаты
labels = kmeans.labels_
centroids = kmeans.cluster_centers_
print(f"Метки кластеров: {labels[:10]}")
print(f"Центроиды:n{centroids}")
print(f"Инерция (within-cluster SSE): {kmeans.inertia_:.2f}")
# Визуализация
plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', alpha=0.6)
plt.scatter(centroids[:, 0], centroids[:, 1], c='red', marker='X', s=200)
plt.title('K-Means Clustering')
plt.show()
Ключевые параметры и методы:
- n_clusters: количество кластеров K (определяется методом локтя или силуэта)
- init: стратегия инициализации ('k-means++', 'random')
- n_init: количество запусков с разными начальными центроидами
- max_iter: максимальное количество итераций
Ограничения и решения:
- Чувствительность к инициализации → используйте
init='k-means++' - Требует указания K → применяйте Elbow Method или Silhouette Analysis
- Работает только с числовыми данными → требуется предобработка категориальных признаков
- Предполагает сферические кластеры → для сложных форм используйте DBSCAN или спектральную кластеризацию
Метод локтя для выбора K:
inertias = []
K_range = range(1, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
inertias.append(kmeans.inertia_)
# График "локтя" - точка изгиба показывает оптимальное K
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('Количество кластеров K')
plt.ylabel('Инерция')
plt.title('Elbow Method')
plt.show()