Кластеризация, то есть разделение элементов выборки по схожести, является видом так называемого обучения без учителя - мы изначально не знаем, какие признаки имеют наши
Кластеризацию не стоит путать с уменьшением размерности данных: кластеризация - это поиск общих групп, а уменьшение размерности - поиск нового представления данных
Можно выделить 4 подхода:
В методах, основанных на центрах, алгоритмы ищут центроиды - точки, которые описывают центры будущих кластеров
Центроид - это такая точка, сумма квадратов расстояний до точек в кластере минимальна
В методе $k$ средних (k-means):
Алгоритм повторяется до тех пор, пока положение центроидов меняется

Выбор точек может быть таким:
Большим недостатком методов, основанных на центроидах, - это выбор числа кластеров $k$. Также методом $k$ средних плохо различаются кластеры невыпуклой формы
В методах, основанных на плотностях, другой подход. В них точки считаются кластерами, если они плотно (то есть близко) расположены
Популярным таким методом является DBSCAN (Density-Based Spatial Clustering of Applications with Noise, Основанная на плотности пространственная кластеризация для приложений с шумами) и работает так:
Если их больше определенного числа $\text{min\_samples}$, то считается, то они принадлежат одному кластеру
Точка, вокруг которой есть $\text{min\_samples}$ точек, считается основной (core point). Точка, вокруг которой меньше $\text{min\_samples}$ точек, но она принадлежит кластеру, считается пограничной (border point)

Наивно DBSCAN работает за квадрат (считаем все расстояния между точками), однако с помощью деревьев и индексов можно получить асимптотику лучше
Иерархическая кластеризация - это метод кластеризации, который строит иерархию кластеров в виде дерева, которое называется дендрограммой. Такие методы делятся на агломеративные (от меньших кластеров к большим) и дивизивные (от больших к меньшим)
Чаще всего используется агломеративный подход, который работает так:


Если расстояния между точками тривиально вычисляется, то расстояния между кластерами (так называемый linkage) можно считать разными способами
Также сами расстояния между точками можно вычислять по-разному: евклидово, манхеттенское, косинусное и так далее
Иерархическая кластеризация позволяет взглянуть, как кластеры друг к другу относятся, однако:
Код примера - machlearn_agglomerative_clustering.py
Методы можно комбинировать - так появился HDBSCAN (Hierarchical DBSCAN). В нем:
Здесь не используется параметр $\varepsilon$, что позволяет хорошо выделять кластера с разными плотностями. Однако, можно задать $\text{min \_ cluster \_ size}$ - минимальный размер устойчивого кластера
Устойчивыми кластерами считаются те, которые долго не распадаются. Для этого вводится метрика $\displaystyle \mathrm{Stability}(C) = \sum_{i \in C} (\lambda_{i} - \mu_{C})$, где $\mu_{C} = \frac{1}{\mathrm{mreach}(x, y)}$ - обратное к весу ребра, удаление которого привело к появлению кластера, а $\lambda_{i} = \frac{1}{\mathrm{mreach}(x_i, x_j)}$ - обратное к весу ребра, удаление которого привело к отделению $i$-ой точки
Для такой иерархии кластеров

стабильность кластера 1 определяется как сумма $(0.067 - 0.034) + (0.067 - 0.034) + (0.069 - 0.034) + (0.069 - 0.034) + (0.073 - 0.034) + (0.073 - 0.034) + (0.059 - 0.034) = 0.239$ 😲
А стабильность кластера 3 равна $(0.059 - 0.055) + (0.073 - 0.055) + (0.073 - 0.055) = 0.04$
Дополнительная информация о HDBSCAN: https://lanselin.github.io/introbook_vol1/HDBSCAN.html
Чтобы оценить, насколько хороша кластеризация выборки, можно использовать следующие метрики:
Оценка силуэта (Silhouette score)
Для $i$-ой точки в кластере определим $\displaystyle a(i) = \frac{1}{\vert C_i \vert - 1} \sum_{x_j \in C_i, i \neq j} \mathrm{dist}(x_i, x_j)$ - среднее расстояние от выбранной точки до остальных в том же кластере
Также определим $\displaystyle b(i) = \min_j \frac{1}{\vert C_j \vert} \sum_{x_k \in C_j} \mathrm{dist}(x_i, x_k)$ - минимальное из средних расстояний от выбранной точки до точек другого кластера
Тогда оценка силуэта для точки считается равной как $s(i) = \frac{b(i) - a(i)}{\max(b(i), a(i))}$
Для кластера из одной точки $s(i) = 0$. Из определения видно, что $s(i) \in [-1; 1]$
Чем больше оценка силуэта, тем наиболее правильно точка отнесена к кластеру
На основе этого можно построить график оценок силуэта (Silhouette plot):

