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

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

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

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

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

Регрессионный анализ — фундамент мира машинного обучения, который превращает хаос данных в прогнозируемые модели. Пока одни специалисты спорят о сложных нейросетях, опытные аналитики знают: грамотно настроенная регрессия часто превосходит "модные" алгоритмы по скорости и эффективности. Python делает эти мощные инструменты доступными каждому, кто готов погрузиться в код. В этом руководстве я разберу не только теорию, но и практические нюансы, которые не найти в официальной документации — от подготовки данных до тонкой настройки гиперпараметров. 🔍

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

Теоретические основы регрессионного анализа в Python

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

Линейная регрессия моделирует линейную зависимость между входными данными и выходными значениями. Математически это выражается формулой:

y = β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ + ε

где:

  • y — зависимая переменная (целевая)
  • x₁, x₂, ..., xₙ — независимые переменные (предикторы)
  • β₀ — свободный член (пересечение с осью y)
  • β₁, β₂, ..., βₙ — коэффициенты регрессии, показывающие вклад каждого предиктора
  • ε — ошибка модели (остатки)

Логистическая регрессия, вопреки названию, решает задачи классификации, а не регрессии. Она моделирует вероятность принадлежности к определённому классу через сигмоидную функцию:

P(y=1|x) = 1 / (1 + e^-(β₀ + β₁x₁ + β₂x₂ + ... + βₙxₙ))

Ключевые различия между двумя типами регрессий представлены в таблице:

ХарактеристикаЛинейная регрессияЛогистическая регрессия
Тип задачиРегрессия (предсказание числовых значений)Классификация (предсказание вероятностей классов)
Целевая переменнаяНепрерывнаяКатегориальная (обычно бинарная 0/1)
Функция активацииОтсутствует (линейная функция)Сигмоидная функция
Метод оценкиМетод наименьших квадратовМаксимальное правдоподобие
Диапазон прогноза(-∞, +∞)[0, 1]

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

Для логистической регрессии ключевые допущения: линейность логита (логарифма шансов), отсутствие мультиколлинеарности и независимость наблюдений. 📊

Алексей Петров, старший аналитик данных Когда я только начинал работать с прогнозированием продаж, я потратил недели на сложные модели глубокого обучения. Результаты были нестабильными, а код разрастался до неприличных размеров. В отчаянии я вернулся к простой линейной регрессии, доработанной специфичными для нашего рынка предикторами. К моему удивлению, эта модель снизила среднюю ошибку прогноза на 23%. Руководство было в восторге, а я получил важный урок: иногда самое эффективное решение — самое простое. Линейная регрессия остаётся основой нашей системы прогнозирования уже третий год, и мы лишь периодически обновляем коэффициенты.

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

Основные библиотеки Python для реализации регрессии

Python предлагает обширный набор библиотек для реализации и анализа регрессионных моделей. Каждая из них обладает своими преимуществами и особенностями применения.

  • NumPy — фундаментальная библиотека для научных вычислений, предоставляет поддержку многомерных массивов и матричных операций, необходимых при работе с данными.
  • Pandas — незаменим для обработки и манипуляции табличными данными, позволяет эффективно подготавливать данные для регрессионных моделей.
  • Scikit-learn — главная библиотека машинного обучения, предлагающая единообразный API для различных алгоритмов, включая линейную и логистическую регрессию.
  • Statsmodels — ориентирована на статистические модели и предоставляет расширенную статистическую информацию о регрессионных моделях.
  • Matplotlib и Seaborn — визуализация данных и результатов моделирования.

Для базового импорта этих библиотек используйте следующий код:

Python
Скопировать код
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score, accuracy_score
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm

Рассмотрим ключевые функциональные возможности двух основных библиотек для регрессионного анализа:

ВозможностьScikit-learnStatsmodels
Основной фокусМашинное обучение, предсказанияСтатистический анализ, проверка гипотез
Константа (интерсепт)Добавляется автоматическиТребуется явное добавление
Статистические показателиОграниченный наборПодробный вывод (p-значения, доверительные интервалы)
Cross-validationВстроенная поддержкаТребует дополнительной реализации
ПрепроцессингОбширные возможности (Pipeline API)Базовые функции
Гиперпараметров оптимизацияGridSearchCV, RandomizedSearchCVОтсутствует

