Spec-Zone.ru › scikit-learn

Примечание

Перейти к концу для скачивания полного примера кода. Или запустить этот пример в вашем браузере через JupyterLite или Binder

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

В этом примере мы сравниваем различные стратегии инициализации K-Means по времени выполнения и качеству результатов.

Поскольку истинные значения здесь известны, мы также применяем различные метрики качества кластеризации для оценки соответствия меток кластеров истинным значениям.

Оцениваемые метрики качества кластеризации (см. Оценка производительности кластеризации для определений и обсуждений метрик):

Сокращение

Полное название

homo

Метрика однородности

compl

Метрика полноты

v-meas

Метрика V-мера

ARI

Скорректированный индекс Рэнда

AMI

Скорректированная взаимная информация

silhouette

Коэффициент силуэта

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

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

Мы начнём с загрузки набора данных digits. Этот набор данных содержит рукописные цифры от 0 до 9. В контексте кластеризации хотелось бы сгруппировать изображения так, чтобы рукописные цифры на изображении были одинаковыми.

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

print(f"# digits: {n_digits}; # samples: {n_samples}; # features {n_features}")
# digits: 10; # samples: 1797; # features 64

Определение эталона оценки

Мы сначала определим эталон оценки. Во время этого эталона мы намерены сравнить различные методы инициализации KMeans. Наш эталон будет:

  • создавать конвейер, который будет масштабировать данные с помощью 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):
    """Benchmark to evaluate the KMeans initialization methods.

    Parameters
    ----------
    kmeans : KMeans instance
        A :class:`~sklearn.cluster.KMeans` instance with the initialization
        already set.
    name : str
        Name given to the strategy. It will be used to show the results in a
        table.
    data : ndarray of shape (n_samples, n_features)
        The data to cluster.
    labels : ndarray of shape (n_samples,)
        The labels used to compute the clustering metrics which requires some
        supervision.
    """
    t0 = time()
    estimator = make_pipeline(StandardScaler(), kmeans).fit(data)
    fit_time = time() - t0
    results = [name, fit_time, estimator[-1].inertia_]

    # Define the metrics which require only the true labels and estimator
    # labels
    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]

    # The silhouette score requires the full dataset
    results += [
        metrics.silhouette_score(
            data,
            estimator[-1].labels_,
            metric="euclidean",
            sample_size=300,
        )
    ]

    # Show the results
    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++. Этот метод является стохастическим, и мы запустим инициализацию 4 раза;
  • случайная инициализация. Этот метод также является стохастическим, и мы запустим инициализацию 4 раза;
  • инициализация на основе проекции PCA. Действительно, мы будем использовать компоненты проекции PCA для инициализации KMeans. Этот метод детерминированный, и одной инициализации достаточно.
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 * "_")
__________________________________________________________________________________
init            time    inertia homo    compl   v-meas  ARI     AMI     silhouette
k-means++       0.035s  69545   0.598   0.645   0.621   0.469   0.617   0.152
random          0.037s  69735   0.681   0.723   0.701   0.574   0.698   0.170
PCA-based       0.012s  69513   0.600   0.647   0.622   0.468   0.618   0.162
__________________________________________________________________________________

Визуализация результатов на данных, уменьшенных PCA

PCA позволяет спроецировать данные из исходного 64-мерного пространства в пространство меньшей размерности. Впоследствии мы можем использовать 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)

# Step size of the mesh. Decrease to increase the quality of the VQ.
h = 0.02  # point in the mesh [x_min, x_max]x[y_min, y_max].

# Plot the decision boundary. For that, we will assign a color to each
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))

# Obtain labels for each point in mesh. Use last trained model.
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])

# Put the result into a color plot
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)
# Plot the centroids as a white 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 clustering on the digits dataset (PCA-reduced data) Centroids are marked with white cross

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_kmeans_digits.ipynb

Download Python source code: plot_kmeans_digits.py

Download zipped: plot_kmeans_digits.zip

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

Кластеризация текстовых документов с помощью k-means

Сравнение алгоритмов кластеризации K-Means и MiniBatchKMeans

Сравнение производительности Bisecting K-Means и обычного K-Means

Эмпирическая оценка влияния стратегий инициализации k-means

© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/cluster/plot_kmeans_digits.html

Spec-Zone.ru

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