Какие методы генерации признаков (feature engineering) вы применяете?

«Какие методы генерации признаков (feature engineering) вы применяете?» — вопрос из категории Предобработка данных, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Генерация признаков — это творческий и критически важный этап, который сильно влияет на качество модели. Вот методы, которые я регулярно использую:

1. Работа с датой и временем: Из одной колонки timestamp можно извлечь десятки информативных признаков.

import pandas as pd
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['hour'] = df['timestamp'].dt.hour
df['day_of_week'] = df['timestamp'].dt.dayofweek
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
df['part_of_day'] = pd.cut(df['hour'], bins=[0, 6, 12, 18, 24], labels=['night', 'morning', 'afternoon', 'evening'])

2. Статистические агрегаты по группам: Добавление информации о группе, к которой принадлежит объект.

# Средняя цена в категории товара
df['mean_price_in_category'] = df.groupby('category_id')['price'].transform('mean')
# Отклонение цены товара от средней по категории
df['price_deviation_from_category'] = df['price'] - df['mean_price_in_category']

3. Взаимодействие признаков (Feature Cross): Комбинирование существующих признаков для выявления нелинейных зависимостей.

df['price_per_sq_meter'] = df['price'] / df['area']
df['income_to_credit_ratio'] = df['monthly_income'] / df['credit_amount']
# Для категориальных признаков можно создать пересечение
df['city_x_product_category'] = df['city'].astype(str) + '_' + df['product_category'].astype(str)

4. Полиномиальные признаки и преобразования: Для линейных моделей это способ уловить нелинейность.

from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2, interaction_only=True, include_bias=False)
poly_features = poly.fit_transform(df[['age', 'income']])

5. Работа с текстом:

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
# Базовые признаки
tfidf = TfidfVectorizer(max_features=500)
tfidf_features = tfidf.fit_transform(df['text_review'])
# Признаки на основе N-грамм
cv = CountVectorizer(ngram_range=(1, 2), max_features=300)
ngram_features = cv.fit_transform(df['product_title'])

6. Целевое кодирование (Target Encoding): Эффективный способ кодировки категориальных признаков с высокой кардинальностью.

target_mean = df.groupby('category')['target'].mean()
df['category_target_enc'] = df['category'].map(target_mean)
# Важно: чтобы избежать data leakage, расчет нужно делать на трейне, а маппинг применять на валидации/тесте

7. Признаки временных рядов (для транзакционных данных):

df = df.sort_values(['user_id', 'timestamp'])
df['days_since_last_purchase'] = df.groupby('user_id')['timestamp'].diff().dt.days
df['purchase_count_7d'] = df.groupby('user_id').rolling('7D', on='timestamp')['amount'].count().values

Ключ к успеху — глубокое понимание доменной области (domain knowledge). Например, для e-commerce можно создать признаки «скидка в процентах» или «сезонность товара».