Spec-Zone.ru › scikit-learn

Примечание

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

Коррекция случайности при оценке производительности кластеризации

Этот ноутбук исследует влияние случайной метки, распределенной равномерно, на поведение некоторых метрик оценки кластеризации. Для этой цели метрики вычисляются с фиксированным количеством образцов и как функция от числа кластеров, назначенных оценщиком. Пример разделен на два эксперимента:

  • первый эксперимент с фиксированными «истинными метками» (и, следовательно, фиксированным количеством классов) и случайно «предсказанными метками»;
  • второй эксперимент с изменяющимися «истинными метками», случайно «предсказанными метками». «Предсказанные метки» имеют такое же количество классов и кластеров, что и «истинные метки».
# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Определение списка метрик для оценки

Алгоритмы кластеризации — это фундаментально методы обучения без учителя. Однако, поскольку мы назначаем метки классов для синтетических кластеров в этом примере, можно использовать метрики оценки, которые используют эту информацию «с учителем», чтобы измерить качество полученных кластеров. Примеры таких метрик следующие:

  • мера V, гармоническое среднее полноты и однородности;
  • индекс Рэнда, который измеряет, как часто пары точек данных группируются последовательно в соответствии с результатом алгоритма кластеризации и назначением класса истинного значения;
  • скорректированный индекс Рэнда (ARI), индекс Рэнда, скорректированный на случайность, такой, что случайное назначение кластера имеет ARI 0,0 в ожидании;
  • взаимная информация (MI) — мера из теории информации, которая количественно определяет, насколько зависимы две метки. Обратите внимание, что максимальное значение MI для идеальных меток зависит от количества кластеров и образцов;
  • нормализованная взаимная информация (NMI), взаимная информация, определенная между 0 (нет взаимной информации) в пределе большого количества точек данных и 1 (идеально совпадающие назначения меток, до перестановки меток). Она не скорректирована на случайность: тогда количество кластеризованных точек данных недостаточно велико, ожидаемые значения MI или NMI для случайных меток могут быть значительно отличны от нуля;
  • скорректированная взаимная информация (AMI), скорректированная на случайность взаимная информация. Аналогично ARI, случайное назначение кластера имеет AMI 0,0 в ожидании.

Дополнительную информацию см. в модуле Оценка производительности кластеризации.

from sklearn import metrics

score_funcs = [
    ("V-measure", metrics.v_measure_score),
    ("Rand index", metrics.rand_score),
    ("ARI", metrics.adjusted_rand_score),
    ("MI", metrics.mutual_info_score),
    ("NMI", metrics.normalized_mutual_info_score),
    ("AMI", metrics.adjusted_mutual_info_score),
]

Первый эксперимент: фиксированные истинные метки и увеличивающееся количество кластеров

Сначала мы определим функцию, которая создает равномерно распределенные случайные метки.

import numpy as np

rng = np.random.RandomState(0)


def random_labels(n_samples, n_classes):
    return rng.randint(low=0, high=n_classes, size=n_samples)

Другая функция будет использовать функцию random_labels для создания фиксированного набора истинных меток (labels_a) распределенных в n_classes и затем оценить несколько наборов случайно «предсказанных» меток (labels_b) для оценки изменчивости заданной метрики при заданном n_clusters.

def fixed_classes_uniform_labelings_scores(
    score_func, n_samples, n_clusters_range, n_classes, n_runs=5
):
    scores = np.zeros((len(n_clusters_range), n_runs))
    labels_a = random_labels(n_samples=n_samples, n_classes=n_classes)

    for i, n_clusters in enumerate(n_clusters_range):
        for j in range(n_runs):
            labels_b = random_labels(n_samples=n_samples, n_classes=n_clusters)
            scores[i, j] = score_func(labels_a, labels_b)
    return scores

В этом первом примере мы установили количество классов (истинное количество кластеров) в n_classes=10. Количество кластеров изменяется в значениях, предоставляемых n_clusters_range.

import matplotlib.pyplot as plt
import seaborn as sns

n_samples = 1000
n_classes = 10
n_clusters_range = np.linspace(2, 100, 10).astype(int)
plots = []
names = []

sns.color_palette("colorblind")
plt.figure(1)

