AI Notebook 4 — Регрессия

Линейные модели, аппроксимация и визуализация регрессионных зависимостей.

Редактировать источник

Дата - 22.04.2023

1.1. Теоретический материал – Линейные регрессионные модели Линейная регрессия

Линейная регрессия (Linear regression) – модель зависимости переменной x от одной или нескольких других переменных (факторов, регрессоров, независимых переменных) с линейной функцией зависимости. Линейная регрессия относится к задаче определения «линии наилучшего соответствия» через набор точек данных и стала простым предшественником нелинейных методов, которые используют для обучения нейронных сетей.

Цель линейной регрессии — поиск линии, которая наилучшим образом соответствует этим точкам. Напомним, что общее уравнение для прямой есть 𝑓 (𝑥) = 𝑏 + 𝑚 ⋅ 𝑥 +, где 𝑚 – наклон линии, а 𝑏 – его сдвиг.

Функция потерь — метод наименьших квадратов

Функция потерь – это мера количества ошибок, которые наша линейная регрессия делает на наборе данных. Хотя есть разные функции потерь, все они вычисляют расстояние между предсказанным значением 𝑦(х) и его фактическим значением. Одна очень распространенная функция потерь называется средней квадратичной ошибкой MSE. Чтобы вычислить MSE, мы просто берем все значения ошибок, считаем их квадраты длин и усредняем.

Задача экраполяции

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

numpy - numpy.linalg.lstsq scipy - scipy.linalg (содержит все функции из numpy.linalg плюс часть новых функций, которых нет в numpy.linalg).

python
import numpy as np
x = np.array([0,1,2,3])
y = ([-1,0.2,0.9,2.1])

#перепишем линейное уравнение y = mx + c как y =Ap, где A = [[ x 1 ]] и 
#p = [[m],[c]]
#Построим A по x:

A = np.vstack([x,np.ones(len(x))]).T
A

#Используем метод lstsq для решения кго относительно вектора p.
m, c = np.linalg.lstsq(A, y, rcond = None)[0]
print(m,c)

#Построим график полученной прямой и укажем на нем точки.
import matplotlib.pyplot as plt 
plt.plot(x,y,'o',label = 'Исходные данные', markersize=10)
plt.plot(x,m*x+c,"r",label = 'Линейгая экстраполяция')
plt.legend()
plt.show()

1.1.2 Пример

Задача: Пусть 𝑥, 𝑦 – вектора длиной 𝑛 > 3 (точек > 3). Задача заключается в построении эстраполяционного полинома второго порядка (параболы). Таким образом, необходимо найти такие коэффициенты поринома 𝑎, 𝑏, 𝑐 по методу наименьших квадратов. Данные мтогут быть получены в результате измерений. Покажем пример генерации данных случайным образом и загрузки их из файла.

python
import numpy as np
import matplotlib.pyplot as plt
from numpy import *
from numpy.random import *
#генерируем случайные x и y
delta = 1.0
x = linspace(-5,5,11)
y = x**2+delta*(rand(11)-0.5)
x += delta*(rand(11)-0.5)

#записываем данные в файл
x.tofile('x_data.txt', '\n')
y.tofile('y_data.txt', '\n')

# читаем данные из файлов
x = fromfile('x_data.txt', float, sep='\n')
y = fromfile('y_data.txt', float, sep='\n')

print(x)
print(y)

# Нахождение коэффициентов функции вида y = ax^2 + bx + c методом наименьших квадратов
# задаем вектор m = [x**2, x, E]
m = vstack((x ** 2, x, ones(11))).T
# находим коэффициенты при составляющих вектора m
s = np.linalg.lstsq(m, y, rcond=None)[0]

# на отрезке [-5,5]
x_prec = linspace(-5, 5, 101)
# рисуем точки
plt.plot(x, y, 'D')
# рисуем кривую вида y = ax^2 + bx + c, подставляя из решения коэффициенты s[0], s[1], s[2]
plt.plot(x_prec, s[0] * x_prec**2 + s[1] * x_prec+s[2], '-', lw=2)
plt.grid()
plt.savefig('парабола.png')

1.1.3 Пример

По данным предыдущего примера постройте эстраполяционного полинома третьего порядка

