Поведенческая сегментация пользователей через KMeans

Senior Python product

Условие задания

**Контекст:** Задание с собеса в продуктовую команду. Есть агрегированные метрики поведения пользователей — нужно разбить их на 4-6 осмысленных сегментов для персонализации (рассылки, рекомендации, UX).

**Данные:**

[см. код в задании]

**Задание:**

1. Провести KMeans-сегментацию с K=5.
2. Обязательно **стандартизация** (StandardScaler) — метрики в разных шкалах.
3. Вернуть `DataFrame` с оригинальными колонками + `segment` (0..4) + `segment_name` (человеко-читаемое).
4. Интерпретировать центроиды: описать каждый сегмент одним предложением.
5. Проверить что cluster sizes не слишком дисбалансированы (ни один < 5%).

Пример данных

Структура для ориентира — реальные значения из эталонного решения.

import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

def segment_users(df: pd.DataFrame, n_clusters: int = 5, random_state: int = 42) -> pd.DataFrame:
    features = [
        'days_since_signup', 'sessions_per_week', 'avg_session_duration',
        'total_purchases', 'avg_order_value', 'days_since_last_visit',
        'features_used'
    ]
    X = df[features].fillna(0).values

    # Стандартизация — иначе avg_order_value (тысячи) забьёт sessions_per_week (единицы)
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)

    # Log-трансформация для skewed распределений
    # avg_order_value и total_purchases часто имеют длинный хвост
    skewed_cols = ['avg_order_value', 'total_purchases']
    for col in skewed_cols:
        idx = features.index(col)
        X_scaled[:, idx] = np.log1p(np.abs(X_scaled[:, idx])) * np.sign(X_scaled[:, idx])

    # KMeans
    model = KMeans(n_clusters=n_clusters, random_state=random_state, n_init=10)
    labels = model.fit_predict(X_scaled)

    # Inverse transform центроидов для интерпретации в оригинальных единицах
    centroids_original = scaler.inverse_transform(model.cluster_centers_)
    centroids_df = pd.DataFrame(centroids_original, columns=features)

    # Автоматическая генерация названий по доминантным фичам
    segment_names = interpret_segments(centroids_df)

    result = df.copy()
    result['segment'] = labels
    result['segment_name'] = result['segment'].map(segment_names)

    return result, centroids_df


def interpret_segments(centroids: pd.DataFrame) -> dict:
    """
    Правило-ориентированное название сегментов по центроидам.
    В продакшне — обсуждают с PM и маркетингом.
    """
    names = {}
    for idx, row in centroids.iterrows():
        if row['total_purchases'] > 20 and row['avg_order_value'] > 5000:
            names[idx] = 'VIP: high frequency + high AOV'
        elif row['days_since_last_visit'] > 30:
            names[idx] = 'Churned: 30+ days inactive'
        elif row['days_since_signup'] < 30 and row['total_purchases'] < 2:
            names[idx] = 'New, unactivated'
        elif row['sessions_per_week'] > 10 and row['total_purchases'] < 5:
            names[idx] = 'Engaged browsers (high sessions, low purchases)'
        elif row['total_purchases'] >= 5 and row['avg_order_value'] < 2000:
            names[idx] = 'Regular low-AOV buyers'
        else:
            names[idx] = f'Segment {idx}'
    return names


# Использование:
segmented, centroids = segment_users(users, n_clusters=5)

# Проверка баланса сегментов
sizes = segmented['segment'].value_counts(normalize=True) * 100
print('Размеры сегментов (%):')
print(sizes.round(1))

# Характеристики центроидов
print('\nЦентроиды в оригинальных единицах:')
print(centroids.round(1))

Темы

clustering kmeans pca segmentation sklearn

Подсказки

Все тестовые задания →

Частые вопросы

Какой уровень знаний нужен для задачи "Поведенческая сегментация пользователей через KMeans"?

Это задание для уровня Senior. Senior-уровень — глубокое понимание темы, опыт решения нестандартных задач, обсуждение trade-off на собеседовании.

На каких собеседованиях встречается такая задача?

Подобные задания в категории «Python» регулярно дают на собеседованиях аналитика данных в Яндекс, Сбер, Ozon, Авито, Тинькофф, Wildberries, T-Bank, X5, ВТБ и других крупных IT-компаниях. Тематика: clustering, kmeans, pca, segmentation, sklearn.

Сколько времени даётся на решение?

На реальном собеседовании на подобную задачу отводится 30-60 минут с обсуждением подходов, оптимизаций и trade-off. Для тренировки рекомендуем сначала решить самостоятельно, потом сверить с эталонным решением и подсказками.

Где ещё потренироваться по теме «Python»?

На zasqlpython.ru есть 530+ Python задачи с проверкой через Pyodide, конспекты Python и pandas, AI мок-собеседование с разбором ваших ответов.

← Все задания