Введение
В этом практическом занятии мы будем изучать алгоритм кластеризации K-Means с использованием библиотеки scikit-learn в Python. Мы будем использовать набор данных с рукописными цифрами, который содержит 64 признака, представляющих 8x8 изображение цифры, и попытаемся сгруппировать изображения в соответствии с цифрой, которую они представляют. Мы сравним различные методы инициализации для K-Means и оценим производительность кластеризации с использованием различных метрик.
Советы по работе с ВМ
После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.
Иногда вам может потребоваться подождать несколько секунд, пока Jupyter Notebook не загрузится. Валидация операций не может быть автоматизирована из-за ограничений Jupyter Notebook.
Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.
Загрузка набора данных
Начнем с загрузки набора данных с рукописными цифрами с использованием функции load_digits() из scikit-learn. Эта функция возвращает признаки и метки для набора данных.
import numpy as np
from sklearn.datasets import load_digits
data, labels = load_digits(return_X_y=True)
(n_samples, n_features), n_digits = data.shape, np.unique(labels).size
Определение бенчмарка оценки
Мы определим бенчмарк для сравнения различных методов инициализации для K-Means. Наш бенчмарк будет:
- создавать конвейер, который масштабирует данные с использованием
StandardScaler - обучать и замерять время настройки конвейера
- измерять производительность кластеризации, полученной с использованием различных метрик
from time import time
from sklearn import metrics
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def bench_k_means(kmeans, name, data, labels):
"""Бенчмарк для оценки методов инициализации KMeans.
Параметры
----------
kmeans : экземпляр KMeans
Экземпляр `KMeans` с уже установленной инициализацией.
name : str
Название стратегии. Будет использоваться для отображения результатов в таблице.
data : ndarray формы (n_samples, n_features)
Данные для кластеризации.
labels : ndarray формы (n_samples,)
Метки, используемые для вычисления метрик кластеризации, требующих некоторого контроля.
"""
t0 = time()
estimator = make_pipeline(StandardScaler(), kmeans).fit(data)
fit_time = time() - t0
results = [name, fit_time, estimator[-1].inertia_]
## Определить метрики, которые требуют только истинных меток и меток оценщика
clustering_metrics = [
metrics.homogeneity_score,
metrics.completeness_score,
metrics.v_measure_score,
metrics.adjusted_rand_score,
metrics.adjusted_mutual_info_score,
]
results += [m(labels, estimator[-1].labels_) for m in clustering_metrics]
## Коэффициент силуэта требует полного набора данных
results += [
metrics.silhouette_score(
data,
estimator[-1].labels_,
metric="euclidean",
sample_size=300,
)
]
## Показать результаты
formatter_result = (
"{:9s}\t{:.3f}s\t{:.0f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}"
)
print(formatter_result.format(*results))
Запуск бенчмарка
Мы сравним три подхода к инициализации K-Means:
- инициализация с использованием
k-means++. Этот метод является стохастическим, и мы запустим инициализацию 4 раза; - случайная инициализация. Этот метод также является стохастическим, и мы запустим инициализацию 4 раза;
- инициализация на основе проекции PCA. Мы будем использовать компоненты PCA для инициализации K-Means. Этот метод детерминирован, и одна инициализация достаточно.
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
print(82 * "_")
print("init\t\ttime\tinertia\thomo\tcompl\tv-meas\tARI\tAMI\tsilhouette")
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="k-means++", data=data, labels=labels)
kmeans = KMeans(init="random", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="random", data=data, labels=labels)
pca = PCA(n_components=n_digits).fit(data)
kmeans = KMeans(init=pca.components_, n_clusters=n_digits, n_init=1)
bench_k_means(kmeans=kmeans, name="PCA-based", data=data, labels=labels)
print(82 * "_")
Визуализация результатов на данных, сокращенных с использованием PCA
Мы будем использовать PCA для сокращения набора данных до 2 размерностей и построения данных и кластеров в этом новом пространстве.
import matplotlib.pyplot as plt
reduced_data = PCA(n_components=2).fit_transform(data)
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4)
kmeans.fit(reduced_data)
## Шаг сетки. Уменьшите, чтобы повысить качество VQ.
h = 0.02 ## точка в сетке [x_min, x_max]x[y_min, y_max].
## Построить границу решения. Для этого мы присвоим цвет каждой
x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1
y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
## Получить метки для каждой точки в сетке. Используйте последнюю обученную модель.
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
## Поместите результат в цветовую диаграмму
Z = Z.reshape(xx.shape)
plt.figure(1)
plt.clf()
plt.imshow(
Z,
interpolation="nearest",
extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.Paired,
aspect="auto",
origin="lower",
)
plt.plot(reduced_data[:, 0], reduced_data[:, 1], "k.", markersize=2)
## Построить центроиды в виде белой X
centroids = kmeans.cluster_centers_
plt.scatter(
centroids[:, 0],
centroids[:, 1],
marker="x",
s=169,
linewidths=3,
color="w",
zorder=10,
)
plt.title(
"K-means clustering on the digits dataset (PCA-reduced data)\n"
"Centroids are marked with white cross"
)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
Резюме
В этом практическом занятии мы изучили алгоритм кластеризации K-Means и применили его к набору данных с рукописными цифрами. Мы сравнили различные методы инициализации и оценили производительность кластеризации с использованием различных метрик. Мы также визуализировали результаты в двумерном пространстве с использованием PCA.