Обучение без учителя — кластеризация

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

В машинном обучении,кластеризация— это именно то, чем мы занимаемся. Это разновидность методаобучения без учителя, цель которого — обнаружить внутреннюю структуру и группировку в данных, не имеющих заранее размеченных ответов (т. е. без "меток").


Что такое обучение без учителя и кластеризация?

Прежде чем начать, давайте быстро разграничим две основные парадигмы машинного обучения:

  • Обучение с учителем: Это как обучение с учителем. Мы предоставляем алгоритму большое количество вопросов (признаковые данные) и соответствующие правильные ответы (метки), позволяя ему выучить отображение из вопросов в ответы. Например, мы показываем алгоритму множество изображений кошек и собак (признаки) и сообщаем ему, кошка на каждом изображении или собака (метки). После обучения он может распознавать новые изображения.
  • Обучение без учителя: Это как позволить машине исследовать и открывать самостоятельно. Мы предоставляем только вопросы (признаковые данные),не предоставляя ответы (метки). Задача алгоритма — самостоятельно находить закономерности, структуры или взаимосвязи в данных. Кластеризация — одна из его основных техник.

Основная идея кластеризации: Разделить выборки в наборе данных на нескольконепересекающихсяподмножеств (называемых кластерами или классами), так чтобы выборки внутри одного кластера были взаимнопохожи, а выборки в разных кластерах были взаимнонепохожи。

Сходство здесь обычно измеряется математическимрасстоянием(например, евклидово расстояние).

Чем меньше расстояние, тем выше сходство.


Классический алгоритм кластеризации: K-Means

K-MeansЭто один из самых известных и часто используемых алгоритмов кластеризации, с интуитивно понятной идеей и относительно простой реализацией.

Принцип и шаги алгоритма

Процесс K-Means можно представить как выбор представителей и перераспределение районов:

  1. Определите число кластеров K: Сначала нужно решить, на сколько классов вы хотите разделить данные. Это значение K должно быть задано заранее; это ключевой параметр K-Means.
  2. Инициализируйте представителей (центроидов): Случайно выберите K точек в пространстве данных как начальные "центральные точки" каждого кластера, которые мы называемцентроидами。
  3. Распределите жителей (образцы): Вычислите расстояние от каждой точки-образца в наборе данных до K центроидов. Следуя принципу "близкие принадлежат к одному классу", назначьте каждый образец кластеру того центроида, которыйближайшийк нему. Таким образом, все образцы распределяются по K кластерам.
  4. Заново выберите представителей (обновите центроиды): Теперь в каждом кластере есть набор образцов. Пересчитайте центроид каждого кластера; новый центроид — этосреднее(средняя точка) всех точек-образцов в этом кластере.
  5. Повторение и сходимость: Повторяйте шаг 3 (назначение) и шаг 4 (обновление), пока положения центроидов не перестанут значительно меняться (то есть алгоритм сходится). На этом этапе кластер, к которому принадлежит каждый образец, тоже больше не меняется.

Пример кода и практика

Давайте использоватьscikit-learnбиблиотеку Python и простой набор данных для демонстрации K-Means.

Пример

# Импорт необходимых библиотек
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans

# -------------------------- Начало настройки китайского шрифта --------------------------
plt.rcParams['font.sans-serif'] = [
    # Предпочтительно для Windows
    'SimHei', 'Microsoft YaHei',
    # Предпочтительно для macOS
    'PingFang SC', 'Heiti TC',
    # Предпочтительно Linux
    'WenQuanYi Micro Hei', 'DejaVu Sans'
]
# Исправление проблемы, когда знаки минуса отображаются в виде квадратов
plt.rcParams['axes.unicode_minus'] = False
# -------------------------- Конец настройки китайского шрифта --------------------------

# 1. Создание искусственного набора данных
# Мы генерируем 300 точек выборки, которые естественно кластеризуются вокруг 4 центров (для удобства наблюдения)
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)
# X — это данные признаков, y_true — истинные метки классов (используются только для итогового сравнения; алгоритм кластеризации не будет их использовать)

# 2. Визуализация исходных данных
plt.scatter(X[:, 0], X[:, 1], s=50) # s — размер точек
plt.title("Исходные неразмеченные данные")
plt.show()

# 3. Примените кластеризацию K-Means
# Укажите кластеризацию на 4 класса
kmeans = KMeans(n_clusters=4, random_state=0, n_init='auto')
# Обучите модель и предскажите метку кластера для каждого образца
y_kmeans = kmeans.fit_predict(X)

# 4. Получите координаты центроидов
centroids = kmeans.cluster_centers_

# 5. Визуализируйте результаты кластеризации
plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis')
# Отметьте точки образцов разных кластеров разными цветами

plt.scatter(centroids[:, 0], centroids[:, 1], c='red', s=200, alpha=0.8, marker='X')
# Отметьте позиции центроидов красными крестиками, alpha — прозрачность
plt.title("Результат кластеризации K-Means (K=4)")
plt.show()

