Подробное руководство по полиномиальной регрессии в Python, обзор, реализация и переобучение

Полный код на Python

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

Эта статья будет посвящена основам полиномиальной регрессии и реализации с использованием библиотеки scikit-learn в Python. Мы также будем работать над экспериментом по переоснащению для новичков в машинном обучении.

Обзор полиномиальной регрессии

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

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

Напоминаем, что линейная регрессия следует самой базовой формуле, которую мы все выучили в школе:

Y = C + BX

Здесь Y — выходная переменная, X — входная переменная, C — точка пересечения, а B — наклон.

А в машинном обучении мы просто используем разные термины:

Здесь h — гипотеза или прогнозируемая выходная переменная, X — входная переменная, theta1 — коэффициент, а theta0 — смещение.

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

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

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

Смотрите, мы делаем несколько переменных из одной входной переменной X, просто применяя к ней разные степени. Полиномиальная регрессия также может выглядеть так:

Это все об обзоре полиномиальной регрессии. Я не буду заходить дальше этого, потому что мы собираемся использовать библиотеку scikit-learn для реализации полиномиальной регрессии. Если вам интересно узнать больше о полиномиальной регрессии, перейдите по этой ссылке:



Реализация полиномиальной регрессии

Здесь мы реализуем полиномиальную регрессию, используя библиотеку Python scikit-learn. Я буду использовать страховой набор данных .csv от Kaggle. Вот ссылка на набор данных:



Во-первых, давайте создадим Pandas DataFrame, используя этот набор данных. Я скачал набор данных, чтобы использовать его:

import pandas as pd 
df = pd.read_csv("insurance.csv")
df.head()

Подготовка данных

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

df.isna().sum()

Итак, у нас есть нулевые нулевые значения в каждом столбце DataFrame. Очень хорошо!

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

df['sex'] = df['sex'].replace({'female': 1, 'male': 2})
df['smoker'] = df['smoker'].replace({'yes': 1, 'no': 2})
df['region'] = df['region'].replace({'southwest': 1, 'southeast': 2, 'northwest': 3, 'northeast': 4})

На этом подготовка данных завершена.

Определение входных функций и целевой переменной

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

X = df.drop(columns = ['charges'])
y = df['charges']

Здесь X — входная переменная, а y — выходная переменная.

Разделить данные для обучения и тестирования

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

В библиотеке scikit-learn для этого есть метод train_test_split. Мы поместим X, y, которые мы определили ранее, test_size равным 0,25, что означает, что 25% данных будут сохранены для целей тестирования, s и random_state равным 1 (вы можете использовать любое другое целое число в качестве random_state).

from sklearn.model_selection import train_test_split 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state = 1)

Масштабирование даты

Хорошей практикой является масштабирование данных и приведение их к одному и тому же диапазону в полиномиальной регрессии. Для этого мы будем использовать метод Standard Scaler из библиотеки scikit-learn:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaler = scaler.fit_transform(X_train)
X_test_scaler = scaler.transform(X_test)

Разработка модели

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

  1. Первым шагом является вызов метода PolynomialFeatures со степенью мощности.

2. Подгонка входных признаков к методу PolynomialFeatures как для обучающих, так и для тестовых данных.

3. Подгонка обучающих входных и выходных переменных к методу полиномиальных признаков.

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

Вот код:

from sklearn.preprocessing import PolynomialFeatures 
poly = PolynomialFeatures(degree=6)
X_poly_train = poly.fit_transform(X_train_scaler)
X_test_poly = poly.transform(X_test_scaler)
poly.fit(X_poly_train, y_train)
lin.fit(X_poly_train, y_train)

Часть разработки и обучения модели завершена!

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

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

y_pred = lin.predict(X_test_poly)

Расчет средней абсолютной ошибки:

from sklearn.metrics import mean_absolute_error
mean_absolute_error(y_test, y_pred)

Выход:

285296796712.7246

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

y_pred_train = lin.predict(X_poly_train)
mean_absolute_error(y_train, y_pred_train)

Выход:

1970.8913236804585

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

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

Решение проблемы переобучения

Решение проблемы переобучения начинается с настройки гиперпараметров. Мы должны попробовать разные гиперпараметры, чтобы найти оптимальные значения, при которых модель хорошо работает как на данных обучения, так и на данных тестирования. Это была простая модель. Здесь у нас есть только один гиперпараметр — степень в методе PolynomialFeatures. Раньше мы использовали степень 6, теперь попробуем со степенью 3.

poly = PolynomialFeatures(degree=3)
X_poly_train = poly.fit_transform(X_train_scaler)
X_test_poly = poly.transform(X_test_scaler)
poly.fit(X_poly_train, y_train)
lin = LinearRegression()
lin.fit(X_poly_train, y_train)

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

y_pred = lin.predict(X_test_poly)
mean_absolute_error(y_test, y_pred)

Выход:

2819.746326567164

Смотреть! Средняя абсолютная ошибка была снижена с огромным запасом, чем раньше.

Мы все еще должны проверить, как это работает на обучающих данных:

y_pred_train = lin.predict(X_poly_train)
mean_absolute_error(y_train, y_pred_train)

Выход:

2818.997792755733

Ух ты! Средняя абсолютная ошибка на обучающих данных и тестовых данных очень близка: 2819 и 2818 соответственно. Это потрясающе!

Это может быть не так близко в вашем случае всегда. Но они должны быть достаточно близко.

Заключение

Это руководство должно было объяснить основную концепцию одной из базовых моделей машинного обучения и реализацию в библиотеке scikit-learn. Он также дал тест на то, что такое переоснащение, и взгляд на то, как его решить. Надеюсь, это было полезно!

Подробнее Чтение