В этом курсе мы будем изучать линейную регрессию с несколькими переменными, которая является расширением простой линейной регрессии, рассмотренной ранее.

Сначала мы определим, что такое линейная регрессия с несколькими переменными, затем мы введем математическую формулировку для формализации этого типа регрессии, а затем мы увидим, как применять метод градиентного спуска для поиска оптимальных параметров.

Наконец, мы применим наши знания на практике, решив пример с использованием python.

В предыдущих уроках мы изучали простую линейную регрессию с использованием одной переменной, где количественная переменная Y зависит от одной переменной, обозначенной X, мы изучали проблему ценообразования дома, в которой мы хотим найти цену дома (отмечено Y), используя размера дома (обозначим через X), мы формализовали эту задачу следующим образом

Где θ_0, θ_1 — параметры, которые нам нужно найти, чтобы иметь линейную зависимость между Y и X.

В этом уроке мы изучим, как смоделировать цену дома с более чем одной входной переменной, такой как, например, количество комнат, возраст дома, количество этажей и т. д. Это поможет нам лучше моделировать наша количественная переменная Y, с большим количеством входной информации мы будем лучше соответствовать

Давайте возьмем приведенный ниже набор данных в качестве примера для нашего исследования.

В приведенной выше таблице каждая строка представляет собой образец нашего набора данных, а каждый столбец, кроме последнего, является входной переменной для нашей задачи линейной регрессии, последний столбец представляет собой переменную Y, которую мы хотим предсказать.

Прежде чем приступить к математической формализации задачи, введем сначала некоторые обозначения,

Например, в этом наборе данных у нас есть

Теперь, когда мы ввели обозначения, давайте расширим математическую формулировку линейной регрессии с одной переменной до формулировки нескольких переменных следующим образом:

Эта формализация довольно проста для понимания, чтобы предсказать нашу переменную Y, мы придадим каждой входной переменной вес важности в окончательном прогнозе, это можно рассматривать как значение корреляции между входной переменной и выходным значением Y, затем мы берем взвешенное среднее значение всех входных переменных и дополнительное смещение, чтобы получить окончательный прогноз.

Мы можем переформулировать это уравнение в матричной форме следующим образом:

Это просто точечный продукт между вектором весов и входной выборкой.

Как и в линейной регрессии только с одной переменной, здесь мы попытаемся минимизировать евклидово расстояние между прогнозируемым значением и реальным значением y. Мы можем определить эту ошибку аппроксимации следующим образом:

Как только эта ошибка аппроксимации определена, мы можем использовать метод градиентного спуска, чтобы найти оптимальные параметры Θ, которые дают наилучшее возможное приближение наших данных.

Общая формулировка метода градиентного спуска дается следующим образом.

Вычисление градиента здесь подробно описываться не будет, но его можно легко рассчитать, обладая базовыми знаниями в области исчисления. Как только этот член будет рассчитан, мы можем использовать метод градиентного спуска для оптимизации нашего параметра, окончательная формулировка дается следующим образом.

Мы можем использовать эту формулу для одновременного обновления наших параметров до сходимости. Как только мы найдем оптимальные параметры для нашего набора данных, мы сможем использовать их для прогнозирования значения y для новых значений x.

Теперь, когда мы заложили основы многомерной линейной регрессии, мы обсудим более практические аспекты решения этой проблемы.

Первая проблема, с которой мы можем столкнуться, заключается в том, что наши входные переменные не имеют одинакового возможного диапазона значений. Например, в наборе данных, описанном выше, переменная размер дома включена в интервал [0–2000], а переменная число этажей включена в интервал [1 -5]. Если мы смоделируем нашу переменную Y, используя только эти две переменные, следующим образом:

И если мы запустим алгоритм градиентного спуска, чтобы найти наилучшее возможное значение для этих параметров, мы увидим, как показано на рисунке ниже, что процесс оптимизации будет изо всех сил пытаться напрямую сходиться к оптимальному решению, у нас будут некоторые колебания, прежде чем достичь окончательное решение. Это связано с тем, что при оптимизации два параметра сдвинуты, переменная размер дома из-за того, что она принимает больший диапазон значений, будет сходиться быстрее, чем переменная количество этажей, которое будет иметь более низкий градиент на каждом шаге оптимизации.

