Введение
В этом лабораторном занятии мы будем использовать библиотеку scikit - learn на Python для выполнения иерархической кластеризации на нескольких виртуальных наборах данных. Иерархическая кластеризация - это метод кластеризации, при котором вы строите иерархию кластеров, либо сверху вниз, либо снизу вверх. Цель иерархической кластеризации - найти кластеры точек, которые похожи друг на друга и отличаются от точек в других кластерах.
Советы по работе с ВМ
После запуска виртуальной машины кликните в левом верхнем углу, чтобы переключиться на вкладку Ноутбук, чтобы получить доступ к Jupyter Notebook для практики.
Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook не загрузится полностью. Валидация операций не может быть автоматизирована из - за ограничений в Jupyter Notebook.
Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.
Импорт библиотек и загрузка данных
Начнем с импорта необходимых библиотек и загрузки виртуальных наборов данных, которые мы будем использовать для наших примеров иерархической кластеризации.
import time
import warnings
import numpy as np
import matplotlib.pyplot as plt
from sklearn import cluster, datasets
from sklearn.preprocessing import StandardScaler
from itertools import cycle, islice
np.random.seed(0)
## %%
## Генерируем наборы данных. Мы выбираем размер достаточно большим, чтобы увидеть масштабируемость
## алгоритмов, но не слишком большим, чтобы избежать слишком длительных времени выполнения
n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=0.5, noise=0.05)
noisy_moons = datasets.make_moons(n_samples=n_samples, noise=0.05)
blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)
no_structure = np.random.rand(n_samples, 2), None
## Анизотропно распределенные данные
random_state = 170
X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)
transformation = [[0.6, -0.6], [-0.4, 0.8]]
X_aniso = np.dot(X, transformation)
aniso = (X_aniso, y)
## Blobs с различными дисперсиями
varied = datasets.make_blobs(
n_samples=n_samples, cluster_std=[1.0, 2.5, 0.5], random_state=random_state
)
Выполнить иерархическую кластеризацию
Теперь мы выполним иерархическую кластеризацию на виртуальных наборах данных, которые мы загрузили на шаге 1. Мы будем использовать разные методы связывания, такие как single, average, complete и ward, чтобы построить наши кластеры.
## Set up cluster parameters
plt.figure(figsize=(9 * 1.3 + 2, 14.5))
plt.subplots_adjust(
left=0.02, right=0.98, bottom=0.001, top=0.96, wspace=0.05, hspace=0.01
)
plot_num = 1
default_base = {"n_neighbors": 10, "n_clusters": 3}
datasets = [
(noisy_circles, {"n_clusters": 2}),
(noisy_moons, {"n_clusters": 2}),
(varied, {"n_neighbors": 2}),
(aniso, {"n_neighbors": 2}),
(blobs, {}),
(no_structure, {}),
]
for i_dataset, (dataset, algo_params) in enumerate(datasets):
## update parameters with dataset-specific values
params = default_base.copy()
params.update(algo_params)
X, y = dataset
## normalize dataset for easier parameter selection
X = StandardScaler().fit_transform(X)
## ============
## Create cluster objects
## ============
ward = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="ward"
)
complete = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="complete"
)
average = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="average"
)
single = cluster.AgglomerativeClustering(
n_clusters=params["n_clusters"], linkage="single"
)
clustering_algorithms = (
("Single Linkage", single),
("Average Linkage", average),
("Complete Linkage", complete),
("Ward Linkage", ward),
)
for name, algorithm in clustering_algorithms:
t0 = time.time()
## catch warnings related to kneighbors_graph
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
message="the number of connected components of the "
+ "connectivity matrix is [0-9]{1,2}"
+ " > 1. Completing it to avoid stopping the tree early.",
category=UserWarning,
)
algorithm.fit(X)
t1 = time.time()
if hasattr(algorithm, "labels_"):
y_pred = algorithm.labels_.astype(int)
else:
y_pred = algorithm.predict(X)
plt.subplot(len(datasets), len(clustering_algorithms), plot_num)
if i_dataset == 0:
plt.title(name, size=18)
colors = np.array(
list(
islice(
cycle(
[
"#377eb8",
"#ff7f00",
"#4daf4a",
"#f781bf",
"#a65628",
"#984ea3",
"#999999",
"#e41a1c",
"#dede00",
]
),
int(max(y_pred) + 1),
)
)
)
plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])
plt.xlim(-2.5, 2.5)
plt.ylim(-2.5, 2.5)
plt.xticks(())
plt.yticks(())
plt.text(
0.99,
0.01,
("%.2fs" % (t1 - t0)).lstrip("0"),
transform=plt.gca().transAxes,
size=15,
horizontalalignment="right",
)
plot_num += 1
plt.show()
Анализировать результаты
Теперь мы будем анализировать результаты нашей иерархической кластеризации. Основываясь на виртуальных наборах данных, которые мы использовали, мы можем сделать следующие наблюдения:
- Single linkage быстрый и может хорошо работать на неку球星 данных, но плохо справляется в присутствии шума.
- Average и complete linkage хорошо работают на чисто разделенных ку球星 кластерах, но дают неоднозначные результаты в других случаях.
- Ward - это наиболее эффективный метод для данных с шумом.
Важно отметить, что, хотя эти наблюдения дают нам некоторое представление о алгоритмах, это представление может не быть применимым для очень высокомерных данных.
Резюме
В этом лабораторном занятии мы научились выполнять иерархическую кластеризацию с использованием библиотеки scikit - learn на Python. Мы использовали разные методы связывания, такие как single, average, complete и ward, чтобы построить наши кластеры, и проанализировали результаты на основе нескольких виртуальных наборов данных. Иерархическая кластеризация - это мощный метод, который может быть использован для идентификации кластеров похожих данных точек и может быть полезен в различных областях, таких как биология, маркетинг и финансы.