Scikit-learn оптимизирован для машинного обучения и предсказательных задач, обеспечивая единообразный интерфейс для множества моделей. Для линейной регрессии используется класс LinearRegression, а для логистической — LogisticRegression.

Statsmodels делает упор на статистический анализ, предоставляя подробную информацию о модели, включая p-значения, доверительные интервалы и диагностику модели. Эта библиотека особенно ценна, когда требуется глубокое понимание взаимосвязей в данных. 🧮

Построение и обучение линейной регрессии в Python

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

Начнем с загрузки и подготовки данных для обучения модели:

Python
Скопировать код
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
import numpy as np

# Загрузка данных (пример с набором данных о ценах на жилье)
data = pd.read_csv('housing_data.csv')

# Базовая очистка данных
data = data.dropna() # Удаление строк с пропущенными значениями

# Выбор признаков и целевой переменной
X = data[['area', 'bedrooms', 'age', 'bathrooms']]
y = data['price']

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

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

Python
Скопировать код
# Создание и обучение модели
model = LinearRegression()
model.fit(X_train, y_train)

# Получение коэффициентов модели
print(f"Коэффициент(ы): {model.coef_}")
print(f"Свободный член: {model.intercept_}")

# Предсказание значений
y_pred = model.predict(X_test)

# Оценка качества модели
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Среднеквадратичная ошибка: {mse}")
print(f"Коэффициент детерминации (R²): {r2}")

Для более глубокого статистического анализа полезно использовать Statsmodels:

Python
Скопировать код
import statsmodels.api as sm

# Добавление константы (свободного члена) к матрице признаков
X_train_sm = sm.add_constant(X_train)
X_test_sm = sm.add_constant(X_test)

# Создание и обучение модели
model_sm = sm.OLS(y_train, X_train_sm).fit()

# Вывод подробной информации о модели
print(model_sm.summary())

Визуализация результатов помогает лучше понять модель:

Python
Скопировать код
# Визуализация предсказаний относительно реальных значений
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--')
plt.xlabel('Фактические значения')
plt.ylabel('Предсказанные значения')
plt.title('Предсказание vs. Реальность')
plt.show()

# Визуализация остатков
residuals = y_test – y_pred
plt.figure(figsize=(10, 6))
plt.scatter(y_pred, residuals, alpha=0.5)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('Предсказанные значения')
plt.ylabel('Остатки')
plt.title('Распределение остатков')
plt.show()

Типичные проблемы при построении линейной регрессии и способы их решения:

  • Мультиколлинеарность — проверяйте коэффициенты VIF (Variance Inflation Factor) и используйте методы регуляризации (Ridge, Lasso).
  • Выбросы — применяйте робастную регрессию или идентифицируйте и обрабатывайте выбросы.
  • Нелинейные зависимости — используйте полиномиальные признаки или трансформации данных.
  • Гетероскедастичность — применяйте взвешенную регрессию или логарифмические преобразования.

Мария Соколова, data scientist В проекте по прогнозированию страховых выплат мы столкнулись с неожиданной проблемой: модель линейной регрессии в scikit-learn давала совершенно другие коэффициенты по сравнению с той же моделью в Statsmodels. После нескольких дней отладки оказалось, что данные содержали мультиколлинеарные признаки, и разные библиотеки по-разному обрабатывали эту проблему. Мы решили вопрос, применив метод главных компонент (PCA) для снижения размерности, что не только устранило мультиколлинеарность, но и повысило стабильность модели на 18%. Особенно запомнился момент, когда бизнес-заказчик благодаря нашей модели обнаружил неэффективность в процессе андеррайтинга, что привело к пересмотру всей тарифной политики компании.

Создание моделей логистической регрессии на Python

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

Начнем с подготовки данных для классификационной задачи:

Python
Скопировать код
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, roc_auc_score, roc_curve
import matplotlib.pyplot as plt
import numpy as np

# Загрузка данных (например, предсказание наличия заболевания)
data = pd.read_csv('diabetes.csv')

# Подготовка данных
X = data.drop('Outcome', axis=1) # Признаки
y = data['Outcome'] # Целевая переменная (0 или 1)

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

# Стандартизация признаков (важно для логистической регрессии)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

Теперь обучим модель логистической регрессии и оценим её эффективность:

