Кластеризация K-Means для рукописных цифр

Machine LearningMachine LearningBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии мы будем изучать алгоритм кластеризации K-Means с использованием библиотеки scikit-learn в Python. Мы будем использовать набор данных с рукописными цифрами, который содержит 64 признака, представляющих 8x8 изображение цифры, и попытаемся сгруппировать изображения в соответствии с цифрой, которую они представляют. Мы сравним различные методы инициализации для K-Means и оценим производительность кластеризации с использованием различных метрик.

Советы по работе с ВМ

После запуска ВМ нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

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

Если вы сталкиваетесь с проблемами во время обучения, не стесняйтесь обращаться к Labby. Оставьте отзыв после занятия, и мы оперативно решим проблему для вас.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/CoreModelsandAlgorithmsGroup(["Core Models and Algorithms"]) sklearn(("Sklearn")) -.-> sklearn/DataPreprocessingandFeatureEngineeringGroup(["Data Preprocessing and Feature Engineering"]) sklearn(("Sklearn")) -.-> sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup(["Advanced Data Analysis and Dimensionality Reduction"]) sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/CoreModelsandAlgorithmsGroup -.-> sklearn/cluster("Clustering") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/preprocessing("Preprocessing and Normalization") sklearn/DataPreprocessingandFeatureEngineeringGroup -.-> sklearn/pipeline("Pipeline") sklearn/AdvancedDataAnalysisandDimensionalityReductionGroup -.-> sklearn/decomposition("Matrix Decomposition") sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/cluster -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} sklearn/preprocessing -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} sklearn/pipeline -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} sklearn/decomposition -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} sklearn/datasets -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} ml/sklearn -.-> lab-49180{{"Кластеризация K-Means для рукописных цифр"}} end

Загрузка набора данных

Начнем с загрузки набора данных с рукописными цифрами с использованием функции 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.