Логистическая регрессия в Python: пошаговое руководство для анализа

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Для кого эта статья:

  • аналитики данных и специалисты по машинному обучению
  • студенты и обучающиеся в сфере analytics и программирования на Python
  • менеджеры и руководители, заинтересованные в применении аналитики для принятия бизнес-решений

Логистическая регрессия — один из самых мощных инструментов в арсенале аналитика данных для решения задач классификации. Удивительно, но за свою кажущуюся простоту этот метод способен давать результаты, сопоставимые с более сложными алгоритмами! Хотите с минимальными затратами создать предиктивную модель, которая определит, откажется ли клиент от подписки или выявит потенциально мошеннические транзакции? Логистическая регрессия в Python — ваш надежный помощник, требующий всего лишь правильного подхода к реализации. Давайте разберемся, как создать такую модель от А до Я. 🚀

Чтобы в совершенстве овладеть не только логистической регрессией, но и другими мощными инструментами анализа данных, Курс «Аналитик данных» с нуля от Skypro станет вашим проводником в мир Python-аналитики. Программа построена так, что вы переходите от теории к практике уже в первые недели обучения — уверенно применяя логистическую регрессию для решения реальных бизнес-задач, оптимизируя модели и повышая их точность до впечатляющих результатов.

Основы логистической регрессии для задач классификации

Логистическая регрессия, несмотря на слово "регрессия" в названии, является методом классификации и служит фундаментальным инструментом машинного обучения для решения бинарных задач предсказания. В отличие от линейной регрессии, которая прогнозирует непрерывные значения, логистическая регрессия оценивает вероятность принадлежности наблюдения к определенному классу. 📊

Ключевым элементом логистической регрессии выступает сигмоидная функция (или логистическая функция), которая преобразует любое действительное число в значение от 0 до 1:

P(y=1) = 1 / (1 + e^(-z))
где z = b0 + b1*x1 + b2*x2 + ... + bn*xn

Эта функция уникально трансформирует линейную комбинацию входных переменных в вероятность. Если полученное значение выше заданного порога (обычно 0.5), наблюдение классифицируется как положительное, иначе — как отрицательное.

Основные преимущества логистической регрессии:

  • Интерпретируемость — коэффициенты модели имеют ясное вероятностное толкование
  • Эффективность — меньшая вычислительная мощность по сравнению со сложными алгоритмами
  • Устойчивость — низкая склонность к переобучению при правильной регуляризации
  • Вероятностный характер — предоставляет не просто метки классов, но и вероятности принадлежности

Логистическая регрессия особенно эффективна, когда отношение между входными и выходными переменными примерно линейное, и для преодоления нелинейности можно вводить полиномиальные признаки.

ЗадачаПрименение логистической регрессииТипичная точность
Кредитный скорингОпределение вероятности дефолта заемщика75-85%
Медицинская диагностикаПрогнозирование наличия заболевания70-90%
МаркетингПредсказание отклика на рекламу65-80%
Обнаружение мошенничестваВыявление подозрительных транзакций80-95%

Михаил Новиков, ведущий аналитик данных.

Когда я только начинал работу в сфере кредитного скоринга, наша команда столкнулась с критической проблемой — существующая модель оценки заёмщиков выдавала слишком много ложноположительных результатов. Банк терял деньги, одобряя кредиты ненадежным клиентам.

Проанализировав ситуацию, я предложил пересмотреть подход и внедрить логистическую регрессию, несмотря на скептицизм коллег, предпочитавших сложные ансамблевые методы. Мы собрали исторические данные о клиентах за три года, включая их поведенческие характеристики, кредитную историю и финансовые показатели.

После очистки и преобразования данных я реализовал модель логистической регрессии с тщательно подобранной L2-регуляризацией. Удивительно, но наша "простая" модель обошла предыдущую по метрике ROC AUC на 7 процентных пунктов! Ключевым преимуществом оказалась не только точность, но и прозрачность — теперь мы могли четко объяснить, почему конкретному клиенту отказано в кредите. За первые шесть месяцев работы новой системы банк сократил убытки от невозвратов на 23%.

Кинга Идем в IT: пошаговый план для смены профессии

Подготовка и предобработка данных для модели

Качество предобработки данных определяет до 80% успеха модели логистической регрессии. Тщательный предварительный анализ и трансформация исходного набора данных критически важны для построения эффективной модели. 🧹