for marker, (score_name, score_func) in zip("d^vx.,", score_funcs):
    scores = fixed_classes_uniform_labelings_scores(
        score_func, n_samples, n_clusters_range, n_classes=n_classes
    )
    plots.append(
        plt.errorbar(
            n_clusters_range,
            scores.mean(axis=1),
            scores.std(axis=1),
            alpha=0.8,
            linewidth=1,
            marker=marker,
        )[0]
    )
    names.append(score_name)

plt.title(
    "Clustering measures for random uniform labeling\n"
    f"against reference assignment with {n_classes} classes"
)
plt.xlabel(f"Number of clusters (Number of samples is fixed to {n_samples})")
plt.ylabel("Score value")
plt.ylim(bottom=-0.05, top=1.05)
plt.legend(plots, names, bbox_to_anchor=(0.5, 0.5))
plt.show()
Clustering measures for random uniform labeling against reference assignment with 10 classes

Индекс Рэнда насыщается при n_clusters > n_classes. Другие нескорректированные меры, такие как мера V, демонстрируют линейную зависимость между количеством кластеров и количеством образцов.

Меры, скорректированные на случайность, такие как ARI и AMI, демонстрируют некоторые случайные вариации, сосредоточенные вокруг средней оценки 0,0, независимо от количества образцов и кластеров.

Второй эксперимент: изменение количества классов и кластеров

В этом разделе мы определим аналогичную функцию, которая использует несколько метрик для оценки 2 равномерно распределенных случайных меток. В этом случае количество классов и назначенное количество кластеров соответствуют каждому возможному значению в n_clusters_range.

def uniform_labelings_scores(score_func, n_samples, n_clusters_range, n_runs=5):
    scores = np.zeros((len(n_clusters_range), n_runs))

    for i, n_clusters in enumerate(n_clusters_range):
        for j in range(n_runs):
            labels_a = random_labels(n_samples=n_samples, n_classes=n_clusters)
            labels_b = random_labels(n_samples=n_samples, n_classes=n_clusters)
            scores[i, j] = score_func(labels_a, labels_b)
    return scores

В этом случае мы используем n_samples=100 для демонстрации эффекта наличия количества кластеров, аналогичного или равного количеству образцов.

n_samples = 100
n_clusters_range = np.linspace(2, n_samples, 10).astype(int)

plt.figure(2)

plots = []
names = []

for marker, (score_name, score_func) in zip("d^vx.,", score_funcs):
    scores = uniform_labelings_scores(score_func, n_samples, n_clusters_range)
    plots.append(
        plt.errorbar(
            n_clusters_range,
            np.median(scores, axis=1),
            scores.std(axis=1),
            alpha=0.8,
            linewidth=2,
            marker=marker,
        )[0]
    )
    names.append(score_name)

plt.title(
    "Clustering measures for 2 random uniform labelings\nwith equal number of clusters"
)
plt.xlabel(f"Number of clusters (Number of samples is fixed to {n_samples})")
plt.ylabel("Score value")
plt.legend(plots, names)
plt.ylim(bottom=-0.05, top=1.05)
plt.show()
Clustering measures for 2 random uniform labelings with equal number of clusters

Мы наблюдаем аналогичные результаты, как и в первом эксперименте: метрики, скорректированные на случайность, остаются постоянно около нуля, в то время как другие метрики имеют тенденцию увеличиваться с более тонкими метками. Средняя мера V случайных меток значительно увеличивается по мере того, как количество кластеров приближается к общему количеству образцов, используемых для вычисления меры. Кроме того, необработанная взаимная информация не ограничена сверху, а ее масштаб зависит от размерности задачи кластеризации и мощности истинных классов. Вот почему кривая выходит за пределы графика.

Таким образом, только скорректированные меры могут быть безопасно использованы как индекс консенсуса для оценки средней стабильности алгоритмов кластеризации для данного значения k на различных перекрывающихся подвыборках набора данных.

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

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

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_adjusted_for_chance_measures.ipynb

Download Python source code: plot_adjusted_for_chance_measures.py

Download zipped: plot_adjusted_for_chance_measures.zip

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

Демонстрация алгоритма кластеризации DBSCAN

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

Демонстрация алгоритма кластеризации с помощью распространения близости

Агломеративная кластеризация с различными метриками

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

Spec-Zone.ru

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