5 ключевых моментов для обучения модели линейной регрессии

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

Коротко говоря, модель линейной регрессии представляет собой линейную комбинацию функций для оценки метки или целевой переменной. В этом кратком обзоре мы будем использовать кодирование Python и набор данных mpg mpg dataset. Основная идея состоит в том, чтобы спрогнозировать расход топлива в милях на галлон (миль на галлон) по таким характеристикам, как количество цилиндров, мощность, ускорение, режим, происхождение и т. д.

df = pd.read_csv('./dataset/df_new.csv')
df.head()

#Пункт 1: Как определить модель?

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

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

Представление модели

Модель такого типа можно представить как линейную комбинацию функций для обозначения метки. Это означает линейное уравнение: линию с наклоном и точкой пересечения с осью y.

Чем больше наклон, тем более крутая линия, и если наклона нет, значением по умолчанию будет точка пересечения по оси Y. Мы хотим наилучшим образом подогнать линию к нашим данным. В общем, у нас может быть многомерная линейная регрессия (гиперплоскость n измерений). Таким образом, мы можем предсказать ярлык Ypred на основе особенностей:

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

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

#Точка 2: Какова цель модели?

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

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

#Пункт 3: Какой алгоритм использовать?

Линейная регрессия — это линия, которой мы хотим наилучшим образом соответствовать всем точкам (данным). Таким образом, нам нужно настроить алгоритм или процедуру для определения параметров модели: весов и смещения. Есть много способов настроить эту процедуру, один из них может быть:

Базовый алгоритм (модель):

  • Входные данные: случайная точка из набора данных.
  • Выход: линия, проходящая близко к точкам, модель, которая лучше всего соответствует данным.
  • Процедура:
    1. выберите модель со случайным весом и смещением (это означает случайную линию)
    2. повторите много раз:
    — Выберите несколько точек в качестве эталона
    Обновить параметры: веса и смещение для улучшения прогнозов ближе к этой точке
    — вычислить значение «потери или ошибки»
    3. вернуть модель

Теперь нам нужно определить, как «обновлять параметры», веса (наклон) и смещение (пересечение оси y). Есть много способов сделать это. Есть один, имея в виду одну точку (r,p) и случайную линию, здесь 2 способа быть ближе к точке. Один из них изменяет наклон путем увеличения (поворот против часовой стрелки) или уменьшения (по часовой стрелке), второй — изменения точки пересечения оси Y путем увеличения (вверх) или уменьшения (вниз). Объединив эти 2 способа, мы можем создать более сложный алгоритм. В Python у нас может быть следующий код:

def update_parameters(weight, bias, r, b, lr):
    label_pred = weight*r + bias
    if b > label_pred:
        weight = weight + lr*r
        bias = bias + lr
     else:
        weight = weight - lr*r
        bias = bias - lr
    return weight, bias

# First version
def basic_linear_model(df, lr=0.01, epochs = 100):
    weight = np.random.random()
    bias = np.random.randint(25,40)
    model = []
    for epoch in range(epochs):
        i = np.random.randint(0, len(df['horsepower'])-1)
        r = df['horsepower'][i]
        b = df['mpg'][i]
        weight, bias = update_parameters(weight, bias, r, b, lr)
        model.append({'weight': weight, 'bias':bias, 'index':i})
    return model

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

# Training: 
model_lr = basic_linear_model(df_line_train, lr=0.001, epochs = len(df_line_train))

# Plotting:
plt.scatter(df_line_train['horsepower'], df_line_train['mpg'])
x = [float(i) for i in range(len(model_lr))]
for w in np.random.randint(0,len(df_line_train), 6):
    y_pred = [model_lr[w]['weight']*i + model_lr[w]['bias'] for i in x]
    plt.plot(x, y_pred)
plt.title('Horsepower' + ' vs ' + 'MPG', fontsize = 15)
plt.xlabel('horsepower')
plt.ylabel('mpg')
plt.show()

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

#Пункт 4: Как оптимизировать алгоритм?

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

Алгоритм градиентного спуска

