Линейная регрессия и градиентный спуск с использованием только Numpy
Узнайте, как реализовать модель линейной регрессии с нуля!
Вероятно, если вы изучаете машинное обучение, вы уже знакомы с моделью линейной регрессии и алгоритмом градиентного спуска. Проблема в том, что часто они реализуются с использованием библиотек высокого уровня, таких как sklearn, поэтому реальная работа может оставаться загадкой. Давайте узнаем, как на самом деле работает написание кода с нуля!
Какова цель линейной регрессии?
Предположим, у вас есть набор данных, содержащий 1000 записей, каждая из которых состоит из 5 признаков. Этот набор данных можно очень просто представить с помощью матрицы 1000 x 5. Для каждой из этих записей X(i)у вас также есть связанные выходные данные y(i), поэтому yт. е. набор выходных данных может быть представлен просто вектором размера 1000.
Если мы нанесем наш набор данных на плоскость, предполагая, что у нас есть только один объект вместо 5, мы можем сказать, что наша цель — найти линию y = mX +q, которая пересекает наши данные таким образом, что различные точки набора данных находятся не слишком далеко от обнаруженной линии.

Обратите внимание, что в строке, которую мы хотим найти, X известен, поскольку это наш набор данных, поэтому скрытые параметры составляют только m. и q. В большем количестве измерений, поэтому с большим количеством признаков, мы не должны находить линию, но гиперплоскость и m и q будут векторами с таким же количеством записи как количество функций.
Более формально, расстояние точек от линии, которую нужно минимизировать, измеряется функцией, называемой среднеквадратической ошибкой (MSE), определяемой по формуле:

Формула говорит нам, что мы на самом деле хотим минимизировать среднеквадратичное расстояние каждой точки от линии.
В формуле y_i — известные выходы, и, поскольку ŷ_i задается линией, мы хотим найти ŷ_i= mX +q, чтобы минимизировать эту функцию, нам просто нужно найти лучшие параметры m и q. Таким образом, мы можем сказать, что MSE — это функция F, которая зависит от двух параметров m и q : F(m,q)
Как только мы нашли эти параметры, мы можем сделать некоторые прогнозы, для каждой новой записи мы можем сказать, какой будет соответствующий результат.
Градиентный спуск для поиска скрытых параметров
Представим MSE (функция стоимости) графически.

Поскольку мы игнорируем, какие параметры минимизируют функцию стоимости, m и q будут инициализированы случайным образом. Итак, сначала мы будем в любой точке функции стоимости (см. график). Наша цель — каждый раз обновлять параметры θ = [m,q], чтобы найти минимум функции стоимости, это гарантирует, что в среднем точки набор данных не будет слишком далеко от найденной линии.
Алгоритм градиентного спуска (GD) просто говорит нам, что это обновление должно соответствовать правилу:
θ = θ - α∇F(θ)
Где α — априорно выбранное число, называемое скоростью обучения, а вместо этого ∇F(θ) — вектор, каждая запись которого содержит частную производную функции стоимости F относительно параметра в θ.
Поэтому давайте вычислим эти частные производные.

Большой! В качестве последнего трюка мы заметили из формул, что мы должны обновлять параметры θ только после суммирования всех n записей, то есть после просмотра всех записей набора данных. Но поскольку очень часто набор данных огромен, мы можем добавить только число k и немедленно выполнить обновление параметров, а затем продолжить обновление с отсутствующими записями. Таким образом, k называется размер пакета, а набор из k элементов, взятых время от времени, называется пакетом. Когда вы исчерпали все доступные пакеты, завершается так называемая эпоха. Вы можете начать снова с новой эпохи, если я хочу улучшить ваши оценки параметров θ.
Реализация в Numpy
Давайте импортируем numpy, создадим случайный набор данных с 5 функциями, а также случайным образом создадим m и q, которые нам нужно будет обнаружить. Мы также генерируем реальный результат, заданный линейной зависимостью, к которой мы добавляем некоторый шум.
Обратите внимание, что нет необходимости различать m и q. Обратите внимание, что вывод:
y = m1X1 + mwX2 + m3X3 + m4X4 + m5X5 + q
но это то же самое, что писать
y = m1X1 + mwX2 + m3X3 + m4X4 + m5X5 +m6X6
при условии, что m6 = q и X6 всегда равно 1.
Затем нам нужно добавить функцию «1», соединив ее с набором данных, который у нас уже есть, а также добавить q к вектору m.
Напишем функцию, которая вычисляет значение частной производной только по m (поскольку мы избавились от q), которая должна принимать на вход оценку m_stat состоит из исходных параметров
Нам также нужно определить функцию MSE
В функции обучения мы продолжаем обновлять параметры. Первый цикл for перебирает заданное нами количество эпох, а второй вложенный цикл for перебирает все пакеты эпохи. Обратите внимание, что для каждой эпохи важно перемешивать данные!
Задаем гиперпараметры и оцениваем параметры
Если мы напечатаем оценочные параметры и исходные, мы обнаружим, что они почти идентичны, поэтому мы нашли исходную строку, которая сгенерировала выходные данные! Теперь я могу использовать эту строку для прогнозирования новых тестовых данных.
Заключение
Модели, основанные на линейной регрессии, относительно просты для интерпретации и очень полезны, когда речь идет о создании прогнозов. Линейная регрессия может применяться в самых разных областях, от здравоохранения до бизнеса. В расширенном машинном обучении, например, в классификации текста, линейная модель по-прежнему очень важна, хотя есть и другие, более сложные модели. Это связано с тем, что линейная модель очень стабильна, она с меньшей вероятностью будет слишком сильно соответствовать данным. Эволюция линейной регрессии — это полиномиальная регрессия, более сложная модель, которая может соответствовать также нелинейным наборам данных с более сложными функциями, пожалуйста, проверьте здесь: https://en.wikipedia.org/wiki /Полиномиальная_регрессия».
Конец
Автор : Марчелло Полити