Ключевые этапы подготовки данных:

  1. Исследовательский анализ – перед началом моделирования необходимо исследовать распределения переменных, выявить выбросы и понять структуру данных
  2. Обработка пропущенных значений – логистическая регрессия требует полных данных, поэтому пропуски необходимо заполнить или удалить соответствующие наблюдения
  3. Кодирование категориальных переменных – преобразование текстовых переменных в числовой формат через one-hot encoding или label encoding
  4. Масштабирование числовых признаков – приведение числовых переменных к единой шкале через стандартизацию или нормализацию
  5. Работа с несбалансированными классами – применение методов ресэмплинга для уравновешивания классов

Рассмотрим пример базовой предобработки данных в Python:

Python
Скопировать код
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer

# Загрузка данных
data = pd.read_csv('customer_data.csv')

# Разделение на признаки и целевую переменную
X = data.drop('churn', axis=1)
y = data['churn']

# Определение числовых и категориальных признаков
numeric_features = X.select_dtypes(include=['int64', 'float64']).columns
categorical_features = X.select_dtypes(include=['object']).columns

# Создание преобразователей для разных типов данных
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())])

categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))])

# Объединение преобразователей
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)])

# Разделение на тренировочную и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Применение преобразований
X_train_processed = preprocessor.fit_transform(X_train)
X_test_processed = preprocessor.transform(X_test)

Важно отметить, что логистическая регрессия весьма чувствительна к выбросам и мультиколлинеарности. Рекомендуется:

  • Проверять корреляцию между признаками и удалять сильно коррелированные
  • Применять методы регуляризации (L1 или L2) для снижения влияния выбросов
  • Использовать методы отбора признаков для уменьшения размерности данных

Для улучшения качества модели также рекомендуется создавать новые признаки (feature engineering), которые могут лучше отражать взаимосвязи в данных и повышать предсказательную способность модели.

Реализация логистической регрессии в Python с scikit-learn

Реализация логистической регрессии в Python с использованием библиотеки scikit-learn представляет собой элегантный процесс, требующий минимального объема кода для получения мощной классификационной модели. Библиотека sklearn обеспечивает гибкий и эффективный инструментарий для создания, обучения и оценки логистической регрессии. 💻

Базовая реализация логистической регрессии выглядит следующим образом:

Python
Скопировать код
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# Создание и обучение модели логистической регрессии
model = LogisticRegression(C=1.0, penalty='l2', solver='lbfgs', max_iter=1000, random_state=42)
model.fit(X_train_processed, y_train)

# Предсказание на тестовой выборке
y_pred = model.predict(X_test_processed)
y_pred_proba = model.predict_proba(X_test_processed)[:, 1]

# Оценка точности модели
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.4f}')

# Детальный отчет о производительности
print("\nClassification Report:")
print(classification_report(y_test, y_pred))

# Матрица ошибок
print("\nConfusion Matrix:")
print(confusion_matrix(y_test, y_pred))

При использовании логистической регрессии в scikit-learn существует несколько важных гиперпараметров, которые следует настроить для оптимальной производительности:

ПараметрОписаниеРекомендуемые значения
penaltyТип регуляризации'l1', 'l2', 'elasticnet', 'none'
CОбратная сила регуляризации0.001, 0.01, 0.1, 1, 10, 100
solverАлгоритм оптимизации'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'
max_iterМаксимальное число итераций100, 500, 1000, 2000
class_weightВеса классов'balanced', None, словарь весов

Для выбора оптимальных гиперпараметров рекомендуется использовать поиск по решетке (GridSearchCV) или случайный поиск (RandomizedSearchCV):

Python
Скопировать код
from sklearn.model_selection import GridSearchCV

# Определение параметров для поиска
param_grid = {
'C': [0\.01, 0.1, 1, 10, 100],
'penalty': ['l1', 'l2'],
'solver': ['liblinear', 'saga']
}

# Создание объекта GridSearchCV
grid_search = GridSearchCV(
estimator=LogisticRegression(random_state=42),
param_grid=param_grid,
cv=5,
scoring='roc_auc',
n_jobs=-1
)

# Обучение и поиск лучших параметров
grid_search.fit(X_train_processed, y_train)

# Вывод лучших параметров
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best cross-validation score: {grid_search.best_score_:.4f}")

# Использование лучшей модели
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test_processed)

Интерпретация модели логистической регрессии — её важное преимущество. Коэффициенты модели напрямую связаны с влиянием признаков на логарифм шансов целевого класса:

Python
Скопировать код
# Извлечение и анализ коэффициентов
feature_names = numeric_features.tolist() + list(preprocessor.named_transformers_['cat'].named_steps['onehot'].get_feature_names_out(categorical_features))
coefficients = pd.DataFrame(best_model.coef_[0], index=feature_names, columns=['Coefficient'])
coefficients = coefficients.sort_values('Coefficient', ascending=False)