python
#Решение
# Нахождение коэффициентов функции вида y = ax^3+bx^2+cx+d методом наименьших квадратов
# задаем вектор m = [x**3,x,E]
m = vstack((x**3,x**2,x,ones(11))).T
# находим коэффициенты при составляющих вектора m
s = np.linalg.lstsq(m,y,rcond=None)[0]

# на отрезке [-5, 5]
x_prec = linspace(-5,5,101)
# рисуем точки
plt.plot(x, y, 'D')
# рисуем кривую вида y = ax^3 + bx^2 + cx + d, подставляя коэффициенты s[0], s[1], s[2], s[3]
plt.plot(x_prec, s[0] * x_prec**3 + s[1] * x_prec**2 + s[2] * x_prec + s[3], '-', lw=3)
plt.grid()
plt.savefig('полином 3-й степени.png')

Задание:

Представьте собственные данные и постройте эктраполяцию полиномами первой, второй и третьей степени.

python
x=array([0,7,12,15])
y=array([3,6,9,12])
A=vstack((x,ones(len(x)))).T
m,c = np.linalg.lstsq(A,y,rcond=None)[0]
plt.plot(x,y,'o',markersize=10)
plt.plot(x,m*x+c,'r')
plt.legend()
plt.show()
delta = 1.0
x= linspace(-10,10,10)
y= x**2+delta*(rand(10))
x+= delta*(rand(10))
m= vstack((x ** 2, x, ones(10))).T
s= linalg.lstsq(m, y, rcond=None)[0]
x_prec=linspace(-10,10,100)
plt.plot(x,y,'D')
plt.plot(x_prec,s[0]*x_prec**2+s[1]*x_prec+s[2],'-',lw=2)
plt.grid()
plt.savefig('парабола.png')
plt.show()
m=vstack((x ** 3, x ** 2, x, ones(10))).T
s=linalg.lstsq(m, y, rcond=None)[0]
x_prec=linspace(-10,10,100)
plt.plot(x,y,'D')
plt.plot(x_prec,s[0]*x_prec**3+s[1]*x_prec**2+s[2]*x_prec+s[3],'-',lw=3)
plt.grid()
plt.savefig('полином 3-й степени.png')
plt.show()

1.1.4 Пример

Задача: Необходимо проверить гипотезу, что наши точечно заданная функция ложится на кривую вида 𝑓(𝑥, 𝑏) = 𝑏0 + 𝑏1𝑒𝑥𝑝(−𝑏^2𝑥^2)

python
#Добавим шума в данные, сделанные по функции f(x, b) с коэффициентами b = (0.25, 0.75, 0.5)
beta=(0.25,0.75,0.5)
def f(x,b0,b1,b2):
    return b0+b1*exp(-b2* x**2)
# зададим массив точек xi
xdata=linspace(0,5,50)
# создаем теоретически правильные значения точек yi (без шума)
y=f(xdata,*beta)
# зашумляем эти данные
ydata=y+0.05*randn(len(xdata))

#Используем функцию для получения решения в виде коэффициентов функции f(x) для указанных xdata и ydata
from scipy.optimize import curve_fit
beta_opt,beta_cov = curve_fit(f, xdata, ydata)
beta_opt

#Вычислим линейное отклонение
lin_dev=sum(beta_cov[0])
print(lin_dev)

