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

Какие существуют методы регуляризации? Плюсы и минусы каждого?

1.8 Middle🔥 192 комментариев
#Машинное обучение

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

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

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

Методы регуляризации в машинном обучении

Регуляризация — техника предотвращения переобучения путём добавления штрафа к функции потерь за сложность модели. Цель: снизить дисперсию модели в обмен на небольшое увеличение смещения.

1. L1 регуляризация (Lasso)

Формула: Loss = MSE + λ * Σ|w|

from sklearn.linear_model import Lasso
import numpy as np

# L1 регуляризация
model = Lasso(alpha=0.1)  # lambda = alpha
model.fit(X_train, y_train)
print(f"Коэффициенты: {model.coef_}")
print(f"Количество нулевых коэффициентов: {np.sum(model.coef_ == 0)}")

Плюсы:

  • Отбор признаков: обнуляет неважные коэффициенты
  • Создает разреженные модели (sparse)
  • Интерпретируемость
  • Быстрая инфенция благодаря нулевым параметрам

Минусы:

  • Может быть нестабильна с коррелированными признаками
  • Когда признаков больше чем примеров, отбирает максимум n признаков
  • Медленнее в обучении чем Ridge
  • Может быть неустойчива при λ близкой к оптимальной

2. L2 регуляризация (Ridge)

Формула: Loss = MSE + λ * Σ(w²)

from sklearn.linear_model import Ridge

# L2 регуляризация
model = Ridge(alpha=1.0)
model.fit(X_train, y_train)
print(f"Коэффициенты: {model.coef_}")
print(f"Норма весов: {np.linalg.norm(model.coef_)}")

# Сравнение с обычной регрессией
from sklearn.linear_model import LinearRegression
model_ols = LinearRegression()
model_ols.fit(X_train, y_train)

print(f"OLS R²: {model_ols.score(X_test, y_test):.4f}")
print(f"Ridge R²: {model.score(X_test, y_test):.4f}")

Плюсы:

  • Стабильна с коррелированными признаками
  • Быстрое обучение (закрытое решение)
  • Не обнуляет коэффициенты, сохраняет все признаки
  • Гладкая функция потерь

Минусы:

  • Не выполняет отбор признаков
  • Менее интерпретируема (много малых коэффициентов)
  • Может быть чувствительна к масштабу признаков

3. ElasticNet (комбинация L1 и L2)

Формула: Loss = MSE + λ1Σ|w| + λ2Σ(w²)

from sklearn.linear_model import ElasticNet

# Комбинирует L1 и L2
model = ElasticNet(alpha=0.1, l1_ratio=0.5)  # 50% L1, 50% L2
model.fit(X_train, y_train)
print(f"Коэффициенты: {model.coef_}")
print(f"Количество нулевых коэффициентов: {np.sum(model.coef_ == 0)}")

Плюсы:

  • Отбор признаков (как L1) + стабильность (как L2)
  • Эффективен с коррелированными группами признаков
  • Более гибкий компромисс между L1 и L2

Минусы:

  • Больше гиперпараметров для настройки (α и l1_ratio)
  • Может быть медленнее обучаться
  • Сложнее интерпретировать

4. Dropout (для нейросетей)

Идея: случайно удаляем нейроны во время обучения

import torch
import torch.nn as nn

class DropoutNet(nn.Module):
    def __init__(self, input_dim, hidden_dim, dropout_rate=0.5):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.dropout = nn.Dropout(dropout_rate)  # Удаляет 50% нейронов
        self.fc2 = nn.Linear(hidden_dim, 1)
    
    def forward(self, x):
        x = torch.relu(self.fc1(x))
        x = self.dropout(x)  # Применяем только во время обучения
        x = self.fc2(x)
        return x

model = DropoutNet(10, 64, dropout_rate=0.5)
model.train()  # Включаем dropout

Плюсы:

  • Очень эффективен для глубоких сетей
  • Теоретически эквивалентен ансамблю
  • Просто реализуется
  • Работает во многих архитектурах

Минусы:

  • Увеличивает время обучения
  • Требует больше эпох для сходимости
  • Не применяется при инфиренции (хитрость с масштабированием)
  • Требует подбора rate

