#01 | Машинное обучение с линейной регрессией

Погрузитесь в суть машинного обучения, разработав несколько регрессионных моделей с практическим вариантом использования на Python для прогнозирования несчастных случаев в США.

Прочитать исходную статью здесьв Хашноде.

🎯 Важность главы

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

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

у«=»(а)+(б)Иксу = (а) + (б) \cdot х

Как мы видим на следующем графике, не любое математическое уравнение является действительным; красная линия не соответствует реальным данным (синие точки), а зеленая — лучше всего.

линейная регрессия.jpeg

Как мы понимаем разработку моделей машинного обучения в Python предсказать, что может произойти в будущем?

В этом руководстве рассматриваются темы, описанные ниже, с использованием Данные по автомобильным авариям в США для прогнозирования несчастных случаев на основе алкоголя.

  1. Пошаговая процедура вычисления линейной регрессии:
    1. .fit() числа математического уравнения
    2. .predict() будущее с математическим уравнением
    3. .score() насколько хорошо математическое уравнение
  2. Как визуализировать модель линейной регрессии?
  3. Как оценивать Регрессионные модели шаг за шагом?
    • Остаточная сумма квадратов
    • Общая сумма квадратов
    • Квадрат отношения R р2Р^2
  4. Как интерпретировать коэффициенты линейной регрессии?
  5. Сравните линейную регрессию с другими моделями машинного обучения, такими как:
    • Случайный лес
    • Опорные векторные машины
  6. Почему нам не нужно знать математику за каждой моделью применения машинного обучения в Python?

💽 Загрузите данные

  • Этот набор данных содержит статистика автомобильных аварий (столбцы)
  • В каждом из Штаты США (ряды)

Посещать этот сайт если вы хотите знать меры столбцов.

import seaborn as sns 

df_crashes = sns.load_dataset(name='car_crashes', index_col='abbrev')[['alcohol', 'total']]
df_crashes.rename({'total': 'accidents'}, axis=1, inplace=True)
df_crashes

df1.jpeg

🤖 Как мы вычисляем модель линейной регрессии в Python?

  • Как всегда, нам нужно использовать функцию

Где функция?

  • Он должен быть в библиотеке

Какая библиотека Python для машинного обучения?

Импортировать класс

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

  • Нам нужно импортировать LinearRegression класс внутри linear_model модуль:
from sklearn.linear_model import LinearRegression

Мгновенный класс

  • Теперь мы создаем экземпляр model_lr класса LinearRegression:
model_lr = LinearRegression()

Подходит для модели

Какая функция применяет линейную регрессию алгоритм в которой Остаточная сумма квадратов сведена к минимуму?

model_lr.fit()
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Input In [186], in <cell line: 1>()
----> 1 model_lr.fit()


TypeError: fit() missing 2 required positional arguments: 'X' and 'y'

Почему он запрашивает два параметра: y и X?

Алгоритм должен различать переменную, которую мы хотим предсказать (y), и переменные, используемые для объяснения (X) прогноз.

  • y: цель ~ независимая ~ метка ~ переменная класса
  • X: особенности ~ зависимые ~ независимые переменные

Разделите переменные

target = df_crashes['accidents']
features = df_crashes[['alcohol']]

Соответствуйте модели снова

model_lr.fit(X=features, y=target)
LinearRegression()

Предсказания

Рассчитать прогнозы

Возьмем исторические данные:

features

df2.jpeg

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

model_lr.predict(X=features)
array([17.32111171, 15.05486718, 16.44306899, 17.69509287, 12.68699734,
       13.59756016, 13.76016066, 15.73575679,  9.0955587 , 16.40851638,
       13.78455074, 20.44100889, 14.87600663, 14.70324359, 14.40446516,
       13.8353634 , 14.54064309, 15.86177218, 19.6076813 , 15.06502971,
       13.98780137, 11.69106925, 13.88211104, 11.5162737 , 16.94713055,
       16.98371566, 24.99585551, 16.45729653, 15.41868581, 12.93089809,
       12.23171592, 15.95526747, 13.10772614, 16.44306899, 26.26007443,
       15.60161138, 17.58737003, 12.62195713, 17.32517672, 14.43088774,
       25.77430543, 18.86988151, 17.3515993 , 20.84141263,  9.53254755,
       14.15040187, 12.82724027, 12.96748321, 19.40239816, 15.11380986,
       17.17477126])

Добавьте новый столбец с прогнозами

Видите ли вы разницу между реальностью и предсказанием?

  • Прогнозы модели не идеальны; они не предсказывают реальные данные точно. Тем не менее, они дают хорошее приближение, позволяющее лицам, принимающим решения, лучше понимать будущее.
df_crashes['pred_lr'] = model_lr.predict(X=features)
df_crashes

df3.jpeg

Визуализация модели

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

import matplotlib.pyplot as plt
sns.scatterplot(x='alcohol', y='accidents', data=df_crashes)
sns.scatterplot(x='alcohol', y='pred_lr', data=df_crashes);

