Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Кластеризация: группировка похожих объектов
Кластеризация — это метод машинного обучения для разделения данных на группы (кластеры) похожих объектов БЕЗ предварительных меток.
Просто говоря: я ищу естественные группы в данных, не зная заранее сколько их будет.
Отличие от классификации
Классификация (supervised):
Данные: [1, 2, 3, 4, 5]
Метки: [A, A, B, B, B]
Задача: Обучить модель предсказывать метку для нового объекта
Кластеризация (unsupervised):
Данные: [1, 2, 3, 4, 5]
Метки: ??? (их нет)
Задача: Найти естественные группы в данных
Результат: [[1, 2], [3, 4, 5]] ← 2 кластера
Простой пример
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# Данные: показатели покупателей
data = pd.DataFrame({
'annual_income': [30000, 35000, 100000, 110000, 25000, 120000],
'spending_score': [25, 30, 85, 90, 20, 95]
})
# K-means кластеризация (разбить на 2 кластера)
kmeans = KMeans(n_clusters=2, random_state=42)
data['cluster'] = kmeans.fit_predict(data)
print(data)
Результат:
annual_income spending_score cluster
0 30000 25 0 ← Low spenders
1 35000 30 0 ← Low spenders
2 100000 85 1 ← High spenders
3 110000 90 1 ← High spenders
4 25000 20 0 ← Low spenders
5 120000 95 1 ← High spenders
Основные алгоритмы кластеризации
1. K-Means (самый популярный)
from sklearn.cluster import KMeans
# Определяю что ищу 3 кластера
kmeans = KMeans(n_clusters=3, random_state=42)
clusters = kmeans.fit_predict(data)
print(f"Centroid'ы (центры кластеров):\n{kmeans.cluster_centers_}")
print(f"Inertia (сумма расстояний): {kmeans.inertia_}")
Как работает K-Means:
Шаг 1: Выбираю 3 случайных точки как центры кластеров
Шаг 2: Назначаю каждую точку ближайшему центру
Шаг 3: Пересчитываю центры (среднее точек в кластере)
Шаг 4: Повтор 2-3 пока центры не стабилизируются
Плюсы:
- Простой и быстрый
- Хорошо масштабируется
- Интуитивно понятный результат
Минусы:
- Нужно заранее знать K (количество кластеров)
- Чувствителен к выбросам
- Предполагает сферические кластеры
2. Hierarchical Clustering (иерархическая)
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
# Иерархическая кластеризация
Z = linkage(data, method='ward')
# Дендрограмма (дерево кластеризации)
dendrogram(Z)
plt.show()
# Результат: визуализирую как данные объединяются в кластеры
Как работает:
Шаг 1: Каждая точка — отдельный кластер
Шаг 2: Объединяю два ближайших кластера
Шаг 3: Повтор пока все не в одном кластере
Результат: дерево, из которого можно вырезать нужное количество кластеров
Плюсы:
- Не нужно заранее знать K
- Дендрограмма показывает структуру
- Гибче чем K-Means
3. DBSCAN (density-based)
from sklearn.cluster import DBSCAN
# Находит кластеры плотности
dbscan = DBSCAN(eps=0.5, min_samples=5)
clusters = dbscan.fit_predict(data)
# Результат может включать -1 (выбросы)
Плюсы:
- Находит кластеры любой формы
- Автоматически находит K
- Хорошо отделяет выбросы
Минусы:
- Сложнее настроить параметры (eps, min_samples)
Как выбрать количество кластеров (K)
Метод 1: Elbow Method (локоть)
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
inertias = []
K_range = range(1, 11)
for k in K_range:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(data)
inertias.append(kmeans.inertia_)
# Инерция — сумма расстояний до центра кластера
# Чем она меньше, тем лучше
plt.plot(K_range, inertias, 'bo-')
plt.xlabel('Number of Clusters (K)')
plt.ylabel('Inertia')
plt.show()
# Ищу "локоть" — точку где инерция перестаёт быстро падать
# Обычно это оптимальное K
Метод 2: Silhouette Score (силуэт)
from sklearn.metrics import silhouette_score
silhouette_scores = []
for k in range(2, 11):
kmeans = KMeans(n_clusters=k, random_state=42)
clusters = kmeans.fit_predict(data)
score = silhouette_score(data, clusters)
silhouette_scores.append(score)
print(f"K={k}: Silhouette Score = {score:.3f}")
# Silhouette score от -1 до 1
# 1 = идеальное разделение
# 0 = точка на границе кластера
# -1 = точка в неправильном кластере
# Выбираю K с максимальным score
best_k = silhouette_scores.index(max(silhouette_scores)) + 2
print(f"\nОптимальное K: {best_k}")
Практические примеры для аналитики
Пример 1: Сегментация клиентов (RFM анализ)
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
# Создаю RFM метрики
df = pd.DataFrame({
'customer_id': range(1, 101),
'recency': [10, 5, 2, 1, 30, ...], # дни с последней покупки
'frequency': [1, 5, 20, 50, 1, ...], # количество покупок
'monetary': [100, 500, 2000, 5000, 50, ...] # общие расходы
})
# Стандартизирую (критично для K-Means)
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[['recency', 'frequency', 'monetary']])
# Кластеризую
kmeans = KMeans(n_clusters=3)
df['segment'] = kmeans.fit_predict(df_scaled)
# Анализирую сегменты
print(df.groupby('segment')[['recency', 'frequency', 'monetary']].mean())
Результат:
segment recency frequency monetary
0 25.2 2.1 120 ← Потерянные клиенты
1 5.3 15.2 1200 ← Хорошие клиенты
2 1.8 45.8 4500 ← VIP клиенты
Пример 2: Кластеризация продуктов
products = pd.DataFrame({
'product_id': range(1, 51),
'price': [10, 50, 100, 20, 200, ...],
'reviews_avg': [4.2, 4.8, 3.5, 4.0, 4.9, ...],
'units_sold': [1000, 500, 100, 2000, 50, ...]
})
# Стандартизирую
scaler = StandardScaler()
products_scaled = scaler.fit_transform(products[['price', 'reviews_avg', 'units_sold']])
# Кластеризую
kmeans = KMeans(n_clusters=4)
products['category_ml'] = kmeans.fit_predict(products_scaled)
# Интерпретирую
for cluster in range(4):
subset = products[products['category_ml'] == cluster]
print(f"Кластер {cluster}:")
print(f" Средняя цена: ${subset['price'].mean():.0f}")
print(f" Рейтинг: {subset['reviews_avg'].mean():.2f}")
print(f" Продаж: {subset['units_sold'].mean():.0f}")
print()
Пример 3: Временные ряды (паттерны)
# Кластеризация временных рядов
user_hourly_activity = pd.DataFrame({
'user_id': [1, 2, 3, 4, 5],
'hour_0': [0, 5, 2, 10, 1],
'hour_1': [0, 3, 1, 8, 0],
'hour_2': [0, 2, 1, 6, 0],
# ... для всех 24 часов
})
# Кластеризую чтобы найти похожие паттерны активности
kmeans = KMeans(n_clusters=3)
user_hourly_activity['activity_pattern'] = kmeans.fit_predict(
user_hourly_activity.iloc[:, 1:]
)
# Результат: находю что некоторые пользователи активны ночью,
# другие днём, третьи равномерно
Визуализация кластеров
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
# Если много размерностей, уменьшаю до 2D
pca = PCA(n_components=2)
data_2d = pca.fit_transform(data_scaled)
# Плотирую
plt.scatter(data_2d[:, 0], data_2d[:, 1], c=clusters, cmap='viridis')
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%})')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%})')
plt.title('Customer Segments')
plt.colorbar(label='Cluster')
plt.show()
Оценка качества кластеризации
Метрики:
from sklearn.metrics import (
silhouette_score,
davies_bouldin_score,
calinski_harabasz_score
)
# Silhouette (лучше > 0.5)
sil_score = silhouette_score(data, clusters)
# Davies-Bouldin (меньше лучше)
db_score = davies_bouldin_score(data, clusters)
# Calinski-Harabasz (больше лучше)
ch_score = calinski_harabasz_score(data, clusters)
print(f"Silhouette Score: {sil_score:.3f}")
print(f"Davies-Bouldin Score: {db_score:.3f}")
print(f"Calinski-Harabasz Score: {ch_score:.3f}")
Вывод
Кластеризация — это исследовательский анализ данных.
Когда использовать:
- Нет предварительных меток
- Хочу найти естественные группы в данных
- Нужна сегментация (клиентов, продуктов, поведения)
Основные алгоритмы:
- K-Means — быстро, просто, нужно знать K
- Hierarchical — гибче, видно структуру
- DBSCAN — находит любые формы кластеров
Практические шаги:
- Подготовка данных (стандартизация)
- Выбор K (Elbow или Silhouette)
- Кластеризация
- Интерпретация и анализ
- Использование (сегментация, персонализация)
Вывод: Кластеризация — мощный инструмент для понимания структуры данных и создания группы похожих объектов без предварительных меток.