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

Что такое модель?

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

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

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

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

В этой части мы рассмотрим следующие цели:

  • Описать, как обрабатывать линейную регрессию в Python.
  • Примените оценку модели, используя визуализацию в Python.
  • Применение методов полиномиальной регрессии к Python.
  • Оцените модель данных с помощью визуализации.
  • Опишите использование R-квадрата и MSE для оценки в выборке.
  • Применяйте прогнозирование и принятие решений к созданию модели Python.

Настройка — импорт данных

Импортировать библиотеки.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

Загрузите данные и сохраните их во фрейме данных df:

Этот набор данных был размещен на объекте IBM Cloud.

# path of data
path = 'https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DA0101EN-SkillsNetwork/labs/Data%20files/automobileEDA.csv'
df = pd.read_csv(path)
df.head()

Примечание. Чтобы лучше понять данные и шаги, которые я предпринял для их очистки, я настоятельно рекомендую прочитать Анализ данных с помощью Python — обработка данных — часть 1. >» и Анализ данных с помощью Python — Исследовательский анализ данных (EDA) — Часть 2.

Для справки, Блокнот также доступен здесь.

Линейная регрессия и множественная линейная регрессия

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

Один из примеров модели данных, которую мы будем использовать:

Простая линейная регрессия

Простая линейная регрессия — это метод, помогающий нам понять взаимосвязь между двумя переменными:

  • Предиктор/независимая переменная — X
  • Отклик/зависимая переменная (которую мы хотим предсказать) — Y

Результатом линейной регрессии является линейная функция, которая предсказывает переменную ответа (зависимую) как функцию переменной-предиктора (независимой).

Линейная функция

  • a относится к пересечению линии регрессии, другими словами: к значению Y, когда X равно 0.
  • b относится к наклону линии регрессии, другими словами: значению, с которым меняется Y, когда X увеличивается на 1 единицу.

Давайте загрузим модули для линейной регрессии:

from sklearn.linear_model import LinearRegression

Создайте объект линейной регрессии:

lm = LinearRegression()
lm

Как «хайвэй-миль на галлон» может помочь нам прогнозировать цену автомобиля?

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

X = df[["highway-mpg"]]
Y = df[["price"]]

Соответствуйте линейной модели с помощью шоссе-миль на галлон:

lm.fit(X,Y)

Мы можем вывести прогноз:

Yhat = lm.predict(X)
Yhat[0:5]

Выход: array([16236.50464347, 16236.50464347, 17058.23802179, 13771.3045085, 20345.17153508])

Какова ценность перехвата (а)?

lm.intercept_

Вывод: 38423.3058581574

Каково значение наклона (b)?

lm.coef_

Вывод:array([-821.73337832])

Какую окончательную оценочную линейную модель мы получим?

Как мы видели выше, мы должны получить окончательную линейную модель со структурой:

Подставляя фактические значения, мы получаем:

Цена = 38423,31 – 821,73 * миль на галлон по шоссе

Множественная линейная регрессия

Что, если мы хотим предсказать цены на автомобили, используя более одной переменной?

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

Уравнение дано:

Из предыдущего раздела мы знаем, что другими хорошими предикторами цены могут быть:

  • Лошадиные силы
  • Снаряженная масса
  • Размер двигателя
  • Шоссе-миль на галлон

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

Z = df[["horsepower", "curb-weight", "engine-size", "highway-mpg"]]

Соответствуйте линейной модели с помощью четырех переменных, упомянутых выше.

lm.fit(Z, df["price"])

Какова ценность перехвата (а)?

lm.intercept_

Вывод: -15806.62462632923

Каковы значения коэффициентов (b1, b2, b3, b4)?

lm.coef_

Вывод: array([53.49574423, 4.7077099, 81.53026382, 36.05748882])

Какова окончательная оценочная линейная модель, которую мы получаем?

Как мы видели выше, у нас должна получиться итоговая линейная функция со структурой:

Какую линейную функцию мы получим в этом примере?

Цена = -15678,742628061467 + 52,65851272 * мощность + 4,69878948 * снаряженная масса + 81,95906216 * объем двигателя + 33,58258185 * шоссе-миль на галлон

Давайте создадим и обучим модель множественной линейной регрессии «lm2», где переменной ответа является «цена», а переменной-предиктором — «нормализованные потери» и «хайвей-миль на галлон».

