#01 | Машинное обучение с линейной регрессией
Погрузитесь в суть машинного обучения, разработав несколько регрессионных моделей с практическим вариантом использования на Python для прогнозирования несчастных случаев в США.
Прочитать исходную статью здесьв Хашноде.
🎯 Важность главы
Машинное обучение — это расчет лучшие номера математического уравнения минимизация расстояния между реальными данными и прогнозами.
Форма математического уравнения линейной регрессии выглядит следующим образом:
Как мы видим на следующем графике, не любое математическое уравнение является действительным; красная линия не соответствует реальным данным (синие точки), а зеленая — лучше всего.
Как мы понимаем разработку моделей машинного обучения в Python предсказать, что может произойти в будущем?
В этом руководстве рассматриваются темы, описанные ниже, с использованием Данные по автомобильным авариям в США для прогнозирования несчастных случаев на основе алкоголя.
- Пошаговая процедура вычисления линейной регрессии:
.fit()
числа математического уравнения.predict()
будущее с математическим уравнением.score()
насколько хорошо математическое уравнение
- Как визуализировать модель линейной регрессии?
- Как оценивать Регрессионные модели шаг за шагом?
- Остаточная сумма квадратов
- Общая сумма квадратов
- Квадрат отношения R
- Как интерпретировать коэффициенты линейной регрессии?
- Сравните линейную регрессию с другими моделями машинного обучения, такими как:
- Случайный лес
- Опорные векторные машины
- Почему нам не нужно знать математику за каждой моделью применения машинного обучения в 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
🤖 Как мы вычисляем модель линейной регрессии в 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
Чтобы рассчитать прогнозы с помощью математического уравнения модели:
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
Визуализация модели
Оранжевые точки ссылаются на прогнозы, выстроенные в линию, поскольку модель линейной регрессии вычисляет лучшие коэффициенты (числа) для математического уравнения линии на основе исторических данных.
import matplotlib.pyplot as plt
sns.scatterplot(x='alcohol', y='accidents', data=df_crashes)
sns.scatterplot(x='alcohol', y='pred_lr', data=df_crashes);
У нас есть оранжевые точки для алкоголя, представленного в нашем 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');
Оценка модели
Рассчитать балл
Для измерения качества модели мы используем .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
Мы не можем использовать все остатки, чтобы сказать, насколько хороша наша модель. Поэтому нам нужно их сложить:
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
И, наконец, сложите остатки, чтобы рассчитать Остаточная сумма квадратов (RSS):
df_crashes['residuals^2'].sum()
231.96888653310063
RSS = df_crashes['residuals^2'].sum()
где
- 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
Где х количество несчастных случаев.
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
Возводим в квадрат остатки по той же причине, что и раньше (преобразуем отрицательные значения в положительные):
df_crashes['real_residuals^2'] = df_crashes.real_residuals**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:
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
🚀 Другие модели регрессии
Можем ли мы создать лучшую модель, которая улучшит текущую оценку линейной регрессии?
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']]
В сюжет:
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');