Простой способ решить эту проблему — просто нормализовать наши входные данные в том же интервале возможных значений. Например, интервал значения [0,1], чтобы изменить масштаб значений наших входных переменных, мы можем просто разделить на максимальное значение, которое может принимать каждая переменная, следующим образом

Как только параметры нормализованы, мы можем заметить на рисунке выше, что сходимость происходит быстрее, и требуется меньше шагов оптимизации. Алгоритм сходится непосредственно к решению после нескольких итераций

В более общем смысле мы хотим, чтобы наши входные значения были включены в интервал [-1,1], конечно, если входные значения включены в интервал больше или меньше этого, это не имеет значения. Но если присутствует большое расхождение, т.е. входные значения принимают слишком большие или слишком маленькие значения, их придется нормализовать.

На практике мы обычно используем MinMaxScaler, который позволяет нам нормализовать наши данные в интервале [0,1] следующим образом:

После того, как проблема нормализации данных решена, остается только выбрать хорошую скорость обучения θ, чтобы иметь функциональный алгоритм.

Как и для всех других гиперпараметров, простой идеей выбора оптимальной скорости обучения является простое построение значений функции стоимости для различных вариантов α, а затем выбор значения, которое лучше всего минимизирует функцию стоимости. Давайте проиллюстрируем это на Python, мы начнем с загрузки набора данных с помощью следующего кода:

import math
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import pandas as pd
df=pd.read_csv('https://raw.githubusercontent.com/navoneel1092283/multivariate_regression/master/data2.txt', header=None)
df.columns=['SqFt','Bedrooms','Price']

Выполнение кода дает следующий результат

Затем мы нормализуем данные следующим образом:

df = (df - df.min())/(df.max()-df.min())
df.head()

Выполнение кода дает следующий результат

Теперь мы определим наши входные переменные (обозначены X) и выходные (обозначены Y) следующим образом:

#setting the matrixes
X = df.iloc[:,0:2]
ones = np.ones([X.shape[0],1])
X = np.concatenate((ones,X),axis=1)
y =df.iloc[:,2:3].values #.values converts it from pandas.core.frame.DataFrame to numpy.ndarray
theta = np.zeros([1,3])

Мы определим две функции для вычисления функции стоимости и для шага градиентного спуска следующим образом:

def computeCost(X,y,theta):
   tobesummed = np.power(((X @ theta.T)-y),2)
   return np.sum(tobesummed)/(2 * len(X))
def gradientDescent(X,y,theta,iters,alpha):
   cost = np.zeros(iters)
   for i in range(iters):
      theta = theta - (alpha/len(X)) * np.sum(X * (X @ theta.T - y),
       axis=0)
      cost[i] = computeCost(X, y, theta)
   return theta,cost

Теперь мы построим значение функции стоимости за 1000 итераций для различных значений α следующим образом:

iters = 1000
#running the gd and cost function
for alpha in [0.0001,0.001,0.01,0.1,1]:
   g,cost = gradientDescent(X,y,theta,iters,alpha)
   finalCost = computeCost(X,y,g)
   plt.plot(np.arange(iters), cost)
plt.xlabel('Iterations')
plt.ylabel('Cost')
plt.title('Error vs. Training Epoch')
plt.legend(["alpha ="+str(alpha) for alpha in [0.0001,0.001,0.01,0.1,1] ])
plt.savefig("1.png",dpi=100)

Выполнение кода дает следующий результат

можно заметить, что скорость сходимости зависит от выбора значения α, чем оно больше, тем быстрее сходимость, но выбор большого значения альфы может привести к расходимости нашего алгоритма, предпочтительнее выбрать маленькое значение α, даже если для сходимости потребуется больше времени, мы избежим проблемы расходимости после нескольких итераций градиентного спуска.

Вывод

В этом курсе мы представили многомерную линейную регрессию, мы определили математическую формулировку задачи и расширение метода градиентного спуска для оптимизации наших параметров, затем мы обсудили более практический аспект нашей проблемы и метод выбора нашего гиперпараметры.