print("Top positive and negative coefficients:")
print(coefficients.head(10)) # Топ положительных
print(coefficients.tail(10)) # Топ отрицательных

Для повышения производительности также можно использовать специализированные приемы, такие как:

  • Подбор оптимального порога классификации на основе бизнес-требований
  • Применение кросс-валидации для более надежной оценки модели
  • Использование различных метрик оценки в зависимости от задачи (precision, recall, F1)
  • Проведение регулярной переоценки и переобучения модели на новых данных

Оценка качества модели и интерпретация результатов

Оценка качества модели логистической регрессии — критический этап, определяющий её практическую применимость. Недостаточно просто обучить модель, необходимо тщательно проанализировать её производительность с помощью различных метрик и визуализаций. 📈

Ключевые метрики оценки логистической регрессии:

  1. Accuracy (точность) — доля правильных предсказаний среди всех предсказаний
  2. Precision (точность классификации) — доля объектов, действительно принадлежащих положительному классу, среди всех объектов, отнесенных моделью к положительному классу
  3. Recall (полнота) — доля объектов положительного класса, верно предсказанных моделью, от всех объектов положительного класса
  4. F1-score — гармоническое среднее между precision и recall
  5. ROC-кривая и AUC — графическое представление компромисса между чувствительностью и специфичностью
  6. Кривая Precision-Recall — особенно важна для несбалансированных наборов данных

Реализация основных метрик и визуализаций:

Python
Скопировать код
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve, precision_recall_curve, auc, roc_auc_score

# Создание ROC-кривой
fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)
roc_auc = auc(fpr, tpr)

