Ответ
Одна из наиболее сложных задач — это разработка системы предсказания оттока (churn prediction) для крупного телеком-оператора. Основная сложность заключалась в работе с крайне несбалансированными данными (только 5% клиентов уходили) и большим количеством шумных, разреженных признаков из истории звонков и транзакций.
Мой подход к решению:
- Feature Engineering: Я создал более 100 новых признаков, агрегируя сырые данные за различные временные окна. Это включало тренды активности, сезонность (например, активность по дням недели), а также признаки, основанные на изменениях поведения (например, резкое снижение числа звонков).
- Борьба с дисбалансом: Простое взвешивание классов в модели не давало нужного recall. Я применил комбинированную стратегию:
SMOTEдля генерации синтетических примеров минорного класса иRandomUnderSamplerдля majority класса, что позволило улучшить работу модели на "сложных" клиентах. - Выбор и настройка модели: После сравнения нескольких алгоритмов лучшие результаты показал CatBoost благодаря своей эффективной работе с категориальными признаками. Я настроил кастомную функцию потерь, чтобы сильнее штрафовать пропуск клиента, который действительно уйдет (false negative).
Пример итогового пайплайна:
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from catboost import CatBoostClassifier
# Определение шагов пайплайна
pipeline = Pipeline([
('preprocessor', custom_preprocessor), # Кастомный трансформер для фичей
('oversample', SMOTE(sampling_strategy=0.2, random_state=42)),
('undersample', RandomUnderSampler(sampling_strategy=0.5, random_state=42)),
('classifier', CatBoostClassifier(
iterations=1000,
learning_rate=0.05,
depth=8,
loss_function='Logloss',
eval_metric='F1',
silent=True
))
])
# Обучение с кросс-валидацией
pipeline.fit(X_train, y_train)
В результате нам удалось достичь F1-score в 0.78 на hold-out выборке (против 0.65 у baseline-решения), что позволило бизнесу более точно таргетировать программы удержания.
Ответ 18+ 🔞
Слушай, вот реальная задача была — предсказать, какой клиент телекома соберёт манатки и свалит. А сложность в чём? В том, что уходят-то единицы, всего 5%, а остальные 95% сидят как приклеенные. Данные — пиздец какой шум, куча признаков из истории звонков, которые больше похожи на редкую сетку, чем на что-то осмысленное.
Как я это, блядь, решал:
- Признаки накручивал (Feature Engineering): Честно, я там насоздавал признаков — овердохуища. Взял сырые данные и начал агрегировать: тренды, сезонность (например, в пятницу все звонят, а в воскресенье — ни хуя), и самое главное — резкие изменения. Если клиент вдруг как с цепи сорвался и перестал звонить — это же явный звоночек, ёпта! Сто с лишним новых фичей вышло.
- Борьба с дисбалансом: Сначала попробовал просто дать веса классам в модели — нихуя не помогло, recall был ниже плинтуса. Потом пошёл на хитрость: использовал
SMOTE, чтобы нагенерить синтетических "уходящих" клиентов, иRandomUnderSampler, чтобы немного порезать этих, блядь, "верных". Стало лучше, модель перестала слепо всех в "лояльные" записывать. - Выбор модели: Перепробовал кучу всего, но в итоге CatBoost оказался королём. Он с категориальными признаками работает как швейцарские часы. А ещё я ему кастомную функцию потерь впендюрил, чтобы он охуевал и боялся пропустить реального "беглеца" (этот ваш false negative).
Вот, смотри, как пайплайн выглядел в коде:
from imblearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from catboost import CatBoostClassifier
# Определение шагов пайплайна
pipeline = Pipeline([
('preprocessor', custom_preprocessor), # Кастомный трансформер для фичей
('oversample', SMOTE(sampling_strategy=0.2, random_state=42)),
('undersample', RandomUnderSampler(sampling_strategy=0.5, random_state=42)),
('classifier', CatBoostClassifier(
iterations=1000,
learning_rate=0.05,
depth=8,
loss_function='Logloss',
eval_metric='F1',
silent=True
))
])
# Обучение с кросс-валидацией
pipeline.fit(X_train, y_train)
Итог? F1-score подняли до 0.78, хотя изначально было 0.65 — и это на отложенной выборке, не на тренировочной! Бизнес потом такие программы удержания запустил, хитрая жопа, что конкретно на этих "подозрительных" клиентах и сфокусировались, а не деньги на всех подряд размазывали. В общем, работа была — ебать колотить, но результат того стоил.