#Вычислим квадратичное отклонение
residuals = ydata-f(xdata,*beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata,ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata,f(xdata,*beta_opt),'b',lw=2)
ax.set_xlim(0, 5)
ax.set_xlabel(r"$x$",fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$",fontsize=18)
plt.show()

print(xdata)
print(ydata)

1.1.5 Пример

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

  1. 𝑓(𝑥, 𝑏) = 𝑏0 + 𝑏1𝑥

  2. 𝑓(𝑥, 𝑏) = 𝑏0 + 𝑏1𝑥 + 𝑏2𝑥2

  3. 𝑓(𝑥, 𝑏) = 𝑏0 + 𝑏1𝑙𝑛(𝑥)

  4. 𝑓(𝑥, 𝑏) = 𝑏0 𝑥𝑏

python
#решение
#1
#Добавим шума в данные, сделанные по функции f(x,b) c коэффицентами beta=(0.25,0.75)
beta=(0.25,0.75)
def f(x,b0,b1):
    return b0+b1*x
#зададим массив точек xi
xdata = linspace(0, 5, 50)
#cоздаем теоретически правильные значения точек yi(без шума)
y = f(xdata, *beta)
#зашумляем эти данные
ydata = y + 0.05 * randn(len(xdata))
beta_opt, beta_cov = curve_fit(f, xdata, ydata)
print(beta_opt)
#Вычисляемлинейное отклонение
lin_dev = sum(beta_cov[0])
print(lin_dev)
#Вычисляем квадратичное отклонение
residuals = ydata - f(xdata, *beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata, ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2)
ax.set_xlim(0, 5)
ax.set_xlabel(r"$x$", fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)
plt.show()

#решение
#2
#Добавим шума в данные, сделанные по функции f(x,b) с коэффицентами b = (0.25б 0.75,0.5)
beta = (0.25, 0.75, 0.5)
def f(x, b0, b1, b2):
    return b0 + b1 * x + b2 * x**2
#зададим массив точек xi
xdata = linspace(0, 5, 50)
#создаем теоретически правильные значения точек yi(без шума)
y = f(xdata, *beta)
#зашумляем эти данные 
ydata = y + 0.05 * randn(len(xdata))
beta_opt, beta_cov = curve_fit(f, xdata, ydata)
print(beta_opt)
#Вычислим линейное отклонение
lin_dev = sum(beta_cov[0])
print(lin_dev)

#вычислить квадратичное отклонение
residuals = ydata - f(xdata, *beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata, ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2)
ax.set_xlim(0, 5)
ax.set_xlabel(r"$x$", fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)
plt.show()

#решение
#3
#Добавим шума в данные, сделанные по функции f(x,b) с коэффицентами b = (1,2)
beta = (1, 2)
def f(x, b0, b1):
    return b0 + b1 * log(x)
#заданим массив точек xi
xdata = linspace(1, 5, 50)
#созадем теоретически правильные значения точек yi(без шума)
y = f(xdata, *beta)
#зашумляем эти данные
ydata = y + 0.05 * randn(len(xdata))
beta_opt, beta_cov = curve_fit(f, xdata, ydata)
print(beta_opt)
#Вычислим линейное отклонение
lin_dev = sum(beta_cov[0])
print(lin_dev)

#Вычислим квадратичное отклонение
residuals = ydata - f(xdata, *beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata, ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2)
ax.set_xlim(0, 5)
ax.set_xlabel(r"$x$", fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)
plt.show()

#решение
#4
#Добавим шума в данные, сделанные по функции f(x,b) с коэффицентами b = (1,2)
beta = (1, 2)
def f(x, b0, b1):
    return b0 * x ** b1
#заданим массив точек xi
xdata = linspace(1, 5, 50)
#созадем теоретически правильные значения точек yi(без шума)
y = f(xdata, *beta)
#зашумляем эти данные
ydata = y + 0.05 * randn(len(xdata))
beta_opt, beta_cov = curve_fit(f, xdata, ydata)
print(beta_opt)
#Вычислим линейное отклонение
lin_dev = sum(beta_cov[0])
print(lin_dev)

#Вычислим квадратичное отклонение
residuals = ydata - f(xdata, *beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata, ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2)
ax.set_xlim(0, 5)
ax.set_xlabel(r"$x$", fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)
plt.show()

Задание:

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

python
beta = (8,88,888)
def f(x, b0, b1, b2):
    return b0 + b1 * x + b2 * x**2
#заданим массив точек xi
xdata = linspace(-7, 7, 100)
#созадем теоретически правильные значения точек yi(без шума)
y = f(xdata, *beta)
#зашумляем эти данные
ydata = y + 50 * randn(len(xdata))
beta_opt, beta_cov = curve_fit(f, xdata, ydata)
print(beta_opt)
#Вычислим линейное отклонение
lin_dev = sum(beta_cov[0])
print(lin_dev)

#Вычислим квадратичное отклонение
residuals = ydata - f(xdata, *beta_opt)
fres = sum(residuals**2)
print(fres)

fig, ax = plt.subplots()
ax.scatter(xdata, ydata)
ax.plot(xdata, y, 'r', lw=2)
ax.plot(xdata, f(xdata, *beta_opt), 'b', lw=2)
ax.set_xlim(0, 50)
ax.set_xlabel(r"$x$", fontsize=18)
ax.set_ylabel(r"$f(x, \beta)$", fontsize=18)
plt.show()

1.2. Теоретический материал – Задачи регрессии

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

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

1.2.1 Пример

Задача: Построим простую линейную регрессию в Python с использованием библиотеки scikit-learn

python
#Импортируем необходимые библиотеки
#используем pandas и numpy для обработки данных
#matpoltlib для визуализации и sklearn для обучения набора данных и импорта моделей
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import DataFrame, Series
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression

#создадим набор данных для описания взаимосвязи между временем обучения студентов и успеваймостью
my_dict = {
    'Учебное время': [0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5, 4.75, 5.0, 5.5],
    'Оценка': [10, 22, 13, 43, 20, 22, 33, 50, 62, 48, 55, 75, 62, 73, 81, 76, 64, 82, 90, 93]
}

dataset = DataFrame(my_dict)
print(dataset.head(5))

#исследуем набор данных 
print(dataset.shape)
print(dataset.describe())

#Рисуем диаграмму
plt.scatter(dataset['Учебное время'], dataset['Оценка'], color='b', label='Данные экзамена')
plt.xlabel('Часы')
plt.ylabel('Оценка')
plt.show()

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

python
x = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 1].values
print(x)
print(y)

