В прошлой статье мы реализовывали линейную регрессию, в этой разберемся что такое регуляризация модели машинного обучения и добавим её в обучение линейной регрессии на Python из прошлых статей.
L1 и L2 регуляризация
В машинном обучении и Data science, регуляризация является важной техникой для управления переобучением модели. Она помогает избежать слишком сложной модели, которая может хорошо подстроиться под обучающие данные, но будет работать плохо на новых данных.
В этой статье мы рассмотрим два основных типа регуляризации: L1 и L2. Более конкретно, мы рассмотрим, как они работают, и как их можно использовать в Python для создания более надежных моделей в data science.
L1 регуляризация
L1 регуляризация также известна как Lasso (Least Absolute Shrinkage and Selection Operator) регуляризация. Она основана на добавлении штрафа, равного абсолютному значению коэффициентов модели.
Формально, L1 регуляризация добавляет в функцию потерь дополнительное слагаемое налагающее штраф за сложность модели, то есть высокие веса:
L1 регуляризация склонна к отбору признаков, так как она может уменьшить веса признаков до нуля. Это позволяет убрать неинформативные признаки из модели, что может уменьшить сложность модели и улучшить ее обобщающую способность.
В библиотеке Python scikit-learn, можно использовать L1 регуляризацию при обучении линейной регрессии:
from sklearn import linear_model reg = linear_model.Lasso(alpha=0.1)
Здесь параметр alpha — это гиперпараметр, который управляет общей силой регуляризации. Большие значения alpha соответствуют более сильной регуляризации.
L1 регуляризация является эффективным методом борьбы с переобучением модели в машинном обучении. Однако, при использовании метода градиентного спуска, который является одним из самых популярных алгоритмов оптимизации модели, L1 регуляризация может привести к некоторым проблемам.
В частности, L1 регуляризация имеет несколько «острых» углов (разрывов) в окрестности нуля, где производная не определена. Это усложняет вычисление градиента функции потерь, когда используется L1 регуляризация. Метод градиентного спуска требует, чтобы градиент был гладким и непрерывным, чтобы правильно работать, и поэтому L1 регуляризация может быть менее эффективна при использовании градиентного спуска.
Вместо L1 регуляризации в методе градиентного спуска часто используется L2 регуляризация, так как она имеет более гладкую производную и может лучше работать с градиентным спуском. Однако, в некоторых случаях L1 регуляризация может все же использоваться в методе градиентного спуска с использованием различных техник оптимизации, таких как координатный спуск или L-BFGS, которые могут лучше обрабатывать разрывы в функции потерь.
Машинное обучение на Python
Код курса
PYML
Ближайшая дата курса
24 февраля, 2025
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.
L2 регуляризация
Помимо L1 регуляризации, существует также L2 регуляризация (иногда называемая Ridge регуляризацией), которая также применяется в линейной регрессии и многих других моделях.
L2 регуляризация так же добавляет к оптимизационной функции модели штрафную функцию:
Эта штрафная функция является суммой квадратов весов модели, умноженных на гиперпараметр регуляризации. Это означает, что L2 регуляризация штрафует большие значения весов, заставляя их приближаться к нулю, но в отличие от L1 регуляризации не зануляет их полностью. Вместо этого L2 регуляризация штрафует большие значения весов более гладко и непрерывно, что позволяет более уверенно управлять компромиссом между точностью и сложностью модели.
Кроме того, L2 регуляризация может помочь в предотвращении переобучения и улучшении обобщающей способности модели, а также в уменьшении влияния шума в данных на модель.
В библиотеке Python scikit-learn, можно использовать L2 регуляризацию при обучении линейной регрессии:
from sklearn import linear_model reg = linear_model.Ridge(alpha=0.1)
Здесь параметр alpha — это гиперпараметр, который управляет общей силой регуляризации. Большие значения alpha соответствуют более сильной регуляризации.
Машинное обучение на Python
Код курса
PYML
Ближайшая дата курса
24 февраля, 2025
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.
Реализация L1 и L2 в цикле обучения модели
Теперь, уже по сложившейся традиции, реализуем описанное выше собственными руками. Для этого используем код уже написанной нами линейной регрессии в статье «Оптимизация в машинном обучении: ключ к качественной модели», но немного перепишем его. Импорты и подготовка данных остаются неизменными:
import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load_diabetes from sklearn.preprocessing import MinMaxScaler from sklearn.model_selection import train_test_split # получаем датасет из библиотеки sklearn diabetes = load_diabetes() scaler = MinMaxScaler() inputs = scaler.fit_transform(diabetes.data) targets = diabetes.target X_train, X_test, y_train, y_test = train_test_split(inputs, targets, test_size=0.3, random_state=42) X_train, X_test = torch.from_numpy(X_train).float(), torch.from_numpy(X_test).float() y_train, y_test = torch.from_numpy(y_train).float().view(-1, 1), torch.from_numpy(y_test).float().view(-1, 1)
Наш класс реализующий линейную регрессию дополнится двумя новыми методами отвечающими за L1 и L2 соответственно:
class LinearRegression(nn.Module): def __init__(self, input_size, output_size, lambda_): super().__init__() self.weights = nn.Parameter(torch.randn(input_size, output_size)) self.bias = nn.Parameter(torch.randn(output_size)) self.lambda_ = lambda_ def forward(self, x): return x @ self.weights + self.bias def l1_reg(self): return self.lambda_ * torch.sum(torch.abs(self.weights)) def l2_reg(self): return self.lambda_ * torch.sum(torch.pow(self.weights, 2)) # Инициализируем модель input_size = X_train.shape[1] output_size = 1 lambda_ = 0.01 model = LinearRegression(input_size, output_size, lambda_)
Далее определим функцию потерь и оптимизационный алгоритм. На этот раз используем алгоритм L-BFGS. L-BFGS является методом оптимизации, который использует информацию о градиенте функции потерь, но он не является прямым градиентным методом оптимизации. Одну эпоху обучения определим функцией fitness_step(). Ункцией Здесь же и будем добавлять нашу регуляризацию в виде штрафа к функции потерь.
# Инициализируем фуункцию потерь и оптимизатор criterion = nn.MSELoss() #optimizer = optim.SGD(model.parameters(), lr=0.1) optimizer = optim.LBFGS(model.parameters(), lr=1.0) # эпоха обучения def fitness_step(): outputs = model(X_train) # Получаем предсказания loss = criterion(outputs, y_train) # Обсчитываем функцию потерь if reg == 'l1': loss += model.l1_reg() # Добавляем L1 регуляризацию elif reg == 'l2': loss += model.l2_reg() # Добавляем L2 регуляризацию # Выполняем оптимизацию параметров модели optimizer.zero_grad() loss.backward() print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}') return loss
Далее будем добавлять штраф к функции потерь непосредственно в цикле обучения (в коде применяется L1, для использования L2 следует переопределить переменную reg на ‘l2’):
# Запускаем обучение reg = 'l1' num_epochs = 500 for epoch in range(num_epochs): optimizer.step(fitness_step) print(f'MSE модели на обучающей выборке {criterion(model(X_train), y_train)}') print(f'MSE модели на тестовой выборке {criterion(model(X_test), y_test)}')
Результаты по качеству сопоставимы с результатами полученными нами в предыдущих статьях.
Машинное обучение на Python
Код курса
PYML
Ближайшая дата курса
24 февраля, 2025
Продолжительность
24 ак.часов
Стоимость обучения
54 000 руб.
Регуляризация полезный инструмент в Data science. Как L1, так и L2 регуляризации применяются для ограничения весов модели с целью избежать переобучения и достичь наилучшей обобщающей способности модели. Применение L1-регуляризации иногда может давать полезный побочный эффект, вызывающий стремление одного или более весовых значений к 0, а это означает, что соответствующий признак не важен. Это одна из форм того, что называют селекцией признаков (feature selection). Однако, использование L1-регуляризации не всегда возможно, так как она может не подходить для некоторых алгоритмов машинного обучения, особенно для тех, которые используют численные методы для вычисления градиента. В отличие от L1, L2-регуляризация работает со всеми алгоритмами машинного обучения, но не удаляет не важные признаки. В конечном итоге, выбор между L1 и L2 регуляризацией зависит от конкретной задачи и методов обучения, поэтому определение наиболее подходящей регуляризации может потребовать тестирования методами проб и ошибок.
Для тех, кто хочет узнать больше о данной теме и быть в курсе более современных методов и инструментов, мы предлагаем посетить наш лицензированный учебный центр в Москве, который специализируется на повышении квалификации ИТ-специалистов. Там вы сможете принять участие в практическом курсе «Машинное обучение на Python«.
Источники:
- https://scikit-learn.org/stable/modules/linear_model.html