Здесь красная пунктирная линия - среднее из оценок для всех точек. Кластеры считаются хорошо разделенными, если максимум оценки силуэта точек внутри кластера больше этого среднего
Код примера - machlearn_silhouette_plot.py
Оценка или индекс DBCV (Density-Based Clustering Validation)
Оценка DBCV считается так:
Метрика DBCV высока, если кластеры состоят из плотно расположенных точек, и учитывает более сложную форму кластеров, чем оценка силуэта

Код примера - machlearn_silhouette_dbcv.py
Статья про DBCV: https://www.researchgate.net/publication/260333211_Density-Based_Clustering_Validation
Оценка Калински-Харабаша (или критерий дисперсионного отношения, Variance Ratio Criterion, VRC)
Оценка Калински-Харабаша вычисляется так: $\mathrm{CH} = \frac{\mathrm{BCSS}}{k - 1} \frac{n - k}{\mathrm{WCSS}}$, где $k$ - число кластеров, $n$ - размер выборки
Здесь $\displaystyle \mathrm{BCSS} = \sum_{i = 1}^k n_i | c_i - c |^2$ - межкластерная сумма квадратов расстояний (Between-Cluster Sum of Squares), где $c_i$ - центроид $i$-ого кластера, $n_i$ - размер $i$-ого кластера, $c$ - среднее всех точек из выборки
$\displaystyle \mathrm{WCSS} = \sum_{i = 1}^k \sum_{x \in C_i} | x - c_i |^2$ - внутрикластерная сумма квадратов расстояний (Within-Cluster Sum of Squares), где $c_i$ - центроид $i$-ого кластера, $x$ - точка из $i$-ого кластера
Метод локтя (Elbow method или Knee method)
Метод локтя применяется для определения оптимального числа кластеров. Для этого:
Далее данные наносят на график:

$\mathrm{WCSS}$ при увеличении числа кластеров будет уменьшаться (так как в пределе один кластер - это одна точка, которая является центроидом кластера), однако после некоторого числа кластеров уменьшение будет не таким значимым
Это число считается оптимальным для разбиения, для примера на картинке таковым является 5
Код примера - machlearn_cluster_elbow_method.py
Чистота кластеров (Purity)
Если метки кластеров для точек заранее известны, то можно воспользоваться метрикой чистоты кластеров \(\mathrm{Purity}(C_k) = \frac{1}{\vert C_k \vert} \max_{c} \vert \{ x_i \in C_k \} \, \vert \, y_i = c \vert\)
Для всех данных чистота определяется как взвешенное среднее: $\mathrm{Purity} = \frac{1}{n} \sum_{i = 1}^k \vert C_i \vert \mathrm{Purity}(C_i)$
Удержание (Retention)
Удержание - это доля объектов, которые остались в том же кластере при кластеризации с немного измененными объектами: $\mathrm{Retention} = \frac{1}{N} \sum_i I(y_i^{(1)} = y_i^{(2)})$
Идея состоит в том, что при кластеризации с немного измененными параметрами (например, при изменении $\varepsilon$ в DBSCAN) объекты должны попадать в те же кластеры, а если кластеры сильно меняются, то выбранный метод кластеризации нестабилен на этих данных