← Назад к вопросам
Что ищут в данных при кластеризации?
1.8 Middle🔥 231 комментариев
#Машинное обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что ищут в данных при кластеризации: цели и инсайты
Кластеризация — это метод неконтролируемого обучения, который ищет скрытую структуру в данных. Рассмотрим, что именно мы пытаемся найти.
1. Естественные группировки (Intrinsic Clusters)
Это сегменты, которые существуют в данных физически.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
# Пример: Сегментация клиентов по поведению
from sklearn.preprocessing import StandardScaler
# Данные: (Расход, Частота покупок, Средний чек)
X = np.array([
[100, 2, 50], # Экономные покупатели
[110, 3, 45], # Экономные покупатели
[1000, 50, 20], # Активные покупатели
[1100, 48, 22], # Активные покупатели
[200, 10, 100], # Премиум клиенты
[190, 12, 95], # Премиум клиенты
])
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
kmeans = KMeans(n_clusters=3, random_state=42)
km_labels = kmeans.fit_predict(X_scaled)
print(f'Кластеры найдены: {set(km_labels)}')
# Результат: 3 естественных сегмента
# Кластер 0: Экономные
# Кластер 1: Активные
# Кластер 2: Премиум
Что ищем:
- Группы похожих объектов
- Отсутствие заранее известных меток
- Внутри-групповую сходство (high intra-cluster similarity)
- Между-групповую различие (low inter-cluster similarity)
2. Аномалии и outliers
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
# DBSCAN обнаруживает outliers как noise (-1 метка)
data = np.array([
[1, 1], [1, 2], [2, 1], [2, 2], # Нормальный кластер
[10, 10], [10, 11], [11, 10], # Второй кластер
[100, 100] # OUTLIER — изолированная точка
])
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)
dbscan = DBSCAN(eps=0.5, min_samples=2)
labels = dbscan.fit_predict(data_scaled)
outliers_indices = np.where(labels == -1)[0]
print(f'Найденные аномалии (индексы): {outliers_indices}') # [7]
Практическое применение:
- Обнаружение мошеннических транзакций
- Выявление неисправного оборудования (sensor anomalies)
- Выбросы в научных данных
3. Структура многомерных данных
from sklearn.decomposition import PCA
from sklearn.cluster import AgglomerativeClustering
import pandas as pd
# Данные: признаки пациентов (болезни, симптомы, тесты)
patient_data = pd.DataFrame({
'age': [25, 65, 30, 70, 28, 68],
'blood_pressure': [120, 150, 118, 160, 122, 155],
'glucose': [100, 180, 95, 200, 105, 190],
'bmi': [22, 28, 21, 30, 23, 29]
})
# Стандартизация
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data_scaled = scaler.fit_transform(patient_data)
# Иерархическая кластеризация
model = AgglomerativeClustering(n_clusters=2, linkage='ward')
clusters = model.fit_predict(data_scaled)
# Выводы
print(f'Кластер 0: {set(np.where(clusters == 0)[0])}')
print(f'Кластер 1: {set(np.where(clusters == 1)[0])}')
# Может выявить группы: "здоровые vs. группа риска"
4. Иерархическая структура
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib.pyplot as plt
# Данные о видах животных (признаки)
animals = np.array([
[1, 1, 1], # Кот
[1, 1, 1], # Собака
[0, 0, 1], # Птица
[0, 0, 1], # Попугай
[1, 0, 0], # Рыба
[1, 0, 0] # Акула
])
Z = linkage(animals, method='ward')
dendrogram(Z, labels=['Кот', 'Собака', 'Птица', 'Попугай', 'Рыба', 'Акула'])
plt.show()
# Дендрограмма показывает:
# - Млекопитающие (Кот, Собака) близки
# - Птицы (Птица, Попугай) близки
# - Рыбы (Рыба, Акула) близки
# - Млекопитающие vs Птицы vs Рыбы — разные ветви
Ищем:
- Иерархию групп
- На каком уровне детализации есть естественные кластеры
- Как связаны объекты на разных уровнях
5. Плотность-зависимые паттерны
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
# Пример: Выявление скопления пользователей в городах
users_locations = np.array([
[55.7558, 37.6173], # Москва центр
[55.7639, 37.6452], # Москва центр
[55.7800, 37.7000], # Москва центр
[59.9311, 30.3609], # Санкт-Петербург центр
[59.9508, 30.3609], # Санкт-Петербург центр
[55.0, 35.0], # Между городами (outlier)
])
dbscan = DBSCAN(eps=0.1, min_samples=2)
clusters = dbscan.fit_predict(users_locations)
print(f'Кластеры: {set(clusters)}')
# Результат: {0, 1, -1}
# 0 = Москва, 1 = СПб, -1 = Outlier
6. Выявление подобных товаров/документов
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import MiniBatchKMeans
# Кластеризация документов (например, отзывы о товарах)
documents = [
"Отличный товар, быстро пришёл",
"Супер качество, рекомендую",
"Плохое качество, не работает",
"Сломался сразу после покупки",
"Хороший товар за деньги",
"Не стоит покупать, развод"
]
vectorizer = TfidfVectorizer(max_features=100, ngram_range=(1, 2))
X = vectorizer.fit_transform(documents)
kmeans = MiniBatchKMeans(n_clusters=2, random_state=42)
kmeans.fit(X)
print(f'Положительные отзывы: {set(np.where(kmeans.labels_ == 0)[0])}')
print(f'Отрицательные отзывы: {set(np.where(kmeans.labels_ == 1)[0])}')
7. Сжатие информации и представление
from sklearn.cluster import KMeans
# Использование центроидов кластеров как compressed representation
X = np.random.randn(10000, 50) # 10К точек в 50-мерном пространстве
kmeans = KMeans(n_clusters=100, random_state=42)
kmeans.fit(X)
# Вместо хранения 10К точек, храним 100 центроидов
centroids = kmeans.cluster_centers_ # Shape: (100, 50)
print(f'Сжатие: {10000 * 50 / (100 * 50)} раз')
# 100x сжатие с приемлемой потерей информации
8. Подготовка к supervised learning
from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# Пример: Unsupervised -> Supervised
iris = load_iris()
X, y = iris.data, iris.target
# Шаг 1: Кластеризация (unsupervised)
kmeans = KMeans(n_clusters=3, random_state=42)
cluster_labels = kmeans.fit_predict(X)
# Шаг 2: Проверяем, соответствуют ли кластеры истинным классам
from sklearn.metrics import adjusted_rand_score
ari = adjusted_rand_score(y, cluster_labels)
print(f'ARI (соответствие кластеров истинным классам): {ari:.3f}')
# Высокий ARI = кластеры хорошо разделяют классы
# Шаг 3: Используем кластеры как новый признак для supervised learning
X_with_clusters = np.column_stack([X, cluster_labels])
X_train, X_test, y_train, y_test = train_test_split(X_with_clusters, y, test_size=0.2)
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
accuracy = rf.score(X_test, y_test)
print(f'Точность с кластерным признаком: {accuracy:.3f}')
Резюме: Что именно ищем при кластеризации
| Что ищем | Когда применяется | Метрика оценки |
|---|---|---|
| Естественные группы | Сегментация клиентов, типология | Silhouette Score |
| Аномалии | Fraud detection, QC | Isolation Forest score |
| Иерархия | Таксономия, классификация | Dendrogram |
| Плотные регионы | Геолокация, скопления | Davies-Bouldin Index |
| Подобие объектов | Рекомендации, дедупликация | Inertia (для K-means) |
| Compressed representation | Dimensionality reduction | Reconstruction error |
| Подготовка к supervised | Feature engineering | Downstream model performance |
Вывод: Кластеризация ищет скрытую структуру в данных без заранее известных меток. Главное — понять, что именно вы ищете в контексте вашей задачи, и выбрать метрики оценки, которые это проверяют.