Градиентный спуск имеет три основные версии: стохастический (некоторый момент времени), мини-пакетный (мини-пакетные точки) и пакетный (весь набор данных). Разница между ними заключается в том, как мы оцениваем алгоритм, но основные шаги одинаковы. Здесь мы собираемся сосредоточиться на стохастике, и он работает следующим образом:

  1. Нам приходится смотреть со всех сторон, чтобы найти направление, в котором мы можем спуститься больше всего.
  2. Мы должны делать небольшие шаги, которые могут обеспечить наибольший спуск.
  3. Повторите этот процесс много раз, пока не окажетесь внизу.

Мы можем получить формулу градиентного спуска, выполнив производную функции потерь:

Параметры и гиперпараметры

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

1. Параметры — веса и смещение $\theta,\theta_0$. В общем, это любые величины, которые модель создает или изменяет в процессе обучения.
2. Гиперпараметры — это скорость обучения $\eta$, эпохи, степень полиномиальной регрессии модели. В общем, это любое количество, которое вы зададите перед тренировочным процессом.

Скорость обучения гиперпараметров связана с тем, насколько быстро наша модель обучается или обновляет веса. Обновление кода Python:

def update_parameters_gradient(weight, bias, r, b, lr):
    label_pred = weight*r + bias
    # Gradient descent
    weight = weight + lr*r*(b-label_pred)
    bias = bias + lr*(b-label_pred)
    return weight, bias

# Second version
def gradient_linear_model(df, lr=0.01, epochs = 100):
    weight = np.random.random()
    bias = np.random.randint(25,40)
    model = []
    for epoch in range(epochs):
        i = np.random.randint(0, len(df['horsepower'])-1)
        r = df['horsepower'][i]
        b = df['mpg'][i]
        weight, bias = update_parameters_gradient(weight, bias, r, b, lr)
        model.append({'weight': weight, 'bias':bias, 'index':i})
    return model
# Training: 
model_sgd_lr = gradient_linear_model(df_line_train, lr=0.00001, epochs = len(df_line_train))

plt.scatter(df_line_train['horsepower'], df_line_train['mpg'])
x = [float(i) for i in range(len(model_sgd_lr))]
for w in np.random.randint(0,len(df_line_train), 10):
    y_pred = [model_sgd_lr[w]['weight']*i + model_sgd_lr[w]['bias'] for i in x]
    plt.plot(x, y_pred)
plt.title('Horsepower' + ' vs ' + 'MPG', fontsize = 15)
plt.xlabel('horsepower')
plt.ylabel('mpg')
plt.show()

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

#Пункт 5: Как оценить, является ли наш алгоритм лучшим?

Для измерения нам нужно знать разницу между реальной стоимостью и прогнозируемой стоимостью, это означает ошибку. Функция Error используется для измерения нашей модели. Для моделей линейной регрессии существует 4 способа определения:

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

MSE: Квадратная ошибка — это квадрат разницы между реальным значением и прогнозируемым значением.

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

Для простоты мы будем использовать RMSE в качестве метрики для оптимизации модели. В питоне у нас есть:

```python
# Measure Error during Epochs:
error_MAE_grad = []
error_RMSE_grad = []
epochs = len(df_line_train)
epoch = [epoch for epoch in range(epochs)]
for w in range(len(model_lr_grad)):
    weight = model_lr_grad[w]['weight']
    bias = model_lr_grad[w]['bias']

    x = df_line_train['horsepower']
    y = df_line_train['mpg']
    
    y_pred = weight*x + bias
    
    MAE = np.sum(np.abs(y - y_pred))/len(df_line_train['mpg'])
    RMSE = np.sqrt(np.sum((y - y_pred)**2)/len(df_line_train['mpg']))
    
    error_MAE_grad.append(MAE)
    error_RMSE_grad.append(RMSE)
#plt.plot(epoch, error_MAE)
plt.plot(epoch, error_RMSE_grad)
plt.title('Epoch' + ' vs ' + 'Error_RMSE', fontsize = 15)
plt.show()

Для получения более подробной информации проверьте мой github или загляните в мой блог. До скорой встречи.