← Назад к вопросам
Какие существуют методы регуляризации? Плюсы и минусы каждого?
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
Регуляризация — критический инструмент для получения моделей, которые хорошо обобщаются на новые данные.