Логистическая регрессия (Logistic Regression)
Логистическая регрессия — это статистический метод классификации, используемый для предсказания вероятности принадлежности объекта к определённому классу. Несмотря на название «регрессия», алгоритм применяется для решения задач бинарной и многоклассовой классификации.
Подробное описание
Постановка задачи: Даны обучающие данные с признаками \(X\) и соответствующими им метками классов \(y\). Необходимо построить модель, которая по новым данным \(X_{new}\) предсказывает вероятность принадлежности к каждому из классов.
Входные данные:
- Матрица признаков \(X\) размером \(n \times m\), где \(n\) — количество объектов, \(m\) — количество признаков.
- Вектор целевых переменных \(y\) длиной \(n\), содержащий метки классов (например, 0 или 1 для бинарной классификации).
Выходные данные:
- Вероятность принадлежности объекта к каждому классу.
- Предсказанный класс (на основе порога вероятности, обычно 0.5).
Ключевая идея: Вместо прямого предсказания класса, логистическая регрессия моделирует вероятность того, что объект принадлежит к определённому классу, используя сигмоидную функцию (для бинарной классификации) или softmax-функцию (для многоклассовой). Эта вероятность затем преобразуется в конкретный класс.
Исторический контекст: Логистическая регрессия была разработана в 1958 году Дэвидом Коксом и стала одним из первых методов машинного обучения, широко применяемых в медицине, экономике и социальных науках.
Основные принципы
Математическая формулировка
Для бинарной классификации используется сигмоидная функция:
Где:
- \(z = w^T X + b\) — линейная комбинация признаков
- \(w\) — вектор весов модели
- \(b\) — смещение (bias)
- \(\sigma(z)\) — сигмоидная функция, отображающая любое вещественное число в интервал \((0, 1)\)
Функция потерь (логарифмическая правдоподобие):
Где:
- \(\hat{y}_i = \sigma(w^T x_i + b)\) — предсказанная вероятность для i-го объекта
- \(y_i\) — истинная метка класса для i-го объекта
Оптимизация выполняется методом градиентного спуска или его вариантами (SGD, Adam и др.).
flowchart TD
A[Входные данные X, y] --> B[Инициализация весов w и смещения b]
B --> C[Вычисление z = w^T * X + b]
C --> D[Применение сигмоидной функции P = 1 / (1 + exp(-z))]
D --> E[Расчёт функции потерь L]
E --> F{Сходимость?}
F -->|Нет| G[Обновление весов через градиентный спуск]
G --> C
F -->|Да| H[Возврат обученной модели]
Пример реализации на Python
import numpy as np
from typing import Tuple
class LogisticRegression:
"""Реализация логистической регрессии для бинарной классификации."""
def __init__(self, learning_rate: float = 0.01, n_iterations: int = 1000):
"""
Инициализация модели.
Args:
learning_rate: Скорость обучения
n_iterations: Количество итераций градиентного спуска
"""
self.learning_rate = learning_rate
self.n_iterations = n_iterations
self.weights = None
self.bias = None
def _sigmoid(self, z: np.ndarray) -> np.ndarray:
"""
Сигмоидная функция.
Args:
z: Линейная комбинация признаков
Returns:
Вероятности в диапазоне (0, 1)
"""
# Ограничиваем значения для предотвращения overflow
z = np.clip(z, -500, 500)
return 1 / (1 + np.exp(-z))
def fit(self, X: np.ndarray, y: np.ndarray) -> None:
"""
Обучение модели.
Args:
X: Матрица признаков размером (n_samples, n_features)
y: Вектор меток классов размером (n_samples,)
"""
n_samples, n_features = X.shape
# Инициализация весов нулями
self.weights = np.zeros(n_features)
self.bias = 0
# Градиентный спуск
for _ in range(self.n_iterations):
# Вычисление линейной комбинации
linear_model = np.dot(X, self.weights) + self.bias
# Применение сигмоидной функции
predictions = self._sigmoid(linear_model)
# Вычисление градиентов
dw = (1 / n_samples) * np.dot(X.T, (predictions - y))
db = (1 / n_samples) * np.sum(predictions - y)
# Обновление весов
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
def predict_proba(self, X: np.ndarray) -> np.ndarray:
"""
Предсказание вероятностей.
Args:
X: Матрица признаков
Returns:
Вероятности принадлежности к классу 1
"""
linear_model = np.dot(X, self.weights) + self.bias
return self._sigmoid(linear_model)
def predict(self, X: np.ndarray, threshold: float = 0.5) -> np.ndarray:
"""
Предсказание классов.
Args:
X: Матрица признаков
threshold: Порог для классификации
Returns:
Предсказанные метки классов (0 или 1)
"""
probabilities = self.predict_proba(X)
return (probabilities >= threshold).astype(int)
if __name__ == "__main__":
# Пример использования
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# Генерация синтетических данных
X, y = make_classification(
n_samples=1000,
n_features=20,
n_informative=15,
n_redundant=5,
random_state=42
)
# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Создание и обучение модели
model = LogisticRegression(learning_rate=0.1, n_iterations=1000)
model.fit(X_train, y_train)
# Предсказания
y_pred = model.predict(X_test)
# Оценка точности
accuracy = accuracy_score(y_test, y_pred)
print(f"Точность модели: {accuracy:.4f}")
# Пример предсказания для одного объекта
sample = X_test[0].reshape(1, -1)
probability = model.predict_proba(sample)[0]
predicted_class = model.predict(sample)[0]
print(f"Вероятность класса 1: {probability:.4f}")
print(f"Предсказанный класс: {predicted_class}")
Достоинства и недостатки
Достоинства:
- Интерпретируемость — веса модели показывают важность каждого признака, что позволяет понять влияние факторов на результат.
- Вычислительная эффективность — алгоритм быстро обучается даже на больших наборах данных благодаря простой математической структуре.
- Хорошая работа с линейно разделимыми данными — показывает отличные результаты, когда классы можно разделить гиперплоскостью.
- Вероятностный вывод — предоставляет не только класс, но и уверенность предсказания в виде вероятности.
Недостатки:
- Линейность границы решений — не может эффективно работать с данными, требующими нелинейной границы разделения без предварительного создания полиномиальных признаков.
- Чувствительность к выбросам — экстремальные значения могут значительно искажать веса модели.
- Предположение о независимости признаков — сильно коррелированные признаки могут ухудшить качество модели.
- Проблемы с несбалансированными данными — требует дополнительных техник (взвешивание классов, oversampling) при сильном дисбалансе классов.
Области применения
- Медицина (диагностика заболеваний на основе симптомов и анализов, прогнозирование риска развития болезней)
- Экономика и финансы (оценка кредитоспособности клиентов, обнаружение мошеннических транзакций, прогнозирование дефолтов)
- Маркетинг (прогнозирование оттока клиентов, определение вероятности покупки товара, таргетированная реклама)
- Обработка текста (классификация спама, анализ тональности отзывов, категоризация документов)