← Назад к вопросам

Как определить оптимальное количество кластеров?

2.0 Middle🔥 151 комментариев
#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как определить оптимальное количество кластеров?

Определение оптимального числа кластеров - одна из главных задач в неконтролируемом обучении. Не существует универсального решения, поэтому используется набор методов и эвристик для поиска наилучшего значения параметра 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 находится на пересечении нескольких методов оценки и бизнес-требований задачи.