Как определить оптимальное количество кластеров?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как определить оптимальное количество кластеров?
Определение оптимального числа кластеров - одна из главных задач в неконтролируемом обучении. Не существует универсального решения, поэтому используется набор методов и эвристик для поиска наилучшего значения параметра k в алгоритме K-means или иных методах кластеризации.
Основные методы
1. Метод Elbow (Локтя)
Будуем график инерции (суммы квадратов расстояний от точек до центроидов) в зависимости от количества кластеров. Ищем "локоть" - точку, где прирост качества замедляется.
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
inertias = []
K_range = range(1, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(X)
inertias.append(kmeans.inertia_)
plt.figure(figsize=(8, 5))
plt.plot(K_range, inertias, "bo-", linewidth=2, markersize=8)
plt.xlabel("Количество кластеров (k)")
plt.ylabel("Инерция")
plt.title("Метод Elbow")
plt.grid(True, alpha=0.3)
plt.show()
# На графике ищем точку, где кривая резко меняет наклон
Минусы: субъективный выбор точки локтя, не всегда четко видна.
2. Silhouette Score
Измеряет, насколько хорошо каждая точка принадлежит своему кластеру (от -1 до 1, чем выше - лучше).
from sklearn.metrics import silhouette_score
silhouette_scores = []
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = silhouette_score(X, labels)
silhouette_scores.append(score)
best_k = K_range[np.argmax(silhouette_scores)]
plt.figure(figsize=(8, 5))
plt.plot(K_range, silhouette_scores, "ro-", linewidth=2, markersize=8)
plt.xlabel("Количество кластеров (k)")
plt.ylabel("Silhouette Score")
plt.axvline(x=best_k, color="g", linestyle="--", label=f"Лучший k={best_k}")
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
print(f"Оптимальное k по Silhouette: {best_k}")
Преимущества: объективная метрика, не требует знания истинных меток. Недостатки: вычислительно дорогая для больших данных.
3. Davies-Bouldin Index
Измеряет среднее сходство каждого кластера с его наиболее похожим соседом (чем ниже - лучше).
from sklearn.metrics import davies_bouldin_score
davies_bouldin_scores = []
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = davies_bouldin_score(X, labels)
davies_bouldin_scores.append(score)
best_k = K_range[np.argmin(davies_bouldin_scores)]
plt.plot(K_range, davies_bouldin_scores, "go-", linewidth=2, markersize=8)
plt.xlabel("Количество кластеров (k)")
plt.ylabel("Davies-Bouldin Index")
plt.axvline(x=best_k, color="r", linestyle="--")
plt.title("Davies-Bouldin Index (меньше - лучше)")
plt.show()
4. Calinski-Harabasz Index (Variance Ratio Criterion)
Отношение межкластерной дисперсии к внутрикластерной (чем выше - лучше).
from sklearn.metrics import calinski_harabasz_score
calinski_scores = []
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
score = calinski_harabasz_score(X, labels)
calinski_scores.append(score)
best_k = K_range[np.argmax(calinski_scores)]
plt.plot(K_range, calinski_scores, "mo-", linewidth=2, markersize=8)
plt.xlabel("Количество кластеров (k)")
plt.ylabel("Calinski-Harabasz Index")
plt.axvline(x=best_k, color="c", linestyle="--")
plt.show()
Комплексный подход
# Комбинируем несколько метрик
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X)
sil_score = silhouette_score(X, labels)
db_score = davies_bouldin_score(X, labels)
ch_score = calinski_harabasz_score(X, labels)
print(f"k={k}: Silhouette={sil_score:.3f}, DB={db_score:.3f}, CH={ch_score:.1f}")
Практические рекомендации
- Начните с Elbow: быстро и интуитивно определит примерный диапазон k.
- Используйте Silhouette Score: дает объективную оценку качества кластеризации.
- Комбинируйте методы: если разные метрики указывают на разные k, анализируйте результаты для каждого значения.
- Учитывайте бизнес-смысл: k должно быть интерпретируемо в контексте задачи.
- Валидируйте внешне: если есть экспертное мнение или доменные знания, используйте их.
- Для иерархической кластеризации: используйте дендрограмму для визуального выбора количества кластеров.
Оптимальное k находится на пересечении нескольких методов оценки и бизнес-требований задачи.