УМК СПО

Учебно-методические комплексы

для преподавателей СПО








Кластеризация — выбор оптимального числа кластеров

ОП.10 Машинное обучение
Лабораторная работа №3
Тема: Кластеризация — выбор оптимального числа кластеров

Цель работы: Экспериментально исследовать метод K-means, научиться выбирать оптимальное число кластеров с помощью метода локтя и силуэтного анализа.
Время выполнения: 2 академических часа
Тип работы: Лабораторная (эксперимент с кластеризацией)

ЗАДАНИЕ ДЛЯ СТУДЕНТА

Этап 1. Создание данных и базовая кластеризация (15 минут)

Создадим искусственный датасет для эксперимента:



import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs, make_moons, load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score, silhouette_samples
from sklearn.preprocessing import StandardScaler

# Создаём датасет с 4 кластерами
X, y_true = make_blobs(n_samples=300, centers=4, cluster_std=0.8, random_state=42)

# Нормализация
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print(f"Размер данных: {X_scaled.shape}")
print(f"Реальное число кластеров: {len(np.unique(y_true))}")

# Визуализация исходных данных
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap='viridis', s=50)
plt.title('Истинная разметка (4 кластера)')
plt.colorbar()

plt.subplot(1, 2, 2)
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.title('Данные без разметки')
plt.tight_layout()
plt.show()



Этап 2. Метод локтя (Elbow method) (20 минут)

Определите оптимальное число кластеров по сумме квадратов расстояний:



# Расчёт инерции для разного числа кластеров
inertias = []
K_range = range(1, 11)

for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(X_scaled)
inertias.append(kmeans.inertia_)

# Визуализация метода локтя
plt.figure(figsize=(10, 5))
plt.plot(K_range, inertias, 'o-', linewidth=2, markersize=8)
plt.xlabel('Число кластеров (k)')
plt.ylabel('Сумма квадратов расстояний (Inertia)')
plt.title('Метод локтя для выбора числа кластеров')
plt.xticks(K_range)
plt.grid(True, alpha=0.3)

# Отмечаем точку "локтя"
# Находим точку максимального изгиба (упрощённо)
plt.axvline(x=4, color='r', linestyle='--', label='Оптимальное k=4')
plt.legend()
plt.show()



Вопрос: При каком значении k наблюдается «локоть»? Сколько кластеров оптимально?

Этап 3. Силуэтный анализ (Silhouette analysis) (20 минут)

Используйте силуэтный коэффициент для оценки качества кластеризации:



# Расчёт силуэтного коэффициента
silhouette_scores = []

for k in range(2, 11):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)
score = silhouette_score(X_scaled, labels)
silhouette_scores.append(score)
print(f"k={k}: Silhouette Score = {score:.4f}")

# Визуализация
plt.figure(figsize=(10, 5))
plt.plot(range(2, 11), silhouette_scores, 'o-', linewidth=2, markersize=8)
plt.xlabel('Число кластеров (k)')
plt.ylabel('Силуэтный коэффициент')
plt.title('Силуэтный анализ для выбора числа кластеров')
plt.xticks(range(2, 11))
plt.grid(True, alpha=0.3)

best_k = range(2, 11)[np.argmax(silhouette_scores)]
plt.axvline(x=best_k, color='r', linestyle='--', label=f'Оптимальное k={best_k}')
plt.legend()
plt.show()



Вопрос: Какое значение k даёт максимальный силуэтный коэффициент?

Этап 4. Визуализация кластеризации для разных k (15 минут)

Посмотрите, как меняется разбиение при разном количестве кластеров:



# Кластеризация для разных k
k_values = [2, 3, 4, 5]
fig, axes = plt.subplots(2, 2, figsize=(12, 10))

for i, k in enumerate(k_values):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_scaled)

row, col = i // 2, i % 2
axes[row, col].scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis', s=50)
axes[row, col].scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
c='red', marker='X', s=200, edgecolors='black')
axes[row, col].set_title(f'k = {k}, Silhouette = {silhouette_score(X_scaled, labels):.3f}')
axes[row, col].set_xlabel('Признак 1')
axes[row, col].set_ylabel('Признак 2')

plt.tight_layout()
plt.show()



Вопросы:
• Что происходит при k=2? Как разделены данные?
• Что происходит при k=5? Есть ли лишние кластеры?

Этап 5. Эксперимент со сложной формой кластеров (15 минут)

Проверьте K-means на данных с нешарообразной формой:



