Лабораторная работа №13: Кластеризация и Сегментация клиентов
Цель: Решить задачу обучения без учителя (Unsupervised Learning). У нас нет правильных ответов (меток классов). Наша задача — найти скрытые структуры в данных и разделить клиентов торгового центра на группы (сегменты) на основе их поведения, используя K-Means и Иерархическую кластеризацию.
Инструменты:
sklearn.cluster: KMeans, AgglomerativeClustering.sklearn.preprocessing: StandardScaler.scipy.cluster.hierarchy: dendrogram, linkage (для визуализации иерархии).sklearn.metrics: silhouette_score.
Данные:
Mall Customers Dataset. Классический учебный датасет для сегментации. Содержит: CustomerID, Gender, Age, Annual Income (Доход), Spending Score (Баллы трат от 1 до 100).
Часть 1: Загрузка, EDA и Масштабирование
Мы будем использовать только два признака: Доход и Рейтинг трат. Это позволит нам легко визуализировать результаты на 2D-плоскости. В реальности признаков может быть больше (N-мерное пространство).
Часть 2: K-Means и Метод Локтя
Мы не знаем, сколько сегментов клиентов существует. 3? 5? 10? Используем метод локтя (Elbow Method), чтобы найти оптимальное .
Задание 2.1: График Инерции
- Запустите цикл
kот 1 до 10. - Внутри цикла обучите
KMeansи сохраните значениеinertia_в список. - Постройте график. Ищите “излом”.
from sklearn.cluster import KMeans
wcss = [] # Within-Cluster Sum of Square (Inertia)
# TODO: Напишите цикл
# for i in range(1, 11):
# kmeans = KMeans(n_clusters=i, init='k-means++', random_state=42, n_init=10)
# kmeans.fit(X_scaled)
# wcss.append(kmeans.inertia_)
# Визуализация
# plt.figure(figsize=(10, 5))
# plt.plot(range(1, 11), wcss, marker='o')
# plt.title('The Elbow Method')
# plt.xlabel('Number of clusters')
# plt.ylabel('WCSS (Inertia)')
# plt.show()
# Вопрос: Где график делает самый резкий поворот? Обычно это 5.
Задание 2.2: Финальная кластеризация и Визуализация
- Обучите модель с оптимальным (пусть будет ).
- Получите предсказанные метки кластеров (
fit_predict).
Нарисуем результат. Чтобы график был понятен бизнесу, точки будем брать из исходного (не масштабированного) датасета X, а цвета — из полученных меток y_kmeans.
# TODO: Обучите финальную модель
# kmeans_final = KMeans(n_clusters=5, init='k-means++', random_state=42, n_init=10)
# y_kmeans = kmeans_final.fit_predict(X_scaled)
plt.figure(figsize=(12, 8))
# TODO: Постройте scatter plot, где цвет (c) зависит от y_kmeans
# plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=50, cmap='viridis', label='Customers')
# Отрисовка центроидов (нужно сделать обратное масштабирование, чтобы они попали на график)
# centers = scaler.inverse_transform(kmeans_final.cluster_centers_)
# plt.scatter(centers[:, 0], centers[:, 1], s=200, c='red', marker='X', label='Centroids')
plt.title('Customer Segments')
plt.xlabel('Annual Income (k$)')
plt.ylabel('Spending Score (1-100)')
plt.legend()
plt.show()
Бизнес-интерпретация
Попробуйте дать названия группам.
- Низкий доход, Низкий скор -> “Экономные”.
- Низкий доход, Высокий скор -> “Транжиры” (целевая группа для кредитов?).
- Высокий доход, Высокий скор -> “VIP”.
Часть 3: Иерархическая кластеризация
Посмотрим на данные с другой стороны. Построим дерево объединения (Дендрограмму).
Часть 4: Валидация (Silhouette Score)
У нас нет “правильных ответов”, но есть математика. Оценим плотность кластеров.
Задание 4.1: Расчет Силуэта
Посчитайте silhouette_score для результата K-Means.
- Диапазон: [-1, 1].
- Хороший результат: > 0.5.
from sklearn.metrics import silhouette_score
# TODO: Посчитайте силуэт
# score = silhouette_score(X_scaled, y_kmeans)
# print(f"Silhouette Score (K-Means): {score:.4f}")
# Сравните с иерархическим (опционально)
# score_hc = silhouette_score(X_scaled, y_hc)
# print(f"Silhouette Score (Hierarchy): {score_hc:.4f}")