Оценка качества кластеризации

Оценка качества кластеризации#

Оценка эффективности алгоритма кластеризации не так проста, как подсчет MSE Loss. В частности, любая метрика оценки должна учитывать не абсолютные значения меток кластеров, а то, определяет ли кластеризация разделение данных, сходное с некоторым истинным набором классов или удовлетворяющее некоторому предположению, например, что члены одного класса более сходны, чем члены разных классов, согласно некоторой мере несходства.

На практике стоит перебирать различные метрики качества для полученных кластеров, чтобы определить наилучшее разделение при отсутствии картинки (или чтобы подбирать гиперпараметры).

Примечание о картинке

Картинку-таки можно получить почти для чего угодно. Гуглите t-SNE. Оно в семинар явно не влезает, а штука мемная.

Таких метрик качества кластеризации очень много (см. пункт 2.3.11.). Их можно разделить на

  • Внешние: Мы знаем истинные кластеры, и хотим проверить качество кластеризации, «зная истину». Применимы, когда часть объектов уже кластеризована ручками (можно сказать, классифицирована).

  • Внутренние: Не знаем ничего о данных и какие там на самом деле кластеры. Максимально общо, смотрят на «красоту» полученных кластеров с точки зрения какой-либо статистики. На практике, наилучшим образом работает Score Function, хотя в конкретной задаче никто ничего не гарантирует (опять-таки, разумно перебирать разные).

Отмечу, что многие внутренние метрики ломаются, если получился всего один кластер.

Как правило, чем метрика чем больше, тем лучше, но не всегда. Будьте внимательны.

Хороший обзор всех методов оценки качества кластеризации тут.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_blobs
from sklearn.cluster import DBSCAN
from sklearn.metrics import adjusted_rand_score, homogeneity_score, completeness_score # Внешние метрики
from sklearn.metrics import silhouette_score, calinski_harabasz_score, davies_bouldin_score # Внутренние метрики (не использую label)

# Создаем датасет
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)

# Гиперпараметры для DBSCAN
eps_values = [0.3, 0.5, 0.7]
min_samples_values = [5, 10, 15]

# Пустой DataFrame для хранения результатов
results = pd.DataFrame(columns=['eps', 'min_samples', 'ARI', 'Homogeneity', 'Completeness', 'Silhouette', 'Calinski-Harabasz', 'Davies-Bouldin'])

# Оценка качества кластеризации
for eps in eps_values:
    for min_samples in min_samples_values:
        db = DBSCAN(eps=eps, min_samples=min_samples).fit(X)
        labels = db.labels_

        # Исключаем кластеризации с одним кластером или с шумом
        if len(set(labels)) > 1 and -1 in labels:
            row_results = pd.DataFrame({
                'eps': [eps],
                'min_samples': [min_samples],
                'ARI': [adjusted_rand_score(y, labels)],
                'Homogeneity': [homogeneity_score(y, labels)],
                'Completeness': [completeness_score(y, labels)],
                'Silhouette': [silhouette_score(X, labels)],
                'Calinski-Harabasz': [calinski_harabasz_score(X, labels)],
                'Davies-Bouldin': [davies_bouldin_score(X, labels)]
            })
            results = pd.concat([results, row_results], ignore_index=True)

# Отображение результатов
plt.scatter(X[:, 0], X[:, 1], s=50, edgecolor='k')
display(results)
eps min_samples ARI Homogeneity Completeness Silhouette Calinski-Harabasz Davies-Bouldin
0 0.3 5 0.457188 0.746654 0.525633 -0.025531 56.615042 2.346569
1 0.3 10 0.093600 0.423733 0.389259 -0.250812 21.101147 2.331979
2 0.5 5 0.914246 0.941359 0.852961 0.630380 473.017056 2.782135
3 0.5 10 0.764861 0.849321 0.735182 0.522095 243.583997 2.426602
4 0.5 15 0.594839 0.749542 0.650764 0.387169 132.366505 2.312980
5 0.7 5 0.697922 0.741675 0.939557 0.559707 381.901589 2.065549
6 0.7 10 0.954275 0.961822 0.905730 0.656940 674.309779 2.317169
7 0.7 15 0.900436 0.925353 0.835969 0.619821 488.004158 3.833437
../../_images/2f2c9b6d379fa463a0a3797a12660a7a05b03b07bdf63018d5ba4c86a90b2ed1.png