Приведи пример задачи с бинарной классификацией
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Пример: Прогнозирование оттока клиентов (Churn Prediction)
Буду описывать реальный проект, в котором я работал для телеком-оператора.
Постановка задачи
Бизнес-контекст: Компания хочет предсказать, какие клиенты рискуют уйти к конкурентам в следующие 30 дней. Если мы определим таких клиентов заранее, сможем предложить им специальные условия или улучшить качество обслуживания.
Классы:
- Класс 1 (Положительный): Клиент уходит (churn = 1)
- Класс 0 (Отрицательный): Клиент остаётся (churn = 0)
Данные и признаки
Использовали следующие признаки:
# Поведенческие метрики
monthly_charges: ежемесячная плата
total_charges: общие затраты за всё время
contract_length: длина контракта (месяцы)
num_customer_service_calls: количество обращений в поддержку
days_since_last_interaction: дни с последнего взаимодействия
# Демографические данные
age: возраст
gender: пол
has_dependents: есть ли иждивенцы
# Сервисные характеристики
internet_type: тип интернета (DSL, Fiber, No)
has_phone_service: наличие телефонии
has_streaming: наличие потокового видео
months_with_company: месяцев в компании
Исследовательский анализ данных (EDA)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Распределение классов
churn_distribution = df["churn"].value_counts()
print(f"Класс 0 (остаются): {churn_distribution[0]}")
print(f"Класс 1 (уходят): {churn_distribution[1]}")
# Результат: явный дисбаланс классов (88% остаются, 12% уходят)
# Корреляция признаков с целевой переменной
correlation = df.corr()["churn"].sort_values(ascending=False)
print(correlation.head(10))
Подготовка данных
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split
# Обработка категориальных признаков
le = LabelEncoder()
df["gender_encoded"] = le.fit_transform(df["gender"])
# Нормализация численных признаков
scaler = StandardScaler()
numerical_features = ["age", "monthly_charges", "total_charges"]
df[numerical_features] = scaler.fit_transform(df[numerical_features])
# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
Проблема дисбаланса классов
Поскольку только 12% клиентов уходят, алгоритм может просто предсказывать, что все клиенты остаются, достигая 88% точности — но это бесполезно для бизнеса.
Решение:
from imblearn.over_sampling import SMOTE
# Переутечение (oversampling) меньшего класса
smote = SMOTE(random_state=42)
X_train_balanced, y_train_balanced = smote.fit_resample(X_train, y_train)
Обучение моделей
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
# Логистическая регрессия (baseline)
lr = LogisticRegression(random_state=42, max_iter=1000)
lr.fit(X_train_balanced, y_train_balanced)
# Random Forest (лучше обрабатывает нелинейности)
rf = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
rf.fit(X_train_balanced, y_train_balanced)
# Gradient Boosting (обычно лучше всех)
gb = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, random_state=42)
gb.fit(X_train_balanced, y_train_balanced)
Оценка моделей
from sklearn.metrics import (
confusion_matrix, precision_score, recall_score,
f1_score, roc_auc_score, roc_curve
)
import matplotlib.pyplot as plt
# Предсказания
y_pred = gb.predict(X_test)
y_pred_proba = gb.predict_proba(X_test)[:, 1]
# Метрики
print(f"Precision: {precision_score(y_test, y_pred):.3f}")
print(f"Recall: {recall_score(y_test, y_pred):.3f}")
print(f"F1-Score: {f1_score(y_test, y_pred):.3f}")
print(f"ROC-AUC: {roc_auc_score(y_test, y_pred_proba):.3f}")
# ROC-кривая
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
plt.figure(figsize=(8, 6))
plt.plot(fpr, tpr, label=f"ROC-AUC = {roc_auc_score(y_test, y_pred_proba):.3f}")
plt.plot([0, 1], [0, 1], "k--", label="Random Classifier")
plt.xlabel("False Positive Rate")
plt.ylabel("True Positive Rate")
plt.legend()
plt.show()
Матрица ошибок
cm = confusion_matrix(y_test, y_pred)
print(f"""
Истинно отрицательные (TN): {cm[0, 0]} - правильно предсказали "остаётся"
Ложные срабатывания (FP): {cm[0, 1]} - неправильно сказали "уходит"
Ложные отрицания (FN): {cm[1, 0]} - неправильно сказали "остаётся"
Истинно положительные (TP): {cm[1, 1]} - правильно предсказали "уходит"
""")
Интерпретация результатов для бизнеса
- Recall = 0.72: Модель находит 72% клиентов, которые действительно уходят
- Precision = 0.65: Из всех предсказанных "уходящих" клиентов, 65% действительно уходят
- ROC-AUC = 0.81: Хороший разделитель между классами
Deployment и мониторинг
import joblib
# Сохранение модели
joblib.dump(gb, "churn_model.pkl")
joblib.dump(scaler, "scaler.pkl")
# Использование в production
def predict_churn(customer_data):
X_scaled = scaler.transform(customer_data)
churn_probability = gb.predict_proba(X_scaled)[0, 1]
return {
"churn_risk": churn_probability,
"action": "outreach" if churn_probability > 0.4 else "monitor"
}
Этот проект демонстрирует полный цикл бинарной классификации — от постановки задачи до deployment в production, с учётом реальных вызовов как дисбаланс классов и необходимость объяснимости результатов для бизнеса.