Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере с помощью JupyterLite или Binder.

Иерархическая кластеризация со структурой и без неё

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

Дополнительные сведения см. в разделе Иерархическая кластеризация.

У наложения ограничений связности есть два преимущества. Во-первых, кластеризация с разреженными матрицами связности обычно выполняется быстрее.

Во-вторых, при использовании матрицы связности методы одиночной, средней и полной связи нестабильны и склонны быстро формировать несколько разрастающихся кластеров. Действительно, методы средней и полной связи противодействуют такому поведению, учитывая при объединении все расстояния между двумя кластерами (тогда как метод одиночной связи усугубляет это поведение, учитывая только кратчайшее расстояние между кластерами). Граф связности нарушает этот механизм для методов средней и полной связи, делая их похожими на более хрупкий метод одиночной связи. Этот эффект сильнее выражен для очень разреженных графов (попробуйте уменьшить число соседей в kneighbors_graph) и при использовании полной связи. В частности, очень малое число соседей в графе задаёт геометрию, близкую к геометрии метода одиночной связи, который, как известно, подвержен такой нестабильности из-за перколяции.

Эффект наложения ограничений связности показан на двух различных, но похожих наборах данных со спиральной структурой. В первом примере мы создаём набор данных «швейцарский рулет» и выполняем иерархическую кластеризацию по координатам данных. Здесь мы сравниваем кластеризацию Уорда без структуры с её структурированным вариантом, который обеспечивает связность k ближайших соседей. Во втором примере мы показываем последствия применения такого графа связности к методам одиночной, средней и полной связи.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Создание набора данных «швейцарский рулет».

import time

from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import make_swiss_roll

n_samples = 1500
noise = 0.05
X1, _ = make_swiss_roll(n_samples, noise=noise)
X1[:, 1] *= 0.5  # Make the roll thinner

Вычисление кластеризации без ограничений связности

print("Compute unstructured hierarchical clustering...")
st = time.time()
ward_unstructured = AgglomerativeClustering(n_clusters=6, linkage="ward").fit(X1)
elapsed_time_unstructured = time.time() - st
label_unstructured = ward_unstructured.labels_
print(f"Elapsed time: {elapsed_time_unstructured:.2f}s")
print(f"Number of points: {label_unstructured.size}")
Compute unstructured hierarchical clustering...
Elapsed time: 0.04s
Number of points: 1500

Построение графика результата кластеризации без структуры

import matplotlib.pyplot as plt
import numpy as np

fig1 = plt.figure()
ax1 = fig1.add_subplot(111, projection="3d", elev=7, azim=-80)
ax1.set_position([0, 0, 0.95, 1])
for l in np.unique(label_unstructured):
    ax1.scatter(
        X1[label_unstructured == l, 0],
        X1[label_unstructured == l, 1],
        X1[label_unstructured == l, 2],
        color=plt.cm.jet(float(l) / np.max(label_unstructured + 1)),
        s=20,
        edgecolor="k",
    )
_ = fig1.suptitle(
    f"Without connectivity constraints (time {elapsed_time_unstructured:.2f}s)"
)
Without connectivity constraints (time 0.04s)

Вычисление кластеризации с ограничениями связности

from sklearn.neighbors import kneighbors_graph

connectivity = kneighbors_graph(X1, n_neighbors=10, include_self=False)

print("Compute structured hierarchical clustering...")
st = time.time()
ward_structured = AgglomerativeClustering(
    n_clusters=6, connectivity=connectivity, linkage="ward"
).fit(X1)
elapsed_time_structured = time.time() - st
label_structured = ward_structured.labels_
print(f"Elapsed time: {elapsed_time_structured:.2f}s")
print(f"Number of points: {label_structured.size}")
Compute structured hierarchical clustering...
Elapsed time: 0.06s
Number of points: 1500

Построение графика результата структурированной кластеризации

fig2 = plt.figure()
ax2 = fig2.add_subplot(111, projection="3d", elev=7, azim=-80)
ax2.set_position([0, 0, 0.95, 1])
for l in np.unique(label_structured):
    ax2.scatter(
        X1[label_structured == l, 0],
        X1[label_structured == l, 1],
        X1[label_structured == l, 2],
        color=plt.cm.jet(float(l) / np.max(label_structured + 1)),
        s=20,
        edgecolor="k",
    )
_ = fig2.suptitle(
    f"With connectivity constraints (time {elapsed_time_structured:.2f}s)"
)
With connectivity constraints (time 0.06s)

Создание двумерного набора данных со спиралью.

n_samples = 1500
np.random.seed(0)
t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, n_samples))
x = t * np.cos(t)
y = t * np.sin(t)

X2 = np.concatenate((x, y))
X2 += 0.7 * np.random.randn(2, n_samples)
X2 = X2.T

Учет локальной связности с помощью графа

Большее число соседей позволяет получить более однородные кластеры, но увеличивает время вычислений. Очень большое число соседей обеспечивает более равномерное распределение размеров кластеров, однако может не учитывать локальную структуру многообразия данных.

knn_graph = kneighbors_graph(X2, 30, include_self=False)

Визуализация кластеризации со структурой и без неё

fig3 = plt.figure(figsize=(8, 12))
subfigs = fig3.subfigures(4, 1)
params = [
    (None, 30),
    (None, 3),
    (knn_graph, 30),
    (knn_graph, 3),
]

for subfig, (connectivity, n_clusters) in zip(subfigs, params):
    axs = subfig.subplots(1, 4, sharey=True)
    for index, linkage in enumerate(("average", "complete", "ward", "single")):
        model = AgglomerativeClustering(
            linkage=linkage, connectivity=connectivity, n_clusters=n_clusters
        )
        t0 = time.time()
        model.fit(X2)
        elapsed_time = time.time() - t0
        axs[index].scatter(
            X2[:, 0], X2[:, 1], c=model.labels_, cmap=plt.cm.nipy_spectral
        )
        axs[index].set_title(
            "linkage=%s\n(time %.2fs)" % (linkage, elapsed_time),
            fontdict=dict(verticalalignment="top"),
        )
        axs[index].set_aspect("equal")
        axs[index].axis("off")

        subfig.subplots_adjust(bottom=0, top=0.83, wspace=0, left=0, right=1)
        subfig.suptitle(
            "n_cluster=%i, connectivity=%r" % (n_clusters, connectivity is not None),
            size=17,
        )

plt.show()
linkage=average (time 0.04s), linkage=complete (time 0.04s), linkage=ward (time 0.04s), linkage=single (time 0.01s), linkage=average (time 0.04s), linkage=complete (time 0.04s), linkage=ward (time 0.04s), linkage=single (time 0.01s), linkage=average (time 0.12s), linkage=complete (time 0.12s), linkage=ward (time 0.15s), linkage=single (time 0.02s), linkage=average (time 0.11s), linkage=complete (time 0.11s), linkage=ward (time 0.15s), linkage=single (time 0.03s)

Общее время выполнения скрипта: (0 минут 2.207 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_ward_structured_vs_unstructured.ipynb

Download Python source code: plot_ward_structured_vs_unstructured.py

Download zipped: plot_ward_structured_vs_unstructured.zip

Связанные примеры

Демонстрация структурированной иерархической кластеризации Уорда на изображении монет

Сравнение различных методов иерархической связи на искусственных наборах данных

Различные варианты агломеративной кластеризации двумерного представления цифр

Сравнение различных алгоритмов кластеризации на искусственных наборах данных

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/cluster/plot_ward_structured_vs_unstructured.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API