Python градиентный спуск: применение и примеры реализации
Градиентный спуск - это метод минимизации функции, который используется в машинном обучении для оптимизации моделей. Этот метод основан на поиске наилучшего значения параметров модели, которые минимизируют ошибку предсказания.
В Python градиентный спуск можно реализовать следующим образом:
1. Определение функции, которую мы хотим минимизировать. Например, функция среднеквадратической ошибки в задаче линейной регрессии:
def mse(y_true, y_pred):
return np.mean((y_true - y_pred)**2)
2. Определение градиента нашей функции, который является вектором частных производных по каждому параметру модели. Для примера с линейной регрессией градиент выглядит так:
def gradient(X, y_true, weights):
y_pred = X.dot(weights)
grad = -2*(y_true - y_pred).dot(X)
return grad
3. Задание начальных значений параметров модели и скорость обучения. Скорость обучения определяет шаг, на который мы будем двигаться в сторону антиградиента. Чем больше скорость, тем быстрее мы сходим к минимуму, но при этом можем пропустить локальный минимум и застрять в глобальном минимуме.
learning_rate = 0.01
n_epochs = 1000
weights = np.zeros(X.shape[1])
4. Написание цикла обучения, в котором мы будем обновлять параметры модели с помощью градиентного спуска. В каждой итерации мы вычисляем значение градиента и обновляем веса модели на нашем шаговом значении.
for i in range(n_epochs):
grad = gradient(X, y_true, weights)
weights -= learning_rate * grad
5. Проверка качества модели. Мы можем использовать нашу обученную модель для предсказания значений на тестовых данных и вычисления метрик качества, таких как средняя абсолютная ошибка или коэффициент детерминации.
y_pred = X_test.dot(weights)
mse(y_test, y_pred)
Пример полного кода для задачи линейной регрессии с помощью градиентного спуска:
import numpy as np
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
def mse(y_true, y_pred):
return np.mean((y_true - y_pred)**2)
def gradient(X, y_true, weights):
y_pred = X.dot(weights)
grad = -2*(y_true - y_pred).dot(X)
return grad
X, y = make_regression(n_samples=100, n_features=5, noise=0.5)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
learning_rate = 0.01
n_epochs = 1000
weights = np.zeros(X.shape[1])
for i in range(n_epochs):
grad = gradient(X_train, y_train, weights)
weights -= learning_rate * grad
y_pred = X_test.dot(weights)
print(mse(y_test, y_pred))