lm2 = LinearRegression()
lm2.fit(df[["normalized-losses", "highway-mpg"]], df["price"])

Найдите коэффициент модели.

lm2.coef_

Вывод: array([1.49789786, -820.45434016])

Оценка модели с помощью визуализации

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

Импортируйте пакет визуализации seaborn:

# import the visualization package: seaborn
import seaborn as sns
%matplotlib inline

График регрессии

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

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

Давайте визуализируем highway-mpg как потенциальную переменную-предиктор цены:

width = 12
height = 10
plt.figure(figsize=(width, height))
sns.regplot(x="highway-mpg", y="price", data=df)
plt.ylim(0,)

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

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

Давайте сравним этот график с графиком регрессии «пиковых оборотов».

plt.figure(figsize=(width, height))
sns.regplot(x="peak-rpm", y="price", data=df)
plt.ylim(0,)

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

На приведенных выше графиках регрессии «пиковые обороты» или «расходы на галлон по трассе» сильнее коррелируют с «ценой»? Используйте метод «.corr()», чтобы проверить свой ответ.

df[["peak-rpm","highway-mpg","price"]].corr()

Остаточный участок

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

Что такое остаток?

Разница между наблюдаемым значением (y) и прогнозируемым значением (Yhat) называется остатком (e). Когда мы смотрим на график регрессии, невязка — это расстояние от точки данных до подобранной линии регрессии.

Так что же такое остаточный график?

График остатков — это график, который показывает остатки по вертикальной оси Y и независимую переменную по горизонтальной оси X.

На что мы обращаем внимание, когда смотрим на остаточный участок?

Смотрим на разброс остатков:

  • Если точки на остаточном графике случайно разбросаны по оси x, то для данных подходит линейная модель.

Что это такое? Случайно распределенные остатки означают, что дисперсия постоянна, и поэтому линейная модель хорошо подходит для этих данных.

width = 12
height = 10
plt.figure(figsize=(width, height))
sns.residplot(df["highway-mpg"], df["price"])
plt.show()

О чем говорит нам этот график?

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

Множественная линейная регрессия

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

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

Сначала сделаем прогноз:

Y_hat = lm.predict(Z)
plt.figure(figsize=(width, height))
ax1 = sns.distplot(df["price"], hist=False, color="r", label="Actual Value")
sns.distplot(Y_hat, hist=False, color="b", label="Fitted Values",ax=ax1)
plt.title("Actual vs Fitted Values for Price")
plt.xlabel("Price (in dollars)")
plt.ylabel("Proportion of Cars")
plt.show()
plt.close()

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

Полиномиальная регрессия и конвейеры.

Полиномиальная регрессия — это частный случай общей модели линейной регрессии или моделей множественной линейной регрессии.

Мы получаем нелинейные отношения, возводя в квадрат или устанавливая члены более высокого порядка переменных-предикторов.

Существуют различные порядки полиномиальной регрессии:

Ранее мы видели, что линейная модель не дает наилучшего соответствия при использовании «highway-mpg» в качестве переменной-предиктора. Давайте посмотрим, можем ли мы вместо этого попробовать подогнать к данным полиномиальную модель.

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

# Define a function PlotPolly 
def PlotPolly(model, independent_variable, dependent_variable, Name):
   x_new = np.linespace(15, 55, 100)
   y_new = model(x_new)
   plt.plot(independent_variable, dependent_variable, ".", x_new, y_new, "-")
   plt.title("Polynomial Fit with Matplotlib for Price ~ Length")
   ax = plt.gca()
   ax.set_facecolor((0.898, 0.898, 0.898))
   fig = plt.gcf()
   plt.xlabel(Name)
   plt.ylabel("Price of Cars")
   plt.show()
   plt.close()

Получим переменные:

x = df["highway-mpg"]
y= df["price"]

Подгоним полином с помощью функции polyfit, а затем воспользуемся функцией poly1d для отображения полиномиальной функции.

# Here we use a polynomial of the 3rd order (cubic)
f = np.polyfit(x, y, 3)
p = np.poly1d(f)
print(p)

Вывод: -1.557 x + 204.8 x — 8965 x + 1.379e+05

Нарисуем функцию:

PlotPolly(p, x, y, "highway-mpg")

np.polyfit(x, y, 3)

Вывод: array([-1.55663829e+00, 2.04754306e+02, -8.96543312e+03, 1.37923594e+05])

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

