Практическая работа: «Анализ данных с применением технологий машинного обучения» Датасет: t-tech/T-ECD, подмножество
small/marketplaceОбъект анализа: товары маркетплейса (items)
Полный ML-пайплайн в одном Jupyter-ноутбуке + интерактивный HTML-дашборд для просмотра результатов.
Главные файлы: analysis.ipynb · dashboard.html · build_notebook.py
- Быстрый старт
- Как работает пайплайн
- Структура проекта
- Полученные метрики
- Соответствие ТЗ
- Ключевые методические решения
- Самооценка и ревью проекта
python -m pip install -r requirements.txtТребуется Python 3.10+. PyTorch ставится в CPU-варианте; для GPU — отдельная установка с
--index-url https://download.pytorch.org/whl/cu121.
Jupyter-интерактивно:
jupyter notebook analysis.ipynbПервый запуск скачает ~2.7 ГБ данных (7 шардов событий + items.pq) с Hugging Face. Кэш в
~/.cache/huggingface/. Повторные запуски — мгновенная загрузка из кэша.
Windows — двойной клик по serve_dashboard.bat (откроет браузер автоматически).
macOS / Linux / любая платформа:
python -m http.server 8000
# открыть http://localhost:8000/dashboard.htmlВ дашборде:
⟳ Обновить— перечитать CSV/JSON и сбросить кэш картинок;▶ Авто 30с— автообновление каждые 30 секунд;- Клик по графику — открыть в полный размер (lightbox);
ESC— закрыть.
analysis.ipynb исполняется сверху вниз и выполняет 9 этапов из ТЗ:
| # | Этап | Что происходит |
|---|---|---|
| 1 | Постановка задачи | Описание объекта, рисков, целевых метрик |
| 2 | Подготовка данных | Скачивание 7 шардов событий + items.pq (resumable), типы, дубликаты, join |
| 3 | Контроль объёма | assert total_rows >= 3_000_000 (по факту ~3.5M) |
| 4 | EDA | Распределения action_type, цены (log), топ-категории — eda_overview.png |
| 5 | Признаки | Поведенческие (action_*, total_interactions, unique_users) + one-hot категорий |
| 6 | Кластеризация | RobustScaler + np.log1p, KMeans, поиск k через silhouette/CH/elbow |
| 7А | Классификация | RandomForest + LogisticRegression + LinearSVM с calibration; F1, ROC-AUC, Precision, Recall |
| 7Б | Регрессия | MLP 128→64→32 + ReLU + Dropout(0.3); train/val/test = 70/15/15; MAE, RMSE, R² |
| 8 | Оптимизация | Naive Python loop vs pandas-groupby vs joblib threading с замером time |
| 9 | Итоговые выводы | Сопоставление кластеризации и ML-ветки |
HF Hugging Face
├─ events/01082..01088.pq ──┐
└─ items.pq (cols=5) ├─► merge(item_id) ──► dropna(price)
│
└─► aggregate by item_id ──► features (item-level)
│
┌──────────────┼──────────────┐
▼ ▼ ▼
кластеризация классификация регрессия
(10 групп) (3 модели) (MLP)
![]() |
![]() |
| EDA: распределения и топ-категории | Поиск оптимального k |
![]() |
![]() |
| Confusion matrix лучшей модели | Регрессия: обучение и предсказания |
Реальные цифры после исполнения ноутбука (без утечки таргета). Внимание: низкий R² регрессии — это честный результат, а не ошибка (см. ниже).
- 3 500 014 событий (7 шардов × 500 002), требование ТЗ ≥3M ✓
- ~1.3M items с непустой ценой после очистки (~280K trial set после стратификации)
- 66 признаков в моделях (без
price)
- Силуэт оптимального k — выбран по argmax silhouette score
- Кластер «бестселлеры»: ~2626 view, ~2025 уникальных пользователей
- Кластер «без активности»: 0 действий по всем типам
- Полный профиль —
results/cluster_profile.csv
| Модель | F1 (test) | ROC-AUC (test) | Precision | Recall |
|---|---|---|---|---|
| Random Forest | 0.431 | 0.684 | 0.427 | 0.436 |
| Logistic Regression | 0.425 | 0.683 | 0.439 | 0.412 |
| Linear SVM (calibrated) | 0.210 | 0.683 | 0.699 | 0.124 |
Лучшая по test ROC-AUC — Random Forest. Конфьюжн-матрица в results/confusion_matrix.png.
| Метрика | Значение |
|---|---|
| MAE | 1.18 |
| RMSE | 1.56 |
| R² | 0.07 |
| Метод | Время | Ускорение |
|---|---|---|
| Naive Python loop | 0.027 s | 1.0× |
| pandas groupby (vectorized) | 0.023 s | 1.19× |
| joblib threading (×4) | 0.044 s | 0.62× (медленнее!) |
- R² регрессии = 0.07. На первый взгляд это «плохо», но фундаментально это корректный
результат: предсказывать конкретную цену товара только по поведенческим признакам
- категории трудно. Большая часть вариации цены — внутри
subcategory, и нужны атрибуты товара (бренд-тиры, размеры, материал), которых в признаках нет.
- категории трудно. Большая часть вариации цены — внутри
- Оптимизация: multiprocessing проиграл. На 200K строк параллелизм через joblib работает медленнее векторизации из-за overhead'а. Дидактически это полезно (показывает, что выбор инструмента зависит от размера данных)
- CalibratedClassifierCV(LinearSVM) дал низкий recall (0.12). Linear SVM на дисбалансных
классах с calibration становится консервативным. Это ожидаемо, но если важна чувствительность —
лучше бы сразу
class_weight='balanced'в LogReg/RF (уже стоит) + калибровка по threshold.
- GridSearchCV для классификации — сейчас RF/LR/SVM с одним набором гиперпараметров. Гридсёрч (как было в исходной версии) дал бы +0.02–0.05 к F1.
- Эмбеддинги item-описаний из items.pq — там лежат векторы текста (мы их игнорируем). На них регрессия R² должен подскочить.
- HDBSCAN в качестве альтернативы KMeans — нативно отделяет шум от плотных кластеров.
- Numba-jit для наивного цикла в разделе оптимизации — даст драматический speedup и покроет третий пункт «numba ИЛИ векторизация ИЛИ multiprocessing» из ТЗ сразу.
- CI —
pytest+nbmakeдля автопрогона ноутбука в GitHub Actions.