# Создаём датасет в форме полумесяцев
X_moons, y_moons = make_moons(n_samples=300, noise=0.05, random_state=42)

# Нормализация
X_moons_scaled = scaler.fit_transform(X_moons)

# K-means на этих данных
kmeans_moons = KMeans(n_clusters=2, random_state=42, n_init=10)
labels_moons = kmeans_moons.fit_predict(X_moons_scaled)

# Визуализация
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(X_moons[:, 0], X_moons[:, 1], c=y_moons, cmap='viridis', s=50)
plt.title('Истинная разметка (два полумесяца)')

plt.subplot(1, 2, 2)
plt.scatter(X_moons[:, 0], X_moons[:, 1], c=labels_moons, cmap='viridis', s=50)
plt.title(f'K-means (k=2), Silhouette = {silhouette_score(X_moons_scaled, labels_moons):.3f}')

plt.tight_layout()
plt.show()

print("K-means не справился с формой полумесяцев!")
print("Силуэтный коэффициент ниже, чем для blob-данных.")



Вопрос: Почему K-means плохо работает на данных в форме полумесяцев?

Этап 6. Практическое задание: кластеризация ирисов Фишера (10 минут)

Примените изученные методы к реальному датасету Iris:



# Загрузка данных Iris
iris = load_iris()
X_iris = iris.data
y_iris = iris.target

# Нормализация
X_iris_scaled = scaler.fit_transform(X_iris)

# Определение оптимального числа кластеров
inertias_iris = []
silhouette_iris = []

for k in range(2, 8):
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
labels = kmeans.fit_predict(X_iris_scaled)
inertias_iris.append(kmeans.inertia_)
silhouette_iris.append(silhouette_score(X_iris_scaled, labels))

# Визуализация
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(range(2, 8), inertias_iris, 'o-')
plt.xlabel('k')
plt.ylabel('Inertia')
plt.title('Метод локтя для Iris')

plt.subplot(1, 2, 2)
plt.plot(range(2, 8), silhouette_iris, 'o-')
plt.xlabel('k')
plt.ylabel('Silhouette Score')
plt.title('Силуэтный анализ для Iris')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

best_k_iris = range(2, 8)[np.argmax(silhouette_iris)]
print(f"Оптимальное число кластеров для Iris: {best_k_iris}")
print(f"Реальное число классов в Iris: {len(np.unique(y_iris))}")



Вопрос: Совпадает ли оптимальное число кластеров с реальным числом видов ирисов?

Этап 7. Выводы по лабораторной работе (10 минут)

Оформите отчёт, включив в него:

1. Графики метода локтя и силуэтного анализа
2. Результаты кластеризации для разных k
3. Сравнение K-means на данных разной формы (blobs vs moons)
4. Анализ датасета Iris
5. Выводы о методах выбора числа кластеров

КРИТЕРИИ ОЦЕНКИ

КритерийМакс. балл
Метод локтя выполнен и проанализирован3
Силуэтный анализ выполнен3Эксперимент с разными k визуализирован2Анализ Iris и moons выполнен2
Итого10


ОТВЕТ ДЛЯ ПРЕПОДАВАТЕЛЯ (эталонный результат)


Нажмите, чтобы увидеть ответы
Этап 2. Метод локтя:
• Локоть наблюдается при k=4 (совпадает с реальным числом кластеров)

Этап 3. Силуэтный анализ:
• Максимальный силуэтный коэффициент также при k=4
• Значение силуэта > 0.5 указывает на хорошую кластеризацию

Этап 4. Визуализация:
• k=2 — объединяет несколько кластеров в один
• k=5 — разбивает один кластер на два (избыточность)

Этап 5. Полумесяцы:
• K-means предполагает сферические кластеры одинакового размера
• Для сложных форм (полумесяцы) нужны другие алгоритмы (DBSCAN, спектральная кластеризация)

Этап 6. Iris:
• Оптимальное k по методу локтя — 3 (совпадает с реальностью)
• Силуэтный анализ также показывает лучший результат при k=3

Этап 7. Вывод:
Метод локтя и силуэтный анализ — эффективные инструменты для выбора k в K-means. Лучший результат достигается, когда оба метода указывают на одно и то же значение k.


Автор: УМК СПО
Лицензия: Бесплатное использование с указанием источника





Логин: Пароль: Забыли пароль?Регистрация

Самозанятый: Стешенко Светлана Николаевна ИНН: 231408226339

Актуальная версия — 2026
Сайт сделан на SiNG cms © 2010-2020