#Теперь когда у нас есть атрибуты и метки, необходимость разделить их на а обучающий и тестовый наборы.
#приведенный фрагмент 80 % данных на обучающий набор, а 20% данных - на набор тестов
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
#далее можно обучить алгоритм линейной регрессии 
#необходимо импортировать класс LinelRegression, создать его экземпляр и вызвать метод fit()
regressor = LinearRegression()
regressor.fit(x_train, y_train)
#приведем полученные коэффиценты для линейной регрессии 
print(regressor.intercept_)
print(regressor.coef_)

Вывод:

code
[[1.0000e+00 3.5710e+03 1.9760e+03 5.2500e-01]
 [2.0000e+00 4.0920e+03 1.2500e+03 5.7200e-01]
 [3.0000e+00 3.8650e+03 1.5860e+03 5.8000e-01]
 [4.0000e+00 4.8700e+03 2.3510e+03 5.2900e-01]
 [3.0000e+00 4.3990e+03 4.3100e+02 5.4400e-01]
 [4.0000e+00 5.3420e+03 1.3330e+03 5.7100e-01]
 [5.0000e+00 5.3190e+03 1.1868e+04 4.5100e-01]
 [3.0000e+00 5.1260e+03 2.1380e+03 5.5300e-01]
 [5.0000e+00 4.4470e+03 8.5770e+03 5.2900e-01]
 [5.0000e+00 4.5120e+03 8.5070e+03 5.5200e-01]
 [4.0000e+00 4.3910e+03 5.9390e+03 5.3000e-01]
 [5.0000e+00 5.1260e+03 1.4186e+04 5.2500e-01]
 [4.0000e+00 4.8170e+03 6.9300e+03 5.7400e-01]
 [5.0000e+00 4.2070e+03 6.5800e+03 5.4500e-01]
 [4.0000e+00 4.3320e+03 8.1590e+03 6.0800e-01]
 [5.0000e+00 4.3180e+03 1.0340e+04 5.8600e-01]
 [6.0000e+00 4.2060e+03 8.5080e+03 5.7200e-01]
 [0.0000e+00 3.7180e+03 4.7250e+03 5.4000e-01]
 [6.0000e+00 4.7160e+03 5.9150e+03 7.2400e-01]
 [3.0000e+00 4.3410e+03 6.0100e+03 6.7700e-01]
 [1.0000e+00 4.5930e+03 7.8340e+03 6.6300e-01]
 [3.0000e+00 4.9830e+03 6.0200e+02 6.0200e-01]
 [1.0000e+00 4.8970e+03 2.4490e+03 5.1100e-01]]
[3571. 4092. 3865. 4870. 4399. 5342. 5319. 5126. 4447. 4512. 4391. 5126.
 4817. 4207. 4332. 4318. 4206. 3718. 4716. 4341. 4593. 4983. 4897.]
-9.094947017729282e-13
[5.75398478e-13 1.00000000e+00 1.11022302e-16 3.44246345e-14]

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

python
y_pred = regressor.predict(x_test)
#сравним фактические значения с прогнозиремыми
df = DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