Давайте создадим полиномиальную модель 11-го порядка с переменными x и y, указанными выше.

# Here we use a polynomial of the 11rd order (cubic)
f1 = np.polyfit(x, y, 11)
p1 = np.poly1d(f1)
print(p1)
PlotPolly(p1, x, y, "Highway MPG")

11 10 9 8 7 -1.243e-08 x + 4.722e-06 x — 0.0008028 x + 0.08056 x — 5.297 x 6 5 4 3 2 + 239.5 x — 7588 x + 1.684e+05 x — 2.565e+06 x + 2.551e+07 x — 1.491e+08 x + 3.879e+08

Аналитическое выражение для многомерной полиномиальной функции усложняется. Например, выражение для многочлена второго порядка (степень = 2) с двумя переменными имеет вид:

Мы можем выполнить полиномиальное преобразование для нескольких функций. Сначала мы импортируем модуль:

from sklearn.preprocessing import PolynomialFeatures

Мы создаем объект PolynomialFeatures степени 2:

pr=PolynomialFeatures(degree=2)
pr
Z_pr=pr.fit_transform()

В исходных данных 201 образец и 4 признака.

Z.shape

Вывод: (201, 4)

После преобразования остается 201 образец и 15 признаков.

Z_pr.shape

Вывод: (201, 15)

Трубопровод

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

from sklearn.pipline import Pipeline
from sklearn.preprocessing import StandardScaler

Мы создаем конвейер, создавая список кортежей, включая имя модели или оценщика и соответствующий ему конструктор.

Input=[("scale", StandardScaler()),("polynomial", PolynomialFeatures(include_bias=False)), ("model", LinearRegression())]

Мы вводим список в качестве аргумента конструктору конвейера:

pipe=Pipeline(Input)
pipe

Во-первых, мы преобразуем тип данных Z в тип float, чтобы избежать предупреждений о преобразовании, которые могут появиться в результате того, что StandardScaler принимает входные данные с плавающей запятой.

Затем мы можем нормализовать данные, выполнить преобразование и одновременно подобрать модель.

z = Z.astype(float)
pipe.fit(Z, y)

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

ypipe = pipe.predict(Z)
ypipe[0:4]

Вывод:array([13102.74784201, 13102.74784201, 18225.54572197, 10390.29636555])

Меры для оценки в выборке

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

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

  • R²/R-квадрат
  • Среднеквадратическая ошибка (MSE)

R-квадрат

R-квадрат, также известный как коэффициент детерминации, является мерой, показывающей, насколько данные близки к подобранной линии регрессии.

Значение R-квадрата представляет собой процент изменения переменной отклика (y), который объясняется линейной моделью.

Среднеквадратическая ошибка (MSE)

Среднеквадратическая ошибка измеряет среднее значение квадратов ошибок. Это разница между фактическим значением (y) и расчетным значением (ŷ).

Модель 1: простая линейная регрессия

Рассчитаем R²:

#highwa_mpg_fit
lm.fit(X, Y)
# Find the R^2
print("The R-square is: ", lm.score(X, Y))

Вывод:The R-square is: 0.4965911884339176

Можно сказать, что ~49,659% вариации цены объясняется этой простой линейной моделью «лошадиная сила_подгонка».

Рассчитаем MSE:

Мы можем предсказать результат, т. е. «yhat», используя метод прогнозирования, где X — входная переменная:

Yhat = lm.predict(X)
print("The out of the first four predicted value is: ", Yhat[0:4])

Вывод: The output of the first four predicted value is: [16236.50464347 16236.50464347 17058.23802179 13771.3045085]

Импортируем функцию mean_squared_error из модуля metrics:

from sklearn.metrics import mean_squared_error

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

mse = mean_squared_error(df["price"], Yhat)
print("The mean square of price and predicted value is: ", mse)

Вывод: The mean square error of price and predicted value is: 31635042.944639888

Модель 2: Множественная линейная регрессия

Рассчитаем R²:

# Fit the model
lm.fit(Z,df["price"])
# Find the R^2
print("The R-square is: ", lm.score(Z, df["price"]))

Вывод: The R-square is: 0.8093562806577457

Мы можем сказать, что примерно 80,896 % вариации цены объясняется этой множественной линейной регрессией «multi_fit».

Рассчитаем прогноз:

Y_predict_multifit = lm.predict(Z)

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

