Машинное обучение
Feature Engineering
В каждом выигрышном решении Kaggle главный фактор победы - не архитектура модели, а признаки. Andrew Ng говорит: applied ML is basically feature engineering. Одна и та же модель с правильными признаками может улучшить accuracy с 70% до 95%. Три инженера берут одинаковый датасет такси: первый подает сырой timestamp - accuracy 61%. Второй извлекает час и день недели - 79%. Третий добавляет is_rush_hour, is_weekend, distance_to_airport и погоду - 94%. Модель одна и та же. Разница - только в признаках.
- **Kaggle-соревнования** - победители тратят 60-80% времени на feature engineering, создавая сотни признаков из сырых данных, и простой gradient boosting с хорошими признаками побеждает сложные нейросети с сырыми данными
- **Рекомендательные системы Netflix/Spotify** - user_avg_rating, genre_preference_vector, time_since_last_interaction, popularity_decay - каждый из этих признаков прошел через feature store и переиспользуется десятками моделей
- **Fraud detection в банках** - transaction_velocity (сколько транзакций за час), distance_from_home, is_new_merchant, amount_vs_avg_ratio - эти hand-crafted features критичны для обнаружения мошенничества в реальном времени
Предварительные знания
Эпоха ручного создания признаков
До того как глубокое обучение автоматизировало построение представлений, качество модели определялось признаками, которые выбирал человек. Большую часть проекта практики тратили на ручное конструирование входов: отношения, бины, члены взаимодействия, доменные сигналы. В 2012 году Педро Домингос изложил общепринятую мудрость в своей широко читаемой статье "A Few Useful Things to Know about Machine Learning", прямо заявив, что именно в инженерии признаков уходит большая часть усилий в проекте машинного обучения и что она часто решает, будет успех или провал. Эндрю Ын говорил то же самое в своих лекциях, называя инженерию признаков сложной, трудоёмкой и той работой, что отделяет хорошие результаты от посредственных. Даже когда нейросети научились извлекать признаки автоматически для изображений и текста, ремесло уцелело в табличных и продакшен-сценариях, где удачно подобранные признаки по-прежнему бьют сырые входы.
Feature Selection
Больше признаков - не значит лучше. С ростом размерности данных возникает **curse of dimensionality**: расстояния между точками выравниваются, модель начинает переобучаться на шуме, а время обучения растет экспоненциально. Feature selection решает эту проблему, оставляя только **информативные** признаки. Три основных подхода: filter methods (статистические тесты до обучения), wrapper methods (перебор подмножеств с обучением модели), embedded methods (отбор встроен в обучение).
**Filter methods** оценивают каждый признак независимо от модели. Correlation - линейная связь с target, mutual information - любая зависимость (включая нелинейную), chi-squared - для категориальных признаков, ANOVA F-value - для числовых. Главный минус: filter методы не учитывают **взаимодействия** между признаками. Признак, бесполезный сам по себе, может быть критически важен в комбинации с другим.
**Wrapper methods** используют модель как черный ящик: пробуют разные подмножества признаков и выбирают лучшее по cross-validation score. Forward selection начинает с пустого множества и добавляет по одному признаку. Backward elimination начинает со всех и убирает по одному. Качество высокое, но стоимость тоже: для d признаков forward selection обучает O(d^2) моделей.
**Curse of dimensionality на практике:** Представьте, что вы заполняете куб данными. В 1D (отрезок) для 10 точек на единицу длины нужно 10 точек. В 2D (квадрат) - 100 точек. В 3D (куб) - 1000. В 100D - 10^100 точек, что больше количества атомов во вселенной. Последствия: - **Расстояния теряют смысл:** в 1000D все точки примерно одинаково далеки друг от друга - **Модели переобучаются:** 100 признаков на 500 образцах - модель найдет случайные паттерны - **Правило:** нужно минимум 5-10 образцов на каждый признак
Компания строит модель на 500 образцах с 2000 признаками. Accuracy на train 99%, на test 52%. Какой метод feature selection лучше всего подойдет как первый шаг?
Создание признаков
Если feature selection убирает лишнее, то **feature creation** (feature engineering) добавляет полезное. Идея: сырые данные редко содержат признаки в той форме, которая нужна модели. Дата заказа "2024-03-15 14:30" сама по себе бесполезна для предсказания. Но из неё можно извлечь: час дня (14 - обеденное время), день недели (пятница), is_weekend (нет), квартал (Q1), дней до зарплаты. Каждый из этих признаков несет информацию, которую модель может использовать.
**Datetime features** - один из самых богатых источников информации в реальных данных. Из одного timestamp можно извлечь десятки признаков: hour, minute, day_of_week, is_weekend, month, quarter, day_of_year, week_of_year. Для e-commerce важен is_payday (конец месяца), для доставки - is_rush_hour, для ритейла - days_to_holiday. Ключевой принцип: **знание домена определяет, какие признаки создавать**.
**Domain-specific features - где знание предметной области критично:** - **E-commerce:** RFM-метрики (Recency - дней с последнего заказа, Frequency - заказов за месяц, Monetary - средний чек), конверсия по категориям, время от добавления в корзину до покупки - **Финансы:** скользящие средние (7d, 30d, 90d), волатильность (стандартное отклонение за окно), отношение цена/прибыль, momentum - **Текст:** длина текста, количество восклицательных знаков, доля заглавных букв, TF-IDF - **Геоданные:** расстояние до центра, плотность точек в радиусе, ближайший объект инфраструктуры
Золотое правило feature engineering: **начинайте с domain knowledge, а не с математики**. Polynomial features можно генерировать автоматически, но лучшие признаки создаются людьми, которые понимают задачу. В соревнованиях Kaggle победители тратят 60-80% времени именно на создание признаков, а не на подбор модели или гиперпараметров. Хорошие признаки могут превратить простую логистическую регрессию в победителя соревнования.
У вас есть колонка order_datetime. Модель предсказывает спрос на доставку еды. Какой набор features будет наиболее полезен?
Стратегии кодирования
Большинство ML-моделей работают с числами, но реальные данные полны категорий: город, цвет, профессия, операционная система. **Encoding** - преобразование категорий в числа. Неправильное кодирование может полностью сломать модель: если закодировать цвета как red=1, green=2, blue=3, модель решит, что blue > red и green = среднее между ними. Это бессмысленно для неупорядоченных категорий.
**Target encoding** решает проблему высокой кардинальности. Вместо создания 10000 бинарных колонок (one-hot для городов), каждая категория заменяется **средним значением target** для этой категории. Город с высокой средней стоимостью жилья получит высокое значение. Главная опасность - **data leakage**: если считать среднее по всем данным (включая текущую строку), модель "подглядывает" ответ. Решение: считать среднее через cross-validation или со сглаживанием (smoothing).
**Когда какой encoding использовать:** - **2-5 категорий** (пол, тип платежа): One-Hot - безопасно и просто - **5-20 категорий** (страна, категория товара): One-Hot для линейных моделей, Label для деревьев - **20-1000 категорий** (город, бренд): Target или Frequency encoding - **1000+ категорий** (user_id, product_id, слово): Embedding (обучаемый вектор в нейросети) - **Упорядоченные** (S/M/L/XL, образование): Ordinal encoding **Правило для деревьев (XGBoost, LightGBM, CatBoost):** Label encoding работает хорошо, потому что деревья разбивают по порогу (city <= 2), не предполагая линейного порядка. CatBoost имеет встроенный target encoding.
Вы строите линейную регрессию для предсказания цены квартиры. Один из признаков - район города (150 уникальных районов). Какой encoding выбрать?
Feature Stores
Когда feature engineering выходит за пределы Jupyter notebook в продакшн, возникают новые проблемы. Data scientist вычисляет avg_order_amount за 30 дней при обучении модели. Инженер при деплое пишет свой SQL-запрос для того же признака, но с ошибкой - считает за 31 день или включает отмененные заказы. Модель обучена на одних данных, а в продакшне получает другие. Результат: **training-serving skew** - модель работает хуже, чем на тестах. **Feature store** решает эту проблему, создавая единый источник правды для признаков.
Feature store решает три ключевые проблемы. **Consistency** - один и тот же код вычисляет признак и для обучения, и для serving, исключая training-serving skew. **Reuse** - команда рекомендаций вычислила user_embedding, команда fraud detection может переиспользовать его без дублирования работы. **Point-in-time correctness** - при обучении модель должна видеть только признаки, доступные *на момент предсказания*, иначе возникает data leakage из будущего.
**Point-in-time correctness - почему это критично:** Вы обучаете модель предсказывать отток. У клиента есть признак avg_purchase_30d. При обучении вы берете данные на 1 марта, но avg_purchase_30d посчитан по данным до 15 марта - на 2 недели вперед! Модель "знает будущее" и показывает отличные метрики. В продакшне будущего нет, и модель проваливается. Feature store хранит **временные срезы** признаков и автоматически выбирает значение, актуальное на нужный момент времени. Это называется **time-travel query**.
Основные feature store инструменты: **Feast** (open-source, Python, поддерживает AWS/GCP/local), **Tecton** (managed Feast, enterprise), **Hopsworks** (open-source, Java/Python), **Databricks Feature Store** (интеграция со Spark). Для небольших команд Feast с Redis online store и Parquet offline store - достаточный выбор. Для enterprise с сотнями моделей и командами - Tecton или Databricks. Feature store стоит внедрять, когда у вас больше 3-5 моделей в продакшне, которые используют пересекающиеся признаки.
Feature engineering не нужен в эпоху deep learning - нейросети сами извлекают признаки из сырых данных
Для табличных данных feature engineering до сих пор важнее выбора модели, а победители Kaggle тратят 80% времени на создание признаков, а не на архитектуру нейросетей
Deep learning автоматически извлекает признаки из изображений, текста и аудио. Но для табличных данных (90% задач в бизнесе) gradient boosting с хорошими признаками стабильно побеждает нейросети. Последние 5 лет победители Kaggle на табличных данных - XGBoost/LightGBM с ручным feature engineering. AutoML-инструменты генерируют базовые признаки, но domain-specific features (RFM в e-commerce, technical indicators в финансах) создаются людьми.
Data scientist обучил модель оттока с признаком avg_purchase_30d. В продакшне ML engineer написал свой SQL с ошибкой - считает avg_purchase_31d. Accuracy модели упала с 92% до 78%. Как feature store предотвратил бы эту проблему?
Итоги
- **Feature Selection:** filter, wrapper и embedded методы отбирают информативные признаки и борются с curse of dimensionality - L1 регуляризация обнуляет веса бесполезных признаков, а tree-based importance оценивает вклад каждого
- **Feature Creation:** datetime decomposition, polynomial interactions, aggregation features и domain-specific признаки превращают сырые данные в информацию, которую модель может использовать - знание предметной области важнее математических методов
- **Encoding:** one-hot для малой кардинальности, target encoding для высокой, ordinal для упорядоченных, embedding для сверхвысокой - неправильный encoding может полностью сломать модель, создав ложный порядок
- **Feature Stores:** Feast, Tecton и аналоги обеспечивают consistency между training и serving, reuse признаков между командами и point-in-time correctness - как три инженера с датасетом такси из нашего примера, разница в признаках определяет результат, а feature store гарантирует, что все используют одни и те же правильные признаки
Связанные темы
Feature engineering связывает предобработку данных с продвинутыми методами моделирования, превращая сырые данные в информативные признаки на каждом этапе ML-пайплайна:
- Data Preprocessing — Feature engineering продолжает preprocessing: после очистки и нормализации данных начинается создание новых признаков, которые усиливают предсказательную силу модели
- Gradient Boosting — XGBoost и LightGBM - основные бенефициары feature engineering на табличных данных, их feature_importances_ помогают понять, какие созданные признаки наиболее полезны
Вопросы для размышления
- Почему domain knowledge часто важнее автоматических методов feature engineering? Приведите пример признака из вашей области, который нельзя сгенерировать автоматически.
- Training-serving skew может незаметно снижать качество модели в продакшне. Как бы вы обнаружили эту проблему без feature store, если метрики в production мониторинге ухудшились?
- Когда polynomial features (автоматическая генерация) оправданы, а когда лучше создавать признаки вручную? Как связан выбор с количеством исходных признаков и объемом данных?
Связанные уроки
- ml-04-data-preprocessing — Feature engineering идёт после очистки данных
- ml-22-gradient-boosting — Сконструированные признаки усиливают деревья
- ml-19-pca — PCA создаёт признаки и снижает размерность
- ml-05-evaluation — Лучшие признаки улучшают метрики
- stat-08-correlation — Корреляция направляет отбор признаков
- stat-01-sampling