plot1.jpeg

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

sns.scatterplot(x='alcohol', y='accidents', data=df_crashes)
sns.scatterplot(x='alcohol', y='pred_lr', data=df_crashes);
sns.lineplot(x='alcohol', y='pred_lr', data=df_crashes, color='orange');

plot2.jpeg

Оценка модели

Рассчитать балл

Для измерения качества модели мы используем .score() функция для правильного расчета разницы между предсказаниями модели и реальностью.

model_lr.score(X=features, y=target)
0.7269492966665405

Объясните счет

Остатки

Пошаговая процедура предыдущего расчета начинается с разницы между реальностью и прогнозами:

df_crashes['accidents'] - df_crashes['pred_lr']
abbrev
AL    1.478888
AK    3.045133
        ...   
WI   -1.313810
WY    0.225229
Length: 51, dtype: float64

Эту разницу обычно называют остатки:

df_crashes['residuals'] = df_crashes['accidents'] - df_crashes['pred_lr']
df_crashes

df4.jpeg

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

df_crashes.residuals.sum()
1.4033219031261979e-13

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

df_crashes.residuals.sum().round(2)
0.0

Но получаем НОЛЬ. Почему?

Остатки содержат положительные и отрицательные числа; некоторые точки находятся выше линии, а другие ниже линии.

Чтобы превратить отрицательные значения в положительные, мы возводим остатки в квадрат:

df_crashes['residuals^2'] = df_crashes.residuals**2
df_crashes

df5.jpeg

И, наконец, сложите остатки, чтобы рассчитать Остаточная сумма квадратов (RSS):

df_crashes['residuals^2'].sum()
231.96888653310063
RSS = df_crashes['residuals^2'].sum()

рСС«=»(уяу^)2RSS = \sum(y_i — \шляпа{y})^2

где

  • y_i — реальное количество аварий
  • у^\шляпа у
  • RSS: Остаточная сумма квадратов
Вариант цели

Модель была сделана для прогнозирования количества аварий.

Мы должны спросить: насколько хороши вариации прогнозов модели по сравнению с вариациями реальных данных (реального количества аварий)?

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

df_crashes.accidents
abbrev
AL    18.8
AK    18.1
      ... 
WI    13.8
WY    17.4
Name: accidents, Length: 51, dtype: float64
df_crashes.accidents.mean()
15.79019607843137

ИксяИкс¯x_i — \бар х

Где х количество несчастных случаев.

df_crashes.accidents - df_crashes.accidents.mean()
abbrev
AL    3.009804
AK    2.309804
        ...   
WI   -1.990196
WY    1.609804
Name: accidents, Length: 51, dtype: float64
df_crashes['real_residuals'] = df_crashes.accidents - df_crashes.accidents.mean()
df_crashes

df6.jpeg

Возводим в квадрат остатки по той же причине, что и раньше (преобразуем отрицательные значения в положительные):

df_crashes['real_residuals^2'] = df_crashes.real_residuals**2

ТТС«=»(уяу¯)2TTS = \sum(y_i — \bar y)^2

где

  • y_i — количество несчастных случаев
  • у¯\бар и
  • TTS: общая сумма квадратов

И мы складываем значения, чтобы получить Общая сумма квадратов (RSS):

df_crashes['real_residuals^2'].sum()
849.5450980392156
TSS = df_crashes['real_residuals^2'].sum()
Соотношение

Соотношение между RSS и TSS показывает, насколько наша модель не соответствует вариации реальных данных.

RSS/TSS
0.2730507033334595

0,27 — это плохость модели, т.к. RSS представляет остатки (ошибки) модели.

Чтобы рассчитать доброта модели, нам нужно вычесть отношение RSS/TSS к 1:

р2«=»1рССТСС«=»1(уяу^)2(уяу¯)2R ^ 2 = 1 — \ frac {RSS} {TSS} = 1 — \ frac {\ sum (y_i — \ hat {y}) ^ 2} {\ sum (y_i — \ bar y) ^ 2}

1 - RSS/TSS
0.7269492966665405

Модель может объяснить 72,69% изменчивости общего количества аварий.

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

Интерпретация модели

Как мы получаем числа математического уравнения линейной регрессии?

  • Нам нужно заглянуть внутрь объекта model_lr и показать атрибуты с .__dict__ (числа рассчитаны с .fit() функция):
model_lr.__dict__
{'fit_intercept': True,
 'normalize': 'deprecated',
 'copy_X': True,
 'n_jobs': None,
 'positive': False,
 'feature_names_in_': array(['alcohol'], dtype=object),
 'n_features_in_': 1,
 'coef_': array([2.0325063]),
 '_residues': 231.9688865331006,
 'rank_': 1,
 'singular_': array([12.22681605]),
 'intercept_': 5.857776154826299}
  • intercept_ это (а) номер математического уравнения
  • coef_ это (b) номер математического уравнения

