Линейная регрессия

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

Линейная регрессия — самый базовый алгоритм машинного обучения для предсказания непрерывных значений; он предполагает, что целевая переменнаяyи переменные-признакиxимеют линейную зависимость, и пытается найти наиболее подходящую линию, описывающую эту зависимость.

y = w * x + b

Где:

  • y— предсказанное значение

  • x— переменная-признак

  • w— вес (наклон)

  • b— смещение (свободный член)

Цель линейной регрессии — найти оптимальныеwиb, чтобы предсказанное значениеyимело минимальную ошибку относительно истинного значения. Обычно используемая функция ошибки — среднеквадратичная ошибка (MSE):

MSE = 1/n * Σ(y_i - y_pred_i)^2

Где:

  • y_i — фактическое значение.
  • y_pred_i — предсказанное значение.
  • n — это количество точек данных.

Наша цель — минимизировать MSE, подбирая w и b.

Как решить задачу линейной регрессии?

1. Метод наименьших квадратов

Метод наименьших квадратов — распространённый подход к решению линейной регрессии; он находит оптимальные значения (w) и (b) путём решения следующих уравнений.

Цель метода наименьших квадратов — минимизировать остаточную сумму квадратов (RSS) по формуле:

\[ \text{RSS} = \sum_{i=1}^n (y_i - \hat{y}_i)^2 \]

Где:

  • \( y_i \)— фактическое значение.
  • \( \hat{y}_i \)— предсказанное значение, которое\( \hat{y}_i = w x_i + b \)вычисляется моделью линейной регрессии.

Минимизируя RSS, можно получить следующие нормальные уравнения:

\[ \begin{cases} w \sum_{i=1}^n x_i^2 + b \sum_{i=1}^n x_i = \sum_{i=1}^n x_i y_i \\ w \sum_{i=1}^n x_i + b n = \sum_{i=1}^n y_i \end{cases} \]

Матричная форма

Запишите нормальные уравнения в матричной форме:

\[ \begin{bmatrix} \sum_{i=1}^n x_i^2 & \sum_{i=1}^n x_i \\ \sum_{i=1}^n x_i & n \end{bmatrix} \begin{bmatrix} w \\ b \end{bmatrix} = \begin{bmatrix} \sum_{i=1}^n x_i y_i \\ \sum_{i=1}^n y_i \end{bmatrix} \]

Метод решения

Решив приведенное выше матричное уравнение, можно получить оптимальное решение.\( w \)и\( b \):

\[ \begin{bmatrix} w \\ b \end{bmatrix} = \begin{bmatrix} \sum_{i=1}^n x_i^2 & \sum_{i=1}^n x_i \\ \sum_{i=1}^n x_i & n \end{bmatrix}^{-1} \begin{bmatrix} \sum_{i=1}^n x_i y_i \\ \sum_{i=1}^n y_i \end{bmatrix} \]

2. Градиентный спуск

Цель градиентного спуска — минимизировать функцию потерь\( J(w, b) \) . В задачах линейной регрессии в качестве функции потерь обычно используется среднеквадратичная ошибка (MSE):

\[ J(w, b) = \frac{1}{2m} \sum_{i=1}^m (y_i - \hat{y}_i)^2 \]

Где:

  • \( m \)— это количество выборок.
  • \( y_i \)— фактическое значение.
  • \( \hat{y}_i \)— предсказанное значение, которое\( \hat{y}_i = w x_i + b \)вычисляется моделью линейной регрессии.

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

\[ \frac{\partial J}{\partial w} = -\frac{1}{m} \sum_{i=1}^m x_i (y_i - \hat{y}_i) \]

\[ \frac{\partial J}{\partial b} = -\frac{1}{m} \sum_{i=1}^m (y_i - \hat{y}_i) \]

Правила обновления параметров

Градиентный спуск обновляет параметры, используя следующие правила:\( w \)и\( b \):

\[ w := w - \alpha \frac{\partial J}{\partial w} \]

\[ b := b - \alpha \frac{\partial J}{\partial b} \]

Где:

  • \( \alpha \)— это скорость обучения, которая управляет размером шага каждого обновления.

Шаги градиентного спуска

  1. Инициализировать параметры: инициализировать\( w \)и\( b \)значения (обычно устанавливаются в 0 или случайные значения).
  2. Вычислить функцию потерь: вычислить значение функции потерь при текущих параметрах\( J(w, b) \)。
  3. Вычислить градиент: вычислить частную производную функции потерь по\( w \)и\( b \)параметры.
  4. Обновление параметров: обновление в соответствии с градиентом\( w \)и\( b \)。
  5. Повторение итерации: повторяйте шаги со 2 по 4, пока функция потерь не сойдётся или не будет достигнуто максимальное число итераций.

Реализация линейной регрессии на Python

Ниже мы используем простой пример, чтобы продемонстрировать, как реализовать линейную регрессию с помощью Python.

1. Импорт необходимых библиотек

Пример

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

2. Генерация данных

Пример

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Сгенерировать случайные данные
np.random.seed(0)
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)

# Визуализировать данные
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.title('Сгенерированные данные из примера')
plt.show()

Отображение выглядит следующим образом:

3. Использование Scikit-learn для линейной регрессии

Пример

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Сгенерировать случайные данные
np.random.seed(0)
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)

# Создайте модель линейной регрессии
model = LinearRegression()

# Обучение модели
model.fit(x, y)

# Вывод параметров модели
print(f"Наклон (w): {model.coef_)
print(f"Свободный член (b): {model.intercept_)

# Прогнозирование
y_pred = model.predict(x)

# Визуализация результата подгонки
plt.scatter(x, y)
plt.plot(x, y_pred, color='red')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Подгонка линейной регрессии')
plt.show()

Результат вывода:

斜率 (w): 2.968467510701019
截距 (b): 4.222151077447231

Отображение выглядит следующим образом:

Мы можем использоватьscore()метод оценки качества модели, возвращающий значение R^2.

Пример

import numpy as np
from sklearn.linear_model import LinearRegression

# Сгенерировать случайные данные
np.random.seed(0)
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)

# Создайте модель линейной регрессии
model = LinearRegression()

# Обучение модели
model.fit(x, y)
# Расчет оценки модели
score = model.score(x, y)
print("Оценка модели:", score)

Результат вывода:

模型得分: 0.7469629925504755

4. Реализация градиентного спуска вручную

Пример

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Сгенерировать случайные данные
np.random.seed(0)
x = 2 * np.random.rand(100, 1)
y = 4 + 3 * x + np.random.randn(100, 1)

# Инициализация параметров
w = 0
b = 0
learning_rate = 0.1
n_iterations = 1000

# Градиентный спуск
for i in range(n_iterations):
    y_pred = w * x + b
    dw = -(2/len(x)) * np.sum(x * (y - y_pred))
    db = -(2/len(x)) * np.sum(y - y_pred)
    w = w - learning_rate * dw
    b = b - learning_rate * db

# Вывод итоговых параметров
print(f"Наклон (w), реализованный вручную: {w}")
print(f"Вручную реализованный свободный член (b): {b}")

# Визуализация результата ручной подгонки
y_pred_manual = w * x + b
plt.scatter(x, y)
plt.plot(x, y_pred_manual, color='green')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Ручная подгонка градиентным спуском')
plt.show()

Результат вывода:

手动实现的斜率 (w): 2.968467510701028
手动实现的截距 (b): 4.222151077447219

Отображение выглядит следующим образом:

Другие расширения