Market Basket Analysis — Apriori

Middle Python E-commerce

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

**Контекст:** E-commerce анализирует корзины покупателей для формирования рекомендаций «С этим товаром покупают».

**Данные:** DataFrame `orders` — колонки: `order_id`, `product_name`, `category`, `price`, `customer_id`.

**Задание:**
1. Преобразуйте данные в формат one-hot encoded корзин (order_id × product)
2. Примените алгоритм Apriori для поиска частых наборов (min_support=0.02)
3. Сгенерируйте ассоциативные правила (min_confidence=0.3)
4. Найдите топ-10 правил по lift и дайте рекомендации для cross-sell

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

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

import pandas as pd
import numpy as np
from mlxtend.frequent_patterns import apriori, association_rules

np.random.seed(42)

products = [
    'Ноутбук', 'Мышь', 'Клавиатура', 'Наушники', 'Монитор',
    'Чехол', 'Зарядка USB-C', 'Коврик для мыши', 'Веб-камера',
    'Подставка', 'Кабель HDMI', 'Сумка для ноутбука', 'SSD-диск',
    'Хаб USB', 'Кресло'
]

# Генерация заказов с реалистичными связями
n_orders = 5000
orders_list = []
for oid in range(n_orders):
    basket_size = np.random.choice([1, 2, 3, 4, 5], p=[0.2, 0.3, 0.25, 0.15, 0.1])
    basket = []

    # Реалистичные связки
    if np.random.random() < 0.15:
        basket.extend(['Ноутбук', 'Мышь', 'Сумка для ноутбука'])
    if np.random.random() < 0.10:
        basket.extend(['Монитор', 'Кабель HDMI'])
    if np.random.random() < 0.12:
        basket.extend(['Мышь', 'Коврик для мыши'])
    if np.random.random() < 0.08:
        basket.extend(['Ноутбук', 'Зарядка USB-C', 'Хаб USB'])

    remaining = max(0, basket_size - len(basket))
    if remaining > 0:
        available = [p for p in products if p not in basket]
        basket.extend(np.random.choice(available, min(remaining, len(available)), replace=False))

    for product in set(basket):
        orders_list.append({'order_id': oid, 'product_name': product, 'customer_id': np.random.randint(1, 2000)})

orders = pd.DataFrame(orders_list)
print(f"Заказов: {orders['order_id'].nunique()}, товаров: {orders['product_name'].nunique()}")
print(f"Средний размер корзины: {orders.groupby('order_id')['product_name'].count().mean():.1f}")

# 1. One-hot encoded корзины
basket_df = orders.groupby(['order_id', 'product_name']).size().unstack(fill_value=0)
basket_df = (basket_df > 0).astype(int)  # бинаризация

print(f"\nМатрица корзин: {basket_df.shape}")

# 2. Apriori — частые наборы
frequent = apriori(basket_df, min_support=0.02, use_colnames=True)
frequent['length'] = frequent['itemsets'].apply(len)
print(f"\nЧастых наборов: {len(frequent)}")
print(f"  1 товар: {(frequent['length']==1).sum()}")
print(f"  2 товара: {(frequent['length']==2).sum()}")
print(f"  3 товара: {(frequent['length']==3).sum()}")

# 3. Ассоциативные правила
rules = association_rules(frequent, metric='confidence', min_threshold=0.3)
rules['antecedents_str'] = rules['antecedents'].apply(lambda x: ', '.join(sorted(x)))
rules['consequents_str'] = rules['consequents'].apply(lambda x: ', '.join(sorted(x)))

print(f"\nПравил с confidence >= 0.3: {len(rules)}")

# 4. Топ-10 по lift
top_rules = rules.nlargest(10, 'lift')
print("\nТоп-10 правил по lift:")
for _, rule in top_rules.iterrows():
    print(f"  {rule['antecedents_str']:>30} → {rule['consequents_str']:<25} "
          f"support={rule['support']:.3f} conf={rule['confidence']:.2f} lift={rule['lift']:.2f}")

# Рекомендации для cross-sell
print("\n=== Рекомендации для cross-sell ===")
for product in ['Ноутбук', 'Монитор', 'Мышь']:
    recs = rules[rules['antecedents'].apply(lambda x: product in x)]
    if len(recs) > 0:
        best = recs.nlargest(3, 'lift')
        print(f"\n  Покупателям '{product}' предложить:")
        for _, r in best.iterrows():
            print(f"    → {r['consequents_str']} (confidence={r['confidence']:.0%}, lift={r['lift']:.1f})")

Темы

pandas mlxtend Apriori ассоциативные правила cross-sell

Подсказки

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

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

Какой уровень знаний нужен для задачи "Market Basket Analysis — Apriori"?

Это задание для уровня Middle. Для middle-аналитиков с опытом 1-3 года, требует уверенного владения темой и понимания edge cases.

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

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

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

На реальном собеседовании на подобную задачу отводится 15-30 минут — оцениваются подход, корректность, обработка edge cases. Для тренировки рекомендуем сначала решить самостоятельно, потом сверить с эталонным решением и подсказками.

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

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

← Все задания