Python
Скопировать код
# Создание и обучение модели логистической регрессии
model = LogisticRegression(C=1.0, solver='liblinear', random_state=42)
model.fit(X_train_scaled, y_train)

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

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

# Детальный отчёт о качестве классификации
print("\nОтчёт о классификации:")
print(classification_report(y_test, y_pred))

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

# ROC-кривая и значение AUC
roc_auc = roc_auc_score(y_test, y_pred_proba)
print(f"\nROC AUC: {roc_auc:.4f}")

# Построение 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:.4f})')
plt.plot([0, 1], [0, 1], 'k--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC-кривая логистической регрессии')
plt.legend(loc='lower right')
plt.show()

# Получение и анализ коэффициентов модели
coefficients = pd.DataFrame({
'Признак': X.columns,
'Коэффициент': model.coef_[0]
})
coefficients = coefficients.sort_values(by='Коэффициент', ascending=False)
print("\nКоэффициенты модели:")
print(coefficients)

Для мультиклассовой логистической регрессии изменения минимальны:

Python
Скопировать код
# Для многоклассовой задачи
model_multi = LogisticRegression(
C=1.0, 
solver='lbfgs', # lbfgs хорошо работает с многоклассовой классификацией
multi_class='multinomial',
max_iter=1000,
random_state=42
)
# Далее обучение и оценка аналогичны бинарному случаю

Важные параметры логистической регрессии, требующие настройки:

  • C — обратный параметр регуляризации; меньшие значения усиливают регуляризацию
  • solver — алгоритм оптимизации ('liblinear', 'lbfgs', 'newton-cg', 'sag', 'saga')
  • penalty — тип регуляризации ('l1', 'l2', 'elasticnet', 'none')
  • class_weight — веса классов для несбалансированных данных
  • max_iter — максимальное количество итераций для конвергенции алгоритма

Интерпретация коэффициентов логистической регрессии имеет некоторые особенности. В отличие от линейной регрессии, они отражают изменение в логарифме шансов (log odds), а не в самой целевой переменной:

$$\log\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + ... + \beta_n x_n$$

Для более понятной интерпретации можно преобразовать коэффициенты в отношения шансов (odds ratios):

Python
Скопировать код
# Преобразование коэффициентов в отношения шансов
odds_ratios = pd.DataFrame({
'Признак': X.columns,
'Коэффициент': model.coef_[0],
'Отношение шансов': np.exp(model.coef_[0])
})
odds_ratios = odds_ratios.sort_values(by='Отношение шансов', ascending=False)
print("\nОтношения шансов:")
print(odds_ratios)

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

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

Оценка и оптимизация регрессионных моделей в Python

После построения регрессионных моделей критически важно правильно оценить их качество и при необходимости оптимизировать. В этом разделе рассмотрим основные метрики оценки, методы перекрестной проверки и техники оптимизации гиперпараметров. 🎯

Начнем с ключевых метрик для оценки моделей:

Тип моделиМетрикаОписаниеИнтерпретация
Линейная регрессияMAE (Mean Absolute Error)Средняя абсолютная ошибкаМеньше — лучше; единицы измерения совпадают с целевой переменной
MSE (Mean Squared Error)Средняя квадратичная ошибкаМеньше — лучше; чувствительна к выбросам
RMSE (Root Mean Squared Error)Корень из средней квадратичной ошибкиМеньше — лучше; единицы измерения совпадают с целевой переменной
R² (Коэффициент детерминации)Доля объясненной дисперсииБлиже к 1 — лучше; может быть отрицательным при плохой модели
Логистическая регрессияAccuracy (Точность)Доля правильных предсказанийБлиже к 1 — лучше; проблематична для несбалансированных классов
Precision (Точность)Доля истинно положительных среди всех положительных предсказанийБлиже к 1 — лучше; важна, когда дорого ошибиться "в положительную сторону"
Recall (Полнота)Доля найденных положительных объектовБлиже к 1 — лучше; важна, когда нельзя пропускать положительные объекты
F1-scoreГармоническое среднее precision и recallБлиже к 1 — лучше; сбалансированная метрика
AUC-ROCПлощадь под ROC-кривойБлиже к 1 — лучше; устойчива к несбалансированным классам

Для надежной оценки моделей следует использовать перекрестную проверку (cross-validation):

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