#визуализируем результат сравнения 
df.plot(kind='bar')
plt.grid(which='major', linestyle='-', linewidth='0.5', color='green')
plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.show()
#построим линию регресии с тестовыми данными 
plt.scatter(x_test, y_test, color='gray')
plt.plot(x_test, y_pred, color='red', linewidth=2)
plt.show()

Задание:

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

(https://raw.githubusercontent.com/AnnaShestova/salary-years-simple-linearregression/master/Salary_Data.csv).

Найдите коэффициенты линии регрессии. Постройте прогноз.

python
url = r'https://raw.githubusercontent.com/AnnaShestova/salary-years-simple-linear-regression/master/Salary_Data.csv'
dataset = pd.read_csv(url)
print(dataset.head(5))

print(dataset.shape)
print(dataset.describe())

plt.scatter(dataset['YearsExperience'], dataset['Salary'], color='b', label='Salary data')
plt.xlabel('Experience')
plt.ylabel('Salary')
plt.show()

x = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 1].values
print(x)
print(y)

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

regressor = LinearRegression()
regressor.fit(x_train, y_train)

print(regressor.intercept_)
print(regressor.coef_)

y_pred = regressor.predict(x_test)
df = DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

df.plot(kind='bar')
plt.grid(which='major', linestyle='-', linewidth='0.5', color='green')
plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.show()

plt.scatter(x_test, y_test, color='blue')
plt.plot(x_test, y_pred, color='green', linewidth=2)
plt.show()

1.3. Теоретический материал – Множественная регрессия

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

1.3.1 Пример

Задача: Для решения задачи множественной регрессии можно задействовать уже известный метод numpy.linalg.lstsq.

python
import numpy as np

y = [1,2,3,4,3,4,5,3,5,5,4,5,4,5,4,5,6,0,6,3,1,3,1]
x = [[0,2,4,1,5,4,5,9,9,9,3,7,8,8,6,6,5,5,5,6,6,5,5],
    [4,1,2,3,4,5,6,7,5,8,7,8,7,8,7,8,6,8,9,2,1,5,6],
    [4,1,2,5,6,7,8,9,7,8,7,8,7,4,3,1,2,3,4,1,3,9,7]]

x = np.transpose(x) # transpose to input vectors
x = np.c_[x, np.ones(x.shape[0])] # add bias term
linreg = np.linalg.lstsq(x, y, rcond=None)[0]
print(linreg)

Вывод:

code
[ 0.1338682   0.26840334 -0.02874936  1.5122571 ]

1.3.2 Пример

Задача: Для данных из предыдущей задачи построить модель множественной линейной регрессии с использованием средств библиотеки sсikit-learn.

python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as seabornInstance
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn import metrics

y = [1,2,3,4,3,4,5,3,5,5,4,5,4,5,4,5,6,0,6,3,1,3,1]
x = [[0,2,4,1,5,4,5,9,9,9,3,7,8,8,6,6,5,5,5,6,6,5,5],
    [4,1,2,3,4,5,6,7,5,8,7,8,7,8,7,8,6,8,9,2,1,5,6],
    [4,1,2,5,6,7,8,9,7,8,7,8,7,4,3,1,2,3,4,1,3,9,7]]

# формируем DataFrame из двух списков
new_y = np.array(y)
new_y = new_y.transpose()
df1 = pd.DataFrame(new_y)
new_x = np.array(x)
new_x = new_x.transpose()
df2 = pd.DataFrame(new_x)
df1 = df1.rename(columns={0: 'y'}, inplace=False)
df2 = df2.rename(columns={0: 'x1', 1: 'x2', 2: 'x3'}, inplace=False)

frames = [df1, df2]
dataset = pd.concat([df1, df2], axis=1, join='inner')
print(dataset.head())

#изучим данные
print(dataset.shape)
print(dataset.describe())

#разделим данные на метки и атрибуты
x = dataset[['x1', 'x2', 'x3']]
y = dataset['y']

#раздлеим данные на обуччающую и тестовую выборки
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

#для обучения алгоритма мы выполняем тот же код, что и раньше, используя метод fit() класса LinearRegression
regressor = LinearRegression()
regressor.fit(x_train, y_train)

#выведем кожффициенты модели 
coeff_df = pd.DataFrame(regressor.coef_, x.columns, columns=['Coefficient'])
coeff_df

#Чтобы сделать прогнозы на тестовых данных, выполните следующий код
y_pred = regressor.predict(x_test)
df = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

#Последний шаг - оценить производительность алгоритма. Мы сделаем это, найдя значения для MSE
print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))

Вывод:

code
   y  x1  x2  x3
0  1   0   4   4
1  2   2   1   1
2  3   4   2   2
3  4   1   3   5
4  3   5   4   6
(23, 4)
               y         x1         x2         x3
count  23.000000  23.000000  23.000000  23.000000
mean    3.565217   5.347826   5.521739   5.043478
std     1.674029   2.404706   2.428422   2.704849
min     0.000000   0.000000   1.000000   1.000000
25%     3.000000   4.500000   4.000000   3.000000
50%     4.000000   5.000000   6.000000   5.000000
75%     5.000000   6.500000   7.500000   7.000000
max     6.000000   9.000000   9.000000   9.000000
Mean Squared Error: 1.3272699242343076

Задание

Постройте модель множественной линейной регрессии для произвольных данных из нескольких столбцов. Для примера можно взять потребления газа (в миллионах галлонов) в 48 штатах США или набор данных о качестве красного вина (1) и (2) соответственно. Найдите коэффициенты множественной регрессии. Постройте прогноз. 1. https://raw.githubusercontent.com/likarajo/petrol_consumption/master/data/pe trol_consumption.csv 2. https://raw.githubusercontent.com/aniruddhachoudhury/Red-WineQuality/master/winequality-red.csv

python
url = r'https://raw.githubusercontent.com/likarajo/petrol_consumption/master/data/petrol_consumption.csv'
dataset = pd.read_csv(url)
print(dataset.head(5))

y = list(dataset['Petrol_tax'])
x = [list(dataset['Average_income']),
        list(dataset['Paved_Highways']),
        list(dataset['Population_Driver_licence(%)']),
        list(dataset['Petrol_Consumption'])]

new_y = new_y.transpose()
df1 = pd.DataFrame(new_y)
new_x = np.array(x)
new_x = new_x.transpose()
df2 = pd.DataFrame(new_x)
df1 = df1.rename(columns={0: 'y'}, inplace=False)
df2 = df2.rename(columns={0: 'x1', 1: 'x2', 2: 'x3'}, inplace=False)

frames = [df1, df2]
dataset = pd.concat([df1, df2], axis=1, join='inner')
print(dataset.head())

print(dataset.shape)
print(dataset.describe())

x = dataset[['x1', 'x2', 'x3']]
y = dataset['y']

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)

regressor = LinearRegression()
regressor.fit(x_train, y_train)

coeff_df = pd.DataFrame(regressor.coef_, x.columns, columns=['Coefficient'])
coeff_df

y_pred = regressor.predict(x_test)
df = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))

Вывод:

code
   Petrol_tax  Average_income  Paved_Highways  Population_Driver_licence(%)  \
0         9.0            3571            1976                         0.525   
1         9.0            4092            1250                         0.572   
2         9.0            3865            1586                         0.580   
3         7.5            4870            2351                         0.529   
4         8.0            4399             431                         0.544   

   Petrol_Consumption  
0                 541  
1                 524  
2                 561  
3                 414  
4                 410  
   y      x1      x2     x3      3
0  1  3571.0  1976.0  0.525  541.0
1  2  4092.0  1250.0  0.572  524.0
2  3  3865.0  1586.0  0.580  561.0
3  4  4870.0  2351.0  0.529  414.0
4  3  4399.0   431.0  0.544  410.0
(23, 5)
               y           x1            x2         x3           3
count  23.000000    23.000000     23.000000  23.000000   23.000000
mean    3.565217  4529.913043   5573.652174   0.567957  540.869565
std     1.674029   484.049764   3856.453123   0.058789  112.101539
min     0.000000  3571.000000    431.000000   0.451000  344.000000
25%     3.000000  4262.500000   2057.000000   0.529500  465.500000
50%     4.000000  4447.000000   5939.000000   0.553000  525.000000
75%     5.000000  4883.500000   8333.000000   0.583000  591.500000
max     6.000000  5342.000000  14186.000000   0.724000  865.000000
Mean Squared Error: 4.749488311367661