# Вывести предсказанные метки кластеров для первых 10 образцов
print("Метки кластеров первых 10 образцов:", y_kmeans[:10])
# Вывести координаты центроидов
print("Координаты центроидов четырёх кластеров:"\n", centroids)

Пояснение кода:

  • make_blobs: Генерирует имитационный набор данных для кластеризации,centers=4указывает, что данные генерируются вокруг 4 центральных точек.
  • KMeans(n_clusters=4): Создаёт экземпляр модели K-Means, задавая число кластеров K равным 4.n_init='auto'— это количество запусков алгоритма с выбором лучшего результата.
  • fit_predict(X): Основной метод, применяемый к даннымXобучает модель и возвращает индекс кластера (0, 1, 2, 3) для каждого образца.
  • cluster_centers_: Атрибут, который хранит координаты K центроидов, полученных после обучения.

Запустив этот код, вы увидите два графика. Первый — это набор беспорядочных точек, а второй чётко разделён на четыре цветные группы, с краснымиXмаркерами в центрах. В этом и заключается магия K-Means!

前10个样本的簇标签: [1 2 0 2 1 1 3 0 2 2]
四个簇的质心坐标:
 [[ 0.94973532  4.41906906]
 [ 1.98258281  0.86771314]
 [-1.37324398  7.75368871]
 [-1.58438467  2.83081263]]

Исходные неразмеченные данные:

Результат кластеризации K-Means:


Как выбрать наилучшее значение K?

В приведённом выше примере, поскольку мы знаем, что данные сгенерированы вокруг 4 центров, мы легко задалиK=4. Но в реальном мире мы часто не знаем, на сколько классов следует разделить данные. Как выбрать K?

Часто используемый метод — это«метод локтя». Идея такова: по мере увеличения числа кластеров K среднее расстояние от точек выборки до центроида их кластера (называемоеискажениемилиinertia) будет уменьшаться. Когда K меньше истинного числа кластеров, увеличение K значительно уменьшит это расстояние; когда K достигает истинного числа кластеров, дальнейшее увеличение K приводит к резкому падению величины уменьшения расстояния. Эта точка перегиба похожа на локтевой сустав, и соответствующее значение K является лучшим выбором.

Пример

# Пример метода локтя: вычислить инерцию для разных значений K
inertias = []
K_range = range(1, 11) # Проверить K от 1 до 10

for k in K_range:
    kmeans = KMeans(n_clusters=k, random_state=0, n_init='auto')
    kmeans.fit(X)
    inertias.append(kmeans.inertia_) # Атрибут inertia_ — это SSE

# Построение кривой локтя
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('Число кластеров K')
plt.ylabel('Инерция (SSE)')
plt.title('Метод локтя для поиска лучшего значения K')
plt.axvline(x=4, color='r', linestyle='--', alpha=0.5) # Отметить известное K=4
plt.show()

Наблюдая за построенной кривой, вы увидите, что около K=4 скорость её спуска заметно замедляется, образуя «локоть», что позволяет предположить, что K=4 — разумный выбор.


Сценарии применения кластеризации

Кластеризация — мощный инструмент разведочного анализа данных с чрезвычайно широким применением:

  1. Сегментация клиентов: В электронной коммерции или маркетинге кластеризация на основе покупательского поведения и демографических данных (демографических характеристик) клиентов позволяет разделить их на группы, такие как "высокоценные клиенты" и "чувствительные к цене клиенты", для целевого маркетинга.
  2. Сегментация изображений: Кластеризация пикселей изображения на основе цвета и текстуры, что можно использовать для упрощения изображений и определения переднего и заднего плана.
  3. Обнаружение аномалий: Обычные точки данных обычно образуют плотные кластеры, тогда как выбросы находятся далеко от центра любого кластера. Кластеризация может использоваться для обнаружения этих выбросов.
  4. Классификация документов: Кластеризация новостных статей или научных работ для автоматического обнаружения горячих тем или исследовательских областей.
  5. Анализ социальных сетей: В социальных сетях с помощью кластеризации связей и взаимодействий пользователей можно обнаружить сообщества или круги.

Практические упражнения и итоги

Упражнение 1: Попробуйте разные значения KИзмените следующее в приведённом выше примере кода K-Means:n_clustersПараметры: установите их равными 2, 3, 5, 8 соответственно. Наблюдайте за графиками результатов кластеризации и почувствуйте влияние выбора значения K на результаты.

Упражнение 2: Используйте реальный набор данныхПопробуйте использоватьscikit-learnвстроенныйiris(Iris) набор данных для кластеризации. Хотя этот набор данных обычно используется для классификации, вы можете игнорировать его метки и использовать только признаки (длину и ширину чашелистиков и лепестков) для кластеризации K-Means, затем сравните результаты кластеризации с истинными метками, чтобы увидеть, насколько хорошо это работает.

Пример

from sklearn import datasets
iris = datasets.load_iris()
X_iris = iris.data # Использовать только данные признаков
Другие расширения