несчастные случаи = (a) + (b) \cdot алкоголь \\ несчастные случаи = (перехват\_) + (коэфф\_) \cdot алкоголь \\ несчастные случаи = (5,857) + (2,032) \cdot алкоголь

На каждую увеличенную единицу алкоголя количество несчастных случаев увеличится на 2,032 единицы.

import pandas as pd

df_to_pred = pd.DataFrame({'alcohol': [1,2,3,4,5]})
df_to_pred['pred_lr'] = 5.857 + 2.032 * df_to_pred.alcohol
df_to_pred['diff'] = df_to_pred.pred_lr.diff()
df_to_pred

df7.jpeg

🚀 Другие модели регрессии

Можем ли мы создать лучшую модель, которая улучшит текущую оценку линейной регрессии?

model_lr.score(X=features, y=target)
0.7269492966665405
  • Давайте попробуем случайный лес и машины опорных векторов.

Нужно ли нам знать математику, стоящую за этими моделями, чтобы реализовать их на Python?

RandomForestRegressor() в Питоне

Подходит для модели

from sklearn.ensemble import RandomForestRegressor

model_rf = RandomForestRegressor()
model_rf.fit(X=features, y=target)
RandomForestRegressor()

Рассчитать прогнозы

model_rf.predict(X=features)
array([18.644     , 16.831     , 17.54634286, 21.512     , 12.182     ,
       13.15      , 12.391     , 17.439     ,  7.775     , 17.74664286,
       14.407     , 18.365     , 15.101     , 14.132     , 13.553     ,
       15.097     , 15.949     , 19.857     , 21.114     , 15.53      ,
       13.241     ,  8.98      , 14.363     ,  9.54      , 17.208     ,
       16.593     , 22.087     , 16.24144286, 14.478     , 11.51      ,
       11.59      , 18.537     , 11.77      , 17.54634286, 23.487     ,
       14.907     , 20.462     , 12.59      , 18.38      , 12.449     ,
       23.487     , 20.311     , 19.004     , 19.22      ,  9.719     ,
       13.476     , 12.333     , 11.08      , 22.368     , 14.67      ,
       17.966     ])
df_crashes['pred_rf'] = model_rf.predict(X=features)

Оценка модели

model_rf.score(X=features, y=target)
0.9549469198566546

Давайте создадим словарь, в котором будет храниться Score каждой модели:

dic_scores = {}
dic_scores['lr'] = model_lr.score(X=features, y=target)
dic_scores['rf'] = model_rf.score(X=features, y=target)

SVR() в Питоне

Подходит для модели

from sklearn.svm import SVR

model_sv = SVR()
model_sv.fit(X=features, y=target)
SVR()

Рассчитать прогнозы

model_sv.predict(X=features)
array([18.29570777, 15.18462721, 17.2224187 , 18.6633175 , 12.12434781,
       13.10691581, 13.31612684, 16.21131216, 12.66062465, 17.17537208,
       13.34820949, 19.38920329, 14.91415215, 14.65467023, 14.2131504 ,
       13.41560202, 14.41299448, 16.39752499, 19.4896662 , 15.20002787,
       13.62200798, 11.5390483 , 13.47824339, 11.49818909, 17.87053595,
       17.9144274 , 19.60736085, 17.24170425, 15.73585463, 12.35136579,
       11.784815  , 16.53431108, 12.53373232, 17.2224187 , 19.4773929 ,
       16.01115736, 18.56379706, 12.06891287, 18.30002795, 14.25171609,
       19.59597679, 19.37950461, 18.32794218, 19.29994413, 12.26345665,
       13.84847453, 12.25128025, 12.38791686, 19.48212198, 15.27397732,
       18.1357253 ])
df_crashes['pred_sv'] = model_sv.predict(X=features)

Оценка модели

model_sv.score(X=features, y=target)
0.7083438012012769
dic_scores['sv'] = model_sv.score(X=features, y=target)

💪 Какой из них лучший? Почему?

Лучшей моделью является случайный лес с оценкой 0,95:

pd.Series(dic_scores).sort_values(ascending=False)
rf    0.954947
lr    0.726949
sv    0.708344
dtype: float64

📊 Визуализируйте 3 модели

Подставим следующие данные:

df_crashes[['accidents', 'pred_lr', 'pred_rf', 'pred_sv']]

df8.jpeg

В сюжет:

sns.scatterplot(x='alcohol', y='accidents', data=df_crashes, label='Real Data')
sns.scatterplot(x='alcohol', y='pred_lr', data=df_crashes, label='Linear Regression')
sns.lineplot(x='alcohol', y='pred_lr', data=df_crashes, color='orange')
sns.scatterplot(x='alcohol', y='pred_rf', data=df_crashes, label='Random Forest')
sns.scatterplot(x='alcohol', y='pred_sv', data=df_crashes, label='Support Vector Machines');

plot3.jpeg

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *