← Назад к вопросам
Почему L1 регуляризация зануляет часть весов?
2.0 Middle🔥 181 комментариев
#Машинное обучение
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Почему L1 регуляризация зануляет часть весов?
L1 регуляризация (Lasso regression) имеет математическое и геометрическое объяснение, почему она автоматически зануляет (обнуляет) некоторые веса модели. Это одна из самых элегантных свойств L1, которое делает её невероятно полезной для отбора признаков.
Математическое объяснение
L1 Loss Function:
Loss = MSE + λ * Σ|w_i|
где:
- MSE — обычная ошибка предсказания
- λ (lambda) — коэффициент регуляризации
- Σ|w_i| — сумма абсолютных значений всех весов
L2 Loss Function для сравнения:
Loss = MSE + λ * Σ(w_i²)
Геометрическое объяснение: диаманты vs круги
Представьте, что оптимизируем два параметра (w1, w2):
import numpy as np
import matplotlib.pyplot as plt
# L1 регуляризация: форма диаманта
w = np.linspace(-3, 3, 100)
# Диаманты имеют острые углы на осях (где w1=0 или w2=0)
# Оптимальное решение часто находится на пересечении с осями
# L2 регуляризация: форма круга
theta = np.linspace(0, 2*np.pi, 100)
x = np.cos(theta)
y = np.sin(theta)
# Круги имеют гладкую форму без острых углов
# Редко пересекают оси (редко w=0)
Ключевая идея:
- L1 имеет острые углы на осях
- L2 имеет гладкую форму
- Оптимальное решение часто на пересечении с осями — w=0
Математическое доказательство
Градиент L1 разрывный в нуле:
# Градиент L1 = sign(w) — перепад в нуле!
# Градиент L2 = 2*w — гладкий
# Loss = error + λ * |w|
# dLoss/dw = d(error)/dw + λ * sign(w)
# Где sign(w) = 1 если w > 0
# -1 если w < 0
# ∈ [-1, 1] если w = 0
Видите? Штраф λ * sign(w) всегда имеет фиксированную величину (λ), независимо от того, насколько мал w. Эта константная "сила" толкает w через ноль!
Сравнение L1 и L2
from sklearn.linear_model import Lasso, Ridge
from sklearn.preprocessing import StandardScaler
import numpy as np
# Синтетические данные
np.random.seed(42)
X = np.random.randn(100, 20)
w_true = np.array([5, 3, 0, 0, 2, 0, 0, 1, 0, 0] + [0]*10)
y = X @ w_true + np.random.randn(100) * 0.5
# L1 регуляризация (Lasso)
lasso = Lasso(alpha=0.1)
lasso.fit(X, y)
# L2 регуляризация (Ridge)
ridge = Ridge(alpha=0.1)
ridge.fit(X, y)
# Подсчёт нулевых коэффициентов
num_zeros_lasso = np.sum(lasso.coef_ == 0)
num_zeros_ridge = np.sum(ridge.coef_ == 0)
print(f"L1 (Lasso): {num_zeros_lasso} нулевых весов")
print(f"L2 (Ridge): {num_zeros_ridge} нулевых весов")
# Обычно: L1 имеет намного больше нулей!
Практический пример: отбор признаков
from sklearn.linear_model import LassoCV
from sklearn.preprocessing import StandardScaler
# Данные с избыточными признаками
X = np.random.randn(1000, 50)
true_indices = [0, 5, 10, 15]
w_true = np.zeros(50)
w_true[true_indices] = [3, 2, -1, 1.5]
y = X @ w_true + np.random.randn(1000) * 0.1
# Автоматический отбор alpha через кросс-валидацию
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
lasso_cv = LassoCV(cv=5)
lasso_cv.fit(X_scaled, y)
# Какие признаки выбрала модель?
selected_features = np.where(lasso_cv.coef_ != 0)[0]
print(f"Истинные признаки: {true_indices}")
print(f"Выбранные Lasso: {list(selected_features)}")
print(f"Оптимальное alpha: {lasso_cv.alpha_:.4f}")
Контроль величины λ (lambda)
from sklearn.linear_model import Lasso
import numpy as np
X = np.random.randn(200, 30)
y = X @ np.random.randn(30) + np.random.randn(200)
alphas = [0.001, 0.01, 0.1, 1.0, 10.0]
coefs = []
for alpha in alphas:
lasso = Lasso(alpha=alpha, max_iter=10000)
lasso.fit(X, y)
coefs.append(lasso.coef_)
coefs = np.array(coefs)
# С большим λ все веса → 0 (overly regularized)
# С маленьким λ веса близки к неregularized решению
for i in range(30):
print(f"Feature {i}: {np.abs(coefs[:, i])}")
Ключевые выводы
- L1 штраф имеет константный градиент (sign(w)), в отличие от L2 (пропорционален w)
- Острые углы диаманта касаются осей, что означает w=0
- L1 выполняет отбор признаков — идеально для высокоразмерных данных
- L2 сжимает веса — все остаются ненулевыми (shrinkage)
- Выбор λ критичен — слишком большой → недообучение, слишком маленький → переобучение
L1 регуляризация — это элегантный способ автоматически избавиться от неважных признаков, делая модели более интерпретируемыми и быстрыми!