Spec-Zone.ru › scikit-learn

Примечание

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

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

Оцените способность стратегий инициализации k-means сделать алгоритм сходимости устойчивым, измеряя относительное стандартное отклонение инерции кластеризации (т.е. сумму квадратов расстояний до ближайшего центра кластера).

Первый график показывает наилучшую инерцию, достигнутую для каждой комбинации модели (KMeans или MiniBatchKMeans) и метода init (init="random" или init="k-means++") для возрастающих значений параметра n_init, который контролирует количество инициализаций.

Второй график демонстрирует один запуск оценщика MiniBatchKMeans с использованием init="random" и n_init=1. Этот запуск приводит к плохой сходимости (локальный оптимум), при которой оценённые центры застревают между кластерами истинного значения.

Набор данных, используемый для оценки, представляет собой 2D сетку изотропных гауссовых кластеров с широким пространственным разнесением.

  • Mean inertia for various k-means init across 5 runs
  • Example cluster allocation with a single random init with MiniBatchKMeans
Evaluation of KMeans with k-means++ init
Evaluation of KMeans with random init
Evaluation of MiniBatchKMeans with k-means++ init
Evaluation of MiniBatchKMeans with random init
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

import matplotlib.cm as cm
import matplotlib.pyplot as plt
import numpy as np

from sklearn.cluster import KMeans, MiniBatchKMeans
from sklearn.utils import check_random_state, shuffle

random_state = np.random.RandomState(0)

# Number of run (with randomly generated dataset) for each strategy so as
# to be able to compute an estimate of the standard deviation
n_runs = 5

# k-means models can do several random inits so as to be able to trade
# CPU time for convergence robustness
n_init_range = np.array([1, 5, 10, 15, 20])

# Datasets generation parameters
n_samples_per_center = 100
grid_size = 3
scale = 0.1
n_clusters = grid_size**2


def make_data(random_state, n_samples_per_center, grid_size, scale):
    random_state = check_random_state(random_state)
    centers = np.array([[i, j] for i in range(grid_size) for j in range(grid_size)])
    n_clusters_true, n_features = centers.shape

    noise = random_state.normal(
        scale=scale, size=(n_samples_per_center, centers.shape[1])
    )

    X = np.concatenate([c + noise for c in centers])
    y = np.concatenate([[i] * n_samples_per_center for i in range(n_clusters_true)])
    return shuffle(X, y, random_state=random_state)


# Part 1: Quantitative evaluation of various init methods


plt.figure()
plots = []
legends = []

cases = [
    (KMeans, "k-means++", {}, "^-"),
    (KMeans, "random", {}, "o-"),
    (MiniBatchKMeans, "k-means++", {"max_no_improvement": 3}, "x-"),
    (MiniBatchKMeans, "random", {"max_no_improvement": 3, "init_size": 500}, "d-"),
]

for factory, init, params, format in cases:
    print("Evaluation of %s with %s init" % (factory.__name__, init))
    inertia = np.empty((len(n_init_range), n_runs))

    for run_id in range(n_runs):
        X, y = make_data(run_id, n_samples_per_center, grid_size, scale)
        for i, n_init in enumerate(n_init_range):
            km = factory(
                n_clusters=n_clusters,
                init=init,
                random_state=run_id,
                n_init=n_init,
                **params,
            ).fit(X)
            inertia[i, run_id] = km.inertia_
    p = plt.errorbar(
        n_init_range, inertia.mean(axis=1), inertia.std(axis=1), fmt=format
    )
    plots.append(p[0])
    legends.append("%s with %s init" % (factory.__name__, init))

plt.xlabel("n_init")
plt.ylabel("inertia")
plt.legend(plots, legends)
plt.title("Mean inertia for various k-means init across %d runs" % n_runs)

# Part 2: Qualitative visual inspection of the convergence

X, y = make_data(random_state, n_samples_per_center, grid_size, scale)
km = MiniBatchKMeans(
    n_clusters=n_clusters, init="random", n_init=1, random_state=random_state
).fit(X)

plt.figure()
for k in range(n_clusters):
    my_members = km.labels_ == k
    color = cm.nipy_spectral(float(k) / n_clusters, 1)
    plt.plot(X[my_members, 0], X[my_members, 1], ".", c=color)
    cluster_center = km.cluster_centers_[k]
    plt.plot(
        cluster_center[0],
        cluster_center[1],
        "o",
        markerfacecolor=color,
        markeredgecolor="k",
        markersize=6,
    )
    plt.title(
        "Example cluster allocation with a single random init\nwith MiniBatchKMeans"
    )

plt.show()

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_kmeans_stability_low_dim_dense.ipynb

Download Python source code: plot_kmeans_stability_low_dim_dense.py

Download zipped: plot_kmeans_stability_low_dim_dense.zip

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

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

Сравнение производительности алгоритмов Bisecting K-Means и Regular 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_stability_low_dim_dense.html

Spec-Zone.ru

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