**Контекст:** 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
Это задание для уровня Middle. Для middle-аналитиков с опытом 1-3 года, требует уверенного владения темой и понимания edge cases.
Подобные задания в категории «Python» регулярно дают на собеседованиях аналитика данных в Яндекс, Сбер, Ozon, Авито, Тинькофф, Wildberries, T-Bank, X5, ВТБ и других крупных IT-компаниях. Тематика: pandas, mlxtend, Apriori, ассоциативные правила, cross-sell.
На реальном собеседовании на подобную задачу отводится 15-30 минут — оцениваются подход, корректность, обработка edge cases. Для тренировки рекомендуем сначала решить самостоятельно, потом сверить с эталонным решением и подсказками.
На zasqlpython.ru есть 482 Python задачи с проверкой через Pyodide, конспекты Python и pandas, AI мок-собеседование с разбором ваших ответов.
← Все задания