Условие
Дано: миллионы пользователей с сотнями транзакций каждый, десятки тысяч продуктов. Разбейте пользователей на осмысленные сегменты.
Решение
Подход
1. Что значит «осмысленные сегменты». Уточняем с заказчиком: «осмысленные для маркетинга» (характерный покупательский профиль), «для рекомендаций» (близость по предпочтениям), «для удержания» (по риску оттока). Метод и метрики разные.
2. Представление пользователей. Прямой подход «one-hot 10k товаров» не масштабируется. Альтернативы:
- RFM — Recency / Frequency / Monetary. Три фичи, легко интерпретируются. Базовый сегмент для CRM.
- Категорийные доли: вместо 10k товаров — N категорий. Пользователь = вектор долей
(category → spend / total_spend). - Эмбеддинги через collaborative filtering: matrix factorization, ALS, или Word2Vec по последовательности транзакций (skip-gram).
- TF-IDF поверх товаров + SVD до 50-100 компонент.
3. Кластеризация.
- На малых размерностях (RFM, ~10 фичей) — k-means.
- В эмбеддинг-пространстве — k-means, mini-batch k-means для больших n, GMM при необходимости вероятностной принадлежности.
- HDBSCAN — если кластеры нерегулярной формы, есть выбросы и не хочется выбирать
k.
4. Выбор k.
- Elbow по inertia / silhouette score / Davies-Bouldin.
- Domain check: можно ли назвать каждый сегмент одним предложением? Если нет — слишком много / мало.
5. Валидация.
- Stability: запускаем кластеризацию на двух случайных половинах данных и считаем ARI/AMI — насколько кластеры воспроизводятся.
- Бизнес: внутри кластера retention/LTV должны заметно отличаться от глобальных.
Реализация
import numpy as np
from sklearn.cluster import MiniBatchKMeans
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import TruncatedSVD
# 1. user x product sparse matrix
# 2. TF-IDF / log1p нормализация
X = TruncatedSVD(n_components=50, random_state=0).fit_transform(user_x_product)
X = StandardScaler().fit_transform(X)
km = MiniBatchKMeans(n_clusters=8, random_state=0, batch_size=10_000)
labels = km.fit_predict(X)Подводные камни
- Не стандартизировать признаки. RFM имеет разные шкалы; k-means минимизирует евклидово расстояние и без стандартизации отдаёт всё одной фиче (обычно — деньгам).
- Долгий хвост Monetary. Лог-преобразование (
log1p(spend)) до кластеризации — почти всегда улучшает результат. - k-means на категориях напрямую через one-hot — даёт мусор. Сначала эмбеддинги / SVD.
- Сегменты живут. Через 3 месяца пользователи мигрируют. Нужно мониторить дрифт распределения и перестраивать сегменты.
- Несбалансированные кластеры. Один большой и шесть маленьких — обычно проблема выбросов; HDBSCAN явно их маркирует.
Эталонный ответ
Сначала договоритесь, для чего сегментация. Сократите размерность (RFM, эмбеддинги или SVD по TF-IDF товаров), стандартизируйте, k-means или mini-batch k-means с выбором k по silhouette + интерпретируемости. Валидация — stability через ARI на двух выборках и бизнес-проверка различий метрик между кластерами.