Машинное обучение

Введение в машинное обучение: линейная регрессия

Как сделать линейную регрессию с помощью SKLearn

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

Сначала я покажу вам пример того, как линейная регрессия работает через sklearn, а затем мы создадим проект, который запускает линейную регрессию в файле .csv. Для этого проекта нашими примерными данными будут квадратные метры квартиры по сравнению с арендной платой.

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

Прежде чем мы начнем, если у вас не установлены библиотеки numpy, pandas, sklearn и matplotlib, нам нужно их установить, я использую pip, но вы также можете использовать conda, если используете установку Anaconda Python.

pip install numpy pandas sklearn matplotlib

Начнем с импорта необходимых библиотек.

libraries for linear regression with sklearn
import numpy as np
import math
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import random

Линейная регрессия с рандомизированным набором данных

Далее мы случайным образом сгенерируем набор значений y из значений x. Сделаем функцию y = 2x с дисперсией +/- 0.1

randomize a dataset for linear regression
arr = [1, 3, 5, 7, 9]
def _func(x):
    return 2 * x + random.uniform(-.1, .1)
x_arr = np.array(arr).reshape(-1, 1)
y_1 = [_func(a) for a in arr]
y_arr = np.array(y_1)

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

print(x_arr)
print(y_arr)
# expected output
[[1]
 [3]
 [5]
 [7]
 [9]]
[ 2.07448972  5.9836436  10.02023471 13.99454233 17.97974717]

Мы собираемся вызвать LinearRegression(), чтобы подогнать наши точки к модели, а затем мы нанесем сгенерированную линию на наши исходные точки.

run linear regression from sklearn
model = LinearRegression().fit(x_arr, y_arr)
plt.scatter(x_arr, y_arr)
plt.plot(x_arr, model.predict(x_arr))
plt.show()

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

print(model.coef_)
print(model.intercept_)
# expected output
[1.99107068]
0.05517809795209949

Отлично, мы убедились, что линейная регрессия возвращает значения, близкие к ожидаемым, теперь давайте проверим среднее отклонение на прогноз. Для этого мы возьмем среднеквадратичную ошибку (MSE), разделим ее на количество записей, а затем возьмем квадратный корень.

mse = sum((y_arr - model.predict(x_arr))**2)
avg_err = math.sqrt(mse/5)
avg_err
# expected output
0.02417347631277344

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

def mse(i, j):
    return sum((i - j)**2)
def avg_err(sum_err, _len):
    return math.sqrt(sum_err/_len)

Мы видим, что наша средняя ошибка также находится в пределах 0,1. Когда мы создавали нашу функцию, мы добавили смещение +/- 0,1 для рандомизации, и наша средняя ошибка прогноза на запись, составляющая менее 0,1, подтверждает, что наша модель линейной регрессии дает хороший прогноз.

Линейная регрессия с реальными данными из CSV

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

run sklearn linear regression on real csv data
arrs = np.genfromtxt("lin_reg_data.csv", delimiter=",", skip_header=1)
x = arrs[:, 0].reshape(-1, 1)
y = arrs[:, 1]
model = LinearRegression().fit(x, y)

Давайте проверим среднюю ошибку на вход (мы ожидаем, что она будет меньше 100), коэффициенты и точку пересечения и посмотрим, как выглядит наша линия на графике относительно обычных точек.

# average error
_len = y.size
_avg_err = avg_err(mse(y, model.predict(x)), _len)
print("The average price error per apartment from this model is", _avg_err)
# coefficients and intercepts
print("The linear scaling coefficient for square feet in this model is", model.coef_[0])
print("The offsetting price/intercept of this model is", model.intercept_)
# plot
plt.scatter(x, y)
plt.plot(x, model.predict(x), color="black")
# expected output
The average price error per apartment from this model is 62.58835009983644
The linear scaling coefficient for square feet in this model is 3.6575960237228298
The offsetting price/intercept of this model is 1.3200558525759334

Прохладный! Модель выглядит довольно хорошо, И наша средняя ошибка цены находится в пределах 100, как и ожидалось. Арендная плата в этом городе (Сиэтле) очень дорогая — 3,66 доллара за квадратный фут. Мы видим, что точка пересечения равна 1,32, и это тоже выглядит примерно так, потому что мы сделали вполне разумное предположение о том, что цена квартиры напрямую зависит от площади в квадратных метрах.
Теперь для нашего последнего пошагового проекта мы собирается попытаться подогнать линейную модель к весу деревьев лиственных пород в тоннах на основе их высоты и радиуса.

sklearn linear regression on 3d csv data
arrs = np.genfromtxt("trees.csv", delimiter=",", skip_header=1)
x = arrs[:, 0:2].reshape(-1, 2)
y = arrs[:, 2]
model = LinearRegression().fit(x, y)

Теперь давайте построим модель (в 3D!) и получим оценку R^2.

plot 3D linear regression output
x1 = []
x2 = []
for entry in x:
    x1.append(entry[0])
    x2.append(entry[1])
fig = plt.figure()
ax = plt.axes(projection = '3d')
ax.scatter(x1, x2, y, alpha=0.3)
ax.plot(x1, x2, model.predict(x), color='black')

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

print("Our R squared value is", model.score(x, y))
# expected output
Our R squared value is 0.9824677872384431

Вау, это действительно хорошее значение R^2, чем ближе значение R^2 к 1, тем точнее линейная модель. Давайте также взглянем на коэффициенты и перехват.

print(model.coef_)
print(model.intercept_)
# expected output
[0.12629947 0.05877378]
-3.575930068798057

Заключение

Глядя на коэффициенты и точку пересечения нашей модели, мы видим, что, несмотря на то, насколько хорошо наша плоскость соответствовала этим значениям, эта модель на самом деле не имеет смысла. Прогнозируемое нами значение — это вес дерева в тоннах, поэтому точка пересечения -3,76 не имеет смысла, мы должны ожидать точку пересечения, равную 0.

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

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

Еще от автора

Если вам понравилась эта статья, поделитесь ею в Твиттере! Чтобы получить неограниченный доступ к статьям Medium, зарегистрируйтесь, чтобы стать членом Medium сегодня! Не забудьте подписаться на меня, Юйцзянь Тан, чтобы получать больше статей о росте, технологиях и многом другом!