plt.figure(figsize=(10, 6))
plt.plot(fpr, tpr, color='darkorange', lw=2, label=f'ROC curve (area = {roc_auc:.3f})')
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0\.0, 1.0])
plt.ylim([0\.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic (ROC) Curve')
plt.legend(loc="lower right")
plt.grid(True)
plt.show()

# Precision-Recall кривая
precision, recall, _ = precision_recall_curve(y_test, y_pred_proba)
pr_auc = auc(recall, precision)

plt.figure(figsize=(10, 6))
plt.plot(recall, precision, color='blue', lw=2, label=f'PR curve (area = {pr_auc:.3f})')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curve')
plt.legend(loc="upper right")
plt.grid(True)
plt.show()

# Калибровочная кривая
from sklearn.calibration import calibration_curve

plt.figure(figsize=(10, 6))
prob_true, prob_pred = calibration_curve(y_test, y_pred_proba, n_bins=10)
plt.plot(prob_pred, prob_true, "s-", label="LogisticRegression")
plt.plot([0, 1], [0, 1], "k:", label="Perfectly calibrated")
plt.xlabel("Mean predicted probability")
plt.ylabel("Fraction of positives")
plt.title("Calibration curve")
plt.legend(loc="lower right")
plt.grid(True)
plt.show()

Анна Соколова, руководитель направления аналитики данных.

Наш e-commerce проект переживал сложный период — конверсия падала, а затраты на привлечение клиентов росли. Маркетинговый бюджет распределялся неэффективно, поскольку мы не могли точно предсказать, кто из посетителей сайта совершит покупку.

Я решила построить модель логистической регрессии на основе данных о поведении пользователей на сайте. Мы собрали информацию о 100,000 сессий, включая время на сайте, количество просмотренных страниц, источник трафика, демографические данные и историю прошлых покупок.

После обучения базовой модели мы получили AUC-ROC около 0.76, что уже было неплохо, но недостаточно для наших целей. Я заметила, что калибровочная кривая показывала существенные отклонения от идеальной — модель переоценивала вероятность конверсии для низкоконверсионных посетителей.

Мы применили технику калибровки Платта (метод логистической регрессии для калибровки вероятностей) и добавили новые признаки, описывающие взаимодействие пользователя с конкретными категориями товаров. Показатель AUC-ROC вырос до 0.83, а калибровочная кривая стала гораздо ближе к идеальной.

Внедрение этой модели позволило нам перераспределить маркетинговый бюджет, сосредоточившись на сегментах с наивысшей вероятностью конверсии. В течение квартала наша общая конверсия выросла на 27%, а стоимость привлечения клиента снизилась на 23%.

При интерпретации результатов логистической регрессии важно обратить внимание на несколько аспектов:

1. Коэффициенты модели и их значимость Коэффициенты логистической регрессии отражают изменение в логарифме шансов (log-odds) при увеличении соответствующего признака на единицу:

Python
Скопировать код
# Расчет экспонент коэффициентов для интерпретации влияния
import numpy as np

exp_coefficients = pd.DataFrame(
np.exp(best_model.coef_[0]), 
index=feature_names, 
columns=['Odds Ratio']
)
exp_coefficients = exp_coefficients.sort_values('Odds Ratio', ascending=False)

print("Top odds ratios (влияние на шансы):")
print(exp_coefficients.head(10))

2. Оценка важности признаков Для определения важности признаков можно использовать значения коэффициентов, скорректированные на стандартное отклонение признака:

Python
Скопировать код
# Расчет стандартизованных коэффициентов (влияние признаков)
from sklearn.preprocessing import scale

# Стандартизация X для расчета стандартизованных коэффициентов
X_std = scale(X_train_processed)
importances = np.abs(best_model.coef_[0] * np.std(X_std, axis=0))

feature_importance = pd.DataFrame(
{'Feature': feature_names, 'Importance': importances}
).sort_values('Importance', ascending=False)

print("Feature importance:")
print(feature_importance.head(10))

3. Анализ ошибок модели Подробный анализ ошибок может выявить паттерны, где модель работает хуже всего:

Python
Скопировать код
# Анализ ошибок предсказания
errors = X_test[y_test != y_pred].copy()
errors['true_label'] = y_test[y_test != y_pred]
errors['predicted_label'] = y_pred[y_test != y_pred]
errors['probability'] = y_pred_proba[y_test != y_pred]

print("Sample of errors:")
print(errors.head())

# Распределение ошибок по категориям (если есть категориальные признаки)
if len(categorical_features) > 0:
for feature in categorical_features:
if feature in errors.columns:
print(f"\nDistribution of errors by {feature}:")
print(errors[feature].value_counts(normalize=True))

При интерпретации результатов необходимо учитывать специфику домена и цели бизнеса. Например, в медицинской диагностике ложноотрицательные результаты (пропуск заболевания) обычно более критичны, чем ложноположительные. В таких случаях следует ориентироваться на показатель Recall, а не на общую точность.

Практические кейсы и оптимизация логистической регрессии

Реальное применение логистической регрессии требует не только понимания теоретических основ, но и практического опыта работы с различными сценариями оптимизации. Рассмотрим несколько практических кейсов и способов улучшения производительности моделей. 🛠️

Кейс 1: Прогнозирование оттока клиентов телекоммуникационной компании

Задача: Определить клиентов с высоким риском ухода для проведения превентивных маркетинговых кампаний

Python
Скопировать код
# Базовая модель для прогнозирования оттока
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, recall_score, precision_score

# Решение проблемы дисбаланса классов – часто отток составляет 10-20%
model = LogisticRegression(class_weight='balanced', C=1.0, penalty='l2', max_iter=1000)
model.fit(X_train_processed, y_train)

# Выбор оптимального порога на основе бизнес-целей
# Например, нам важнее поймать всех уходящих клиентов (высокий recall)
y_pred_proba = model.predict_proba(X_valid_processed)[:, 1]

# Поиск оптимального порога для максимизации F2-меры 
# (придаем recall в 2 раза больший вес, чем precision)
from sklearn.metrics import fbeta_score
thresholds = np.arange(0.1, 0.9, 0.05)
best_threshold = 0.5
best_f2 = 0
for threshold in thresholds:
y_pred_thresh = (y_pred_proba >= threshold).astype(int)
f2 = fbeta_score(y_valid, y_pred_thresh, beta=2)
if f2 > best_f2:
best_f2 = f2
best_threshold = threshold

print(f"Optimal threshold: {best_threshold:.2f}")
# Применение оптимального порога на тестовой выборке
y_test_pred = (model.predict_proba(X_test_processed)[:, 1] >= best_threshold).astype(int)

Кейс 2: Обнаружение мошеннических транзакций

Задача: Выявить потенциально мошеннические финансовые операции при значительном дисбалансе классов (обычно <1% транзакций мошеннические)

Python
Скопировать код
# Решение проблемы сильного дисбаланса классов
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline as ImbPipeline
from sklearn.model_selection import StratifiedKFold

# Создание пайплайна с SMOTE для балансировки обучающей выборки
pipeline = ImbPipeline([
('preprocessor', preprocessor),
('sampling', SMOTE(random_state=42)),
('classifier', LogisticRegression(penalty='l1', solver='liblinear', C=0.1, random_state=42))
])

# Кросс-валидация с сохранением соотношения классов в фолдах
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
scores = cross_val_score(pipeline, X, y, cv=cv, scoring='roc_auc')

print(f"Cross-validation ROC-AUC: {scores.mean():.4f} ± {scores.std():.4f}")

# Модель с использованием Precision-Recall AUC в качестве метрики оптимизации
# для несбалансированных данных это часто более информативно, чем ROC AUC
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer, average_precision_score

# Создание собственной метрики
pr_auc_scorer = make_scorer(average_precision_score, needs_proba=True)

# Поиск оптимальных параметров
param_grid = {
'classifier__C': [0\.01, 0.1, 1, 10, 100],
'classifier__class_weight': ['balanced', None]
}

grid_search = GridSearchCV(
estimator=pipeline,
param_grid=param_grid,
cv=cv,
scoring=pr_auc_scorer,
n_jobs=-1
)

grid_search.fit(X, y)
best_params = grid_search.best_params_
print(f"Best parameters: {best_params}")

Оптимизация логистической регрессии может осуществляться различными способами:

  • Регуляризация: выбор между L1 (Lasso) и L2 (Ridge) регуляризацией в зависимости от количества признаков и наличия мультиколлинеарности
  • Подбор гиперпараметров: систематический поиск оптимальных значений C (сила регуляризации), class_weight и др.
  • Инженерия признаков: создание взаимодействий между признаками, полиномиальных признаков для моделирования нелинейных зависимостей
  • Техники ресэмплинга: использование SMOTE, ADASYN, RandomUnderSampler для балансировки классов
  • Калибровка вероятностей: применение метода Платта или изотонической регрессии для получения более точных вероятностей

Примеры продвинутой инженерии признаков:

Python
Скопировать код
from sklearn.preprocessing import PolynomialFeatures
from sklearn.feature_selection import SelectFromModel

# Создание полиномиальных признаков
poly = PolynomialFeatures(degree=2, interaction_only=True)
X_poly = poly.fit_transform(X_train_processed)

# Обучение модели с L1-регуляризацией для отбора признаков
l1_model = LogisticRegression(C=0.1, penalty='l1', solver='liblinear')
l1_model.fit(X_poly, y_train)

# Отбор значимых признаков
selector = SelectFromModel(l1_model, prefit=True)
X_train_selected = selector.transform(X_poly)
X_test_selected = selector.transform(poly.transform(X_test_processed))

print(f"Original features: {X_poly.shape[1]}, Selected features: {X_train_selected.shape[1]}")

# Обучение финальной модели на отобранных признаках
final_model = LogisticRegression(C=1.0, penalty='l2')
final_model.fit(X_train_selected, y_train)
final_score = roc_auc_score(y_test, final_model.predict_proba(X_test_selected)[:, 1])
print(f"Final model ROC AUC: {final_score:.4f}")

Сравнение различных подходов к оптимизации:

Метод оптимизацииПреимуществаНедостаткиКогда использовать
L1-регуляризацияАвтоматический отбор признаков, разреженные моделиМожет удалить важные признакиВысокоразмерные данные, много нерелевантных признаков
L2-регуляризацияСтабильность модели, работа с коррелированными признакамиНе создает разреженные моделиМультиколлинеарность, общий случай
SMOTE/ADASYNРешение проблемы дисбаланса классовСоздание синтетических примеров может вносить шумСильный дисбаланс классов
Калибровка вероятностейТочные вероятностные оценкиТребует отдельной валидационной выборкиКогда важна точность вероятностей, а не только классификация

Интеграция логистической регрессии в промышленные системы часто требует дополнительных шагов:

  1. Сериализация модели и препроцессора для последующего использования
  2. Настройка мониторинга производительности модели на реальных данных
  3. Разработка стратегии переобучения модели при снижении её эффективности
  4. Создание API для интеграции модели с другими системами

Понять, в какую сторону развивать свои навыки в области анализа данных, чтобы достичь максимальных результатов, поможет Тест на профориентацию от Skypro. Пройдите всесторонний анализ ваших нынешних компетенций и получите персонализированную дорожную карту развития — узнайте, стоит ли углубляться в область предиктивной аналитики и логистической регрессии, или ваши таланты найдут лучшее применение в других направлениях анализа данных.

Логистическая регрессия, несмотря на свою кажущуюся простоту, остается незаменимым инструментом аналитика данных. Ее интерпретируемость, вычислительная эффективность и надежность делают ее идеальным выбором для широкого спектра задач классификации. Мастерство в применении логистической регрессии требует не только технических навыков, но и глубокого понимания предметной области, умения правильно выбирать метрики оценки и способности интерпретировать результаты в контексте бизнес-задач. Овладев материалом этого руководства, вы сможете превратить сырые данные в ценные инсайты, способные трансформировать бизнес-процессы и принимать обоснованные решения на основе данных.