print("The mean square error of price and predicted value using multifit is: ", mean_squared_error(df["price"], Y_predict_multifit))

Вывод: The mean square error of price and predicted value using multifit is: 11980366.87072649

Модель 3: полиномиальная подгонка

Рассчитаем R².

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

from sklearn.metrics impot r2_score

Мы применяем функцию, чтобы получить значение R²:

r_squared = r2_score(y, p(x))
print("The R-square value is: ", r_squared)

Вывод: The R-square value is: 0.6741946666390652

Можно сказать, что ~67,419 % изменения цены объясняется этим полиномиальным соответствием.

MSE

Мы также можем рассчитать MSE:

mean_square_error(df["price"], p(x))

Вывод: 20474146.426361218

Прогнозирование и принятие решений

Прогноз

В предыдущем разделе мы обучили модель методом fit. Теперь мы будем использовать метод predict для создания прогноза. Давайте импортируем pyplot для построения графиков; мы также будем использовать некоторые функции из NumPy.

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

Создайте новый вход:

new_input = np.arrange(1, 100, 1).reshape(-1, 1)

Подходит к модели:

lm.fit(X, Y)
lm

Сделайте прогноз:

yhat= lm.predict(new_input)
yhat[0:5]

Вывод:array([37601.57247984, 36779.83910151, 35958.10572319, 35136.37234487, 34314.63896655])

Мы можем построить данные:

plt.plot(new_input, yhat)
plt.show()

Принятие решения: определение хорошей подгонки модели

Теперь, когда мы визуализировали различные модели и сгенерировали значения R-квадрата и MSE для подгонки, как нам определить хорошую подгонку модели?

  • Что такое хорошее значение R-квадрата?

При сравнении моделей модель с более высоким значением R-квадрата лучше подходит для данных.

  • Что такое хорошая MSE?

При сравнении моделей модель с наименьшим значением MSE лучше подходит для данных.

Давайте посмотрим на значения для разных моделей.

Простая линейная регрессия: использование Highway-mpg в качестве предиктора цены.

  • R-квадрат: 0,49659118843391759
  • СКО: 3,16*10⁷

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

  • R-квадрат: 0,80896354913783497
  • СКО: 1,2*10⁷

Полиномиальная аппроксимация: использование Highway-mpg в качестве предиктора цены.

  • R-квадрат: 0,67419466663906514
  • СКО: 2,05*10⁷

Модель простой линейной регрессии (SLR) и модель множественной линейной регрессии (MLR)

Обычно чем больше у вас переменных, тем лучше ваша модель предсказывает, но это не всегда так. Иногда у вас может быть недостаточно данных, вы можете столкнуться с числовыми проблемами или многие переменные могут быть бесполезными и даже действовать как шум. В результате вы всегда должны проверять MSE и R².

Чтобы сравнить результаты моделей MLR и SLR, мы рассмотрим комбинацию как R-квадрата, так и MSE, чтобы сделать наилучший вывод о соответствии модели.

  • MSE: MSE SLR составляет 3,16*10⁷, тогда как MLR имеет MSE 1,2*10⁷. MSE MLR намного меньше.
  • R-квадрат. В этом случае мы также видим большую разницу между R-квадратом SLR и R-квадратом MLR. R-квадрат для SLR (~ 0,497) очень мал по сравнению с R-квадратом для MLR (~ 0,809).

Этот R-квадрат в сочетании с MSE показывает, что MLR кажется лучшей моделью, подходящей для этой помощи, по сравнению с SLR.

Простая линейная модель (SLR) против полиномиальной подгонки

  • MSE: мы видим, что полиномиальная подгонка снизила MSE, поскольку эта MSE меньше, чем у SLR.
  • R-квадрат: R-квадрат для полиномиальной аппроксимации больше, чем R-квадрат для SLR, поэтому полиномиальная аппроксимация также значительно увеличила R-квадрат.

Поскольку полиномиальная подгонка привела к более низкому MSE и более высокому R-квадрату, мы можем сделать вывод, что эта модель была лучше подходящей модели, чем некоторая линейная регрессия для прогнозирования «цены» с «highway-mpg» в качестве переменной-предиктора.

Множественная линейная регрессия (MLR) против полиномиальной подгонки

  • MSE: MSE для MLR меньше, чем MSE для полиномиальной аппроксимации.
  • R-квадрат: R-квадрат для MLR также намного больше, чем для полиномиального подбора.

Заключение

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

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