Ответ
Подбор модели кластеризации — итеративный процесс, который включает выбор алгоритма, определение оптимального числа кластеров и оценку результата.
1. Выбор алгоритма: Зависит от структуры данных и задачи.
- K-Means / K-Medoids: Для сферических кластеров примерно одинакового размера. Чувствителен к выбросам.
- DBSCAN: Для кластеров произвольной формы и обнаружения шума (выбросов). Не требует задания числа кластеров.
- Agglomerative Clustering (иерархическая): Для построения дендрограммы и анализа иерархии кластеров.
- Gaussian Mixture Models (GMM): Для кластеров, имеющих форму эллипсоидов (мягкая кластеризация с вероятностями принадлежности).
2. Определение числа кластеров (для K-Means):
- Метод локтя (Elbow Method): Ищем "изгиб" на графике зависимости инерции (within-cluster sum of squares) от числа кластеров.
- Силуэтный анализ (Silhouette Analysis): Выбираем число кластеров, максимизирующее средний силуэтный коэффициент (от -1 до 1).
3. Оценка качества кластеризации:
Внутренние метрики (нет истинных меток):
- Silhouette Score: Оценивает, насколько объект похож на свой кластер по сравнению с другими кластерами. Ближе к 1 — лучше.
- Индекс Дэвиса-Боулдина (DBI): Оценивает среднее сходство между кластерами. Ближе к 0 — лучше.
- Индекс Калински-Харабаса (CHI): Отношение межкластерной дисперсии к внутрикластерной. Выше — лучше.
Внешние метрики (есть истинные метки):
- Adjusted Rand Index (ARI): Измеряет сходство двух кластеризаций с поправкой на случайность. От -1 до 1.
- Normalized Mutual Information (NMI): Измеряет взаимную информацию между кластеризациями, нормализованную по энтропии. От 0 до 1.
Практический пример с K-Means и силуэтным анализом:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, davies_bouldin_score
# Генерация синтетических данных
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)
# Подбор числа кластеров методом локтя и силуэта
inertia = []
silhouette_scores = []
K_range = range(2, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto').fit(X)
inertia.append(kmeans.inertia_)
silhouette_scores.append(silhouette_score(X, kmeans.labels_))
# Визуализация
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(K_range, inertia, 'bo-')
ax1.set_title('Метод локтя')
ax1.set_xlabel('Число кластеров')
ax1.set_ylabel('Инерция')
ax2.plot(K_range, silhouette_scores, 'ro-')
ax2.set_title('Силуэтный анализ')
ax2.set_xlabel('Число кластеров')
ax2.set_ylabel('Силуэтный коэффициент')
plt.show()
# Обучение финальной модели с выбранным k=4
best_k = 4
final_model = KMeans(n_clusters=best_k, random_state=42, n_init='auto').fit(X)
labels = final_model.labels_
# Оценка
print(f"Silhouette Score: {silhouette_score(X, labels):.3f}")
print(f"Davies-Bouldin Index: {davies_bouldin_score(X, labels):.3f}")