5. Batch Normalization

Идея: нормализуем входы каждого слоя

class BatchNormNet(nn.Module):
    def __init__(self, input_dim, hidden_dim):
        super().__init__()
        self.fc1 = nn.Linear(input_dim, hidden_dim)
        self.bn1 = nn.BatchNorm1d(hidden_dim)  # Нормализуем
        self.fc2 = nn.Linear(hidden_dim, 1)
    
    def forward(self, x):
        x = self.fc1(x)
        x = self.bn1(x)  # После активации
        x = torch.relu(x)
        x = self.fc2(x)
        return x

Плюсы:

  • Уменьшает internal covariate shift
  • Позволяет использовать более высокие learning rate
  • Имеет регуляризирующий эффект
  • Ускоряет сходимость

Минусы:

  • Разное поведение в train vs test (требует режимов)
  • На малых batch размерах шумная оценка
  • Добавляет вычислительные затраты
  • Сложнее отлаживать

6. Early Stopping

Идея: остановить обучение, когда validation ошибка начинает расти

from sklearn.ensemble import GradientBoostingRegressor

model = GradientBoostingRegressor(n_estimators=1000, validation_fraction=0.1,
                                   n_iter_no_change=10)  # Early stopping
model.fit(X_train, y_train)
print(f"Обучено деревьев: {model.n_estimators_}")

Плюсы:

  • Простая в реализации
  • Эффективна для градиентных методов
  • Не требует гиперпараметра λ
  • Останавливает обучение вовремя

Минусы:

  • Требует validation набора (потеря данных обучения)
  • Случайный в выборе точки остановки
  • Может быть чувствительна к noise в validation ошибке

7. Weight Decay / L2 норма в нейросетях

import torch.optim as optim

# L2 регуляризация в оптимизаторе
optimizer = optim.Adam(model.parameters(), lr=0.001, weight_decay=1e-4)

# weight_decay = λ в L2 штрафе

8. Data Augmentation

Идея: увеличить размер обучающего набора путём трансформаций

from torchvision.transforms import transforms

transform = transforms.Compose([
    transforms.RandomRotation(15),
    transforms.RandomHorizontalFlip(),
    transforms.ColorJitter(brightness=0.2, contrast=0.2),
    transforms.ToTensor(),
])

Плюсы:

  • Эффективно увеличивает обучающий набор
  • Улучшает обобщение
  • Особенно эффективна для изображений

Минусы:

  • Требует домена знаний (какие трансформации допустимы)
  • Может добавить шум
  • Не универсальна (сложно для табличных данных)

Сравнительная таблица

МетодТип моделиСкоростьОтбор признаковКоррелированныеСложность
L1ЛинейныеМедленноДаНетСредняя
L2ЛинейныеБыстроНетДаНизкая
ElasticNetЛинейныеСреднеДаДаСредняя
DropoutСетиМедленноНетДаНизкая
BatchNormСетиСреднеНетДаНизкая
Early StoppingВсеБыстроНетДаНизкая
Data AugВсе-НетДаВысокая

Практический пример: выбор метода

from sklearn.model_selection import cross_val_score

# Сравниваем методы регуляризации
models = {
    "OLS": LinearRegression(),
    "Ridge": Ridge(alpha=1.0),
    "Lasso": Lasso(alpha=0.1),
    "ElasticNet": ElasticNet(alpha=0.1, l1_ratio=0.5)
}

for name, model in models.items():
    scores = cross_val_score(model, X_train, y_train, cv=5, scoring="r2")
    print(f"{name:12} | R²: {scores.mean():.4f} +/- {scores.std():.4f}")

Лучшие практики

  • Начни с L2 (Ridge) для линейных моделей
  • Используй L1 если нужен отбор признаков
  • Комбинируй методы (L1 + Dropout)
  • Подбирай λ через cross-validation
  • Нормализуй признаки перед регуляризацией
  • Используй early stopping с валидационным набором
  • Для сетей комбинируй Dropout + BatchNorm + Weight Decay

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

Какие существуют методы регуляризации? Плюсы и минусы каждого? | PrepBro