# Для линейной регрессии
cv = KFold(n_splits=5, shuffle=True, random_state=42)
cv_scores = cross_val_score(
LinearRegression(),
X_scaled,
y,
cv=cv,
scoring='neg_mean_squared_error'
)

# Преобразование отрицательных MSE в положительные RMSE
rmse_scores = np.sqrt(-cv_scores)
print(f"Средний RMSE при кросс-валидации: {rmse_scores.mean():.4f}")
print(f"Стандартное отклонение RMSE: {rmse_scores.std():.4f}")

# Для логистической регрессии
cv_scores_logreg = cross_val_score(
LogisticRegression(),
X_scaled,
y,
cv=cv,
scoring='roc_auc'
)
print(f"Средний AUC-ROC при кросс-валидации: {cv_scores_logreg.mean():.4f}")
print(f"Стандартное отклонение AUC-ROC: {cv_scores_logreg.std():.4f}")

Оптимизация гиперпараметров поможет улучшить модель. Для этого используются методы Grid Search и Random Search:

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

# Для линейной регрессии (например, Ridge с регуляризацией)
from sklearn.linear_model import Ridge

# Определение параметров для поиска
param_grid = {
'alpha': [0\.001, 0.01, 0.1, 1.0, 10.0, 100.0],
'solver': ['auto', 'svd', 'cholesky', 'lsqr', 'sparse_cg']
}

# Инициализация GridSearchCV
grid_search = GridSearchCV(
Ridge(),
param_grid,
cv=5,
scoring='neg_mean_squared_error',
n_jobs=-1, # Использовать все доступные ядра процессора
verbose=1
)

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

# Вывод лучших параметров и результатов
print(f"Лучшие параметры: {grid_search.best_params_}")
print(f"Лучший RMSE: {np.sqrt(-grid_search.best_score_):.4f}")

# Для логистической регрессии
param_grid_logreg = {
'C': [0\.001, 0.01, 0.1, 1, 10, 100],
'penalty': ['l1', 'l2', 'elasticnet', 'none'],
'solver': ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']
}

# RandomizedSearchCV может быть эффективнее при большом пространстве параметров
random_search = RandomizedSearchCV(
LogisticRegression(max_iter=1000),
param_distributions=param_grid_logreg,
n_iter=20, # Количество случайных комбинаций для проверки
cv=5,
scoring='roc_auc',
n_jobs=-1,
random_state=42,
verbose=1
)

random_search.fit(X_train_scaled, y_train)
print(f"Лучшие параметры: {random_search.best_params_}")
print(f"Лучший AUC-ROC: {random_search.best_score_:.4f}")

Для борьбы с переобучением рекомендуется применять регуляризацию. В линейной регрессии используют Ridge (L2), Lasso (L1) или ElasticNet (комбинация L1 и L2):

Python
Скопировать код
from sklearn.linear_model import Ridge, Lasso, ElasticNet

# Ridge (L2 регуляризация)
ridge_model = Ridge(alpha=1.0)
ridge_model.fit(X_train_scaled, y_train)

# Lasso (L1 регуляризация)
lasso_model = Lasso(alpha=0.1)
lasso_model.fit(X_train_scaled, y_train)

# ElasticNet (L1 + L2)
elastic_model = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic_model.fit(X_train_scaled, y_train)

# Сравнение моделей
models = {
'Ridge': ridge_model,
'Lasso': lasso_model,
'ElasticNet': elastic_model
}

for name, model in models.items():
y_pred = model.predict(X_test_scaled)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
r2 = r2_score(y_test, y_pred)
print(f"{name}: RMSE = {rmse:.4f}, R² = {r2:.4f}")

Дополнительные советы по оптимизации регрессионных моделей:

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

Помните, что излишняя сложность модели может привести к переобучению. Стремитесь к балансу между сложностью модели и её обобщающей способностью, используя метрики на валидационной выборке. 💡

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

Регрессионные модели — это не просто математические формулы, а мощные инструменты аналитики, способные находить скрытые закономерности в данных. Освоив линейную и логистическую регрессию в Python, вы получаете возможность превращать хаотичные массивы цифр в точные прогнозы и обоснованные решения. Главное помнить, что сила этих моделей заключается не в их сложности, а в тщательной подготовке данных, продуманном выборе признаков и грамотной интерпретации результатов. В конечном счете, хорошая регрессионная модель — это баланс между точностью, простотой и способностью объяснять реальные процессы.