← Назад к вопросам

Приведи пример задачи с бинарной классификацией

1.0 Junior🔥 231 комментариев
#Машинное обучение#Опыт и проекты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример: Прогнозирование оттока клиентов (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, с учётом реальных вызовов как дисбаланс классов и необходимость объяснимости результатов для бизнеса.

Приведи пример задачи с бинарной классификацией | PrepBro