Coding Linear Regression¶
Посмотрим на некий обзор главных моментов которые дадут нам возможность реализовать линейные модели в python и numpy. Посмотрим как отличается линейная регрессия от логистической, и как можно добавлять регуляризацию для этих моделей, чтобы можно было контролировать обобщающию способность модели. В этом разделе фокус на линейной регрессии.
В этом разделе посмотрим на реализацию линейных моделей в python и numpy. Есть различные подходя для решения задачи линейной регрессии, мы посмотрим на реализацию с помощью матричных операции и с градиентном спуском. Так же посмотрим как добавлять гегуляризацию для этой модели
Задача оптимизации гиперпараметров¶
Существует несколько вариантов для выбора гипераметров линейной регрессии
- Через прямые матричные операции
- Через градиентны спуск
Я думаю важно знать о обоих подходов и как они реализуются
Реализация Матричных Операции¶
Линейная регрессия выражается следующей зависимостью:
- \(X\) — матрица объекты-признаки
- \(y\) — вектор целевых значений
Cоответствующих:
- \(X\), \(\theta\) — параметр линейной регрессии, \(\epsilon\) — некоторый шум
Наша задача, минимизировать среднеквадратическую ошибку между \(y\) и \(X\theta\) (используюя Least Squares Method)
Используя матричную формулеровку, следует выражение для \(\theta\) как:
Который нам дает оптимальный \(\theta\) в этой постоновке задачи, решая \(\theta\) мы можем делать предсказание \(y=X\theta+\epsilon\)
Реализация Градиентного Спуска¶
Алтернативный подход для решения этой задачи (оптимизации гиперпараметров) является с методом градиентного спуска
Для реализации линейной регрессии с помощью методов оптимизации будем использовать функцию ошибки среднего квадратичного, которая является выпуклой функцией в n-мерном пространстве \(\mathbb{R}^n\) и в общем виде выглядит следующим образом:
- \(x_i\) — вектор-признак \(i\)-го объекта обучающей выборки
- \(y_i\) — истинное значение для \(i\)-го объекта,
- \(a(x)\) — алгоритм, предсказывающий для данного объекта \(x\) целевое значение
- \(n\) — кол-во объектов в выборке
В случае линейной регрессии \(MSE\) представляется как:
- \(\theta\) — параметр модели линейной регрессии
- \(X\) — матрица объекты-признаки
- \(y\) - вектор истинных значений, соответствующих \(X\)
Возьмем первый вариант представления функции ошибки и посчитаем ее градиент по параметру \(\theta\), предварительно переименовав \(MSE\) в \(L\):
Нам еще нужны функции для шага градиентного спуска и оптимизационный цикл
# шаг градиентного спуска
def grad_step(theta,theta_grad,alpha):
return theta - alpha*theta_grad
# оптимизационный цикл
def optimise(X,theta,n_iters):
# theta0
theta = start_theta.copy()
# оптимизационный цикл
for i in range(n_iters):
theta_grad = mse_grad(X,theta)
theta = grad_step(theta,theta_grad,alpha)
return theta
Мы начинаем с начального условия theta итеративно меняем его с помощью градиента, мы используем градиентный спуск для обновления параметров модели (весов) в направлении, противоположном градиенту функции потерь, чтобы минимизировать ошибку предсказания
Регуляризация¶
Далее посмотрим как можно реализовать регуляризацию в линейную регрессию, это важное понятие потому что оно даст нам возможность контролировать обобщаюшию способность модели, давая нам контроль над влиянием изменения гиперпараметров модели при ее оптимизации. Существет несколько подходов, L1 и L2 регуляризация:
- Для L1 нормалтзации: Регуляризация также штрафует большие коэффициенты, и может свести их к нулю!
- Для L2 нормалтзации: Регуляризация штрафует большие коэффициенты, но не обнуляет их, а лишь делает их ближе к нулю. Это помогает уменьшить вариативность модели и сделать её более стабильной
Рассмотрим как это можно реализовать при использования градиентного спуска
После добавления регуляризации функция ошибки линейной регрессии будет выглядеть следующим образом:
А ее градиент по параметру \(\theta\):
Что мы делаем, мы добавляем дополнительный термин который пропорционален квадрату величины коэффициентов в квадратную функцию потерь (на подобие RidgeRegressor)
# градиент квадратной функции потерь
def mse_grad_reg(X,theta):
n = X.shape[0]
grad = (1/n) * X.T.dot(X.dot(theta) - y) # стандартный градиент функции потерь
grad_temp = lambd * np.mean(theta) # дополнительный термин
return grad + grad_temp
Предсказание с LinearRegression¶
Имея оптимизированные параметры \(\theta\), мы можем делаить предсказания используя функцию
Подведем Итоги¶
В этом посте мы рассмотрели как можно реализовать линейную регрессию в простом виде. Так же отметили как можно добавить регуляризацию для обоих вариантов. Для линейной регресии мы представили два варианта решения оптимизации гиперпараметров линейных моделей**. Подход градиетного спуска используется чаще всего на практике, так как вычисления обратной матрицы является трудозатратным процессом.
Для решения задачи выбора гиперпараметров линейной регресии с помошью градиентного спуска нам нужно знать градиент среднеквадратической ошибки, так же и для логистической регресиии нам нужно знать градиент бинарной кросс энтропии, это пожалуй остновной момент. Зная формулы для \(\frac{dL}{d\theta}\), мы можем воспользоваться градиентном спуском для оптимизации гиперпараметров.
Так же мы увидили как можно добавлять регуляризацию, собственно добавляя дополнительный термин в функцию потерь, дает нам возможность штрафовать большие значения весов, чем больше значение \(\alpha\), тем больше эффект регуляризации и веса будут уменьшатся для больших значении.