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

Чтобы объяснить на примере, вы можете представить список домов с информацией о размере, расстоянии до центра города, саде (независимые переменные). Используя эту информацию, вы можете попытаться понять, как меняется цена (зависимые переменные).

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

Линейные модели регрессии

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

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

Функция линейной регрессии написана в предположении линейной зависимости между переменными:

у=w1x1+…+wnxn+c

где w — коэффициенты регрессии, x — независимые переменные или признаки, y — зависимая переменная/результат, а c — постоянная погрешность.

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

yprice=500Xsize−350Xрасстояние до города+400.000

Таким образом, если мы подставим в эту функцию характеристики нового дома, мы сможем предсказать его цену (допустим, площадь дома составляет 150 м2, а расстояние до центра города — 5 км).

yprice=500∗150−350∗5+400,000=75,000−1750+400,000=476,750

Посмотрите, как минусует коэффициент расстояния до центра города. То есть ближе к центру дом будет дороже.

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

import matplotlib.pyplot as plt
from sklearn.datasets import make_regression
plt.figure()
plt.title('Samples in a dataset with only one feature (dependent variable)')
X, y = make_regression(n_samples = 80, n_features=1,
n_informative=1, bias = 50,
noise = 40, random_state=42)
plt.scatter(X, y, marker= 'o', s=50)
plt.show()

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

y=w1x1+c

где w1 будет наклоном кривой, а c будет значением смещения.

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

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

Линейная регрессия по методу наименьших квадратов

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

RSS(w,c)=∑i(yi−(w.xi+b))2

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

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

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42)
model = LinearRegression()
model.fit(X_train, y_train)
print('feature coefficient (w_1): {}'.format(model.coef_))
print('intercept (c): {:.3f}'.format(model.intercept_))
print('R-squared score (training):{:.3f}'.format(model.score(X_train, y_train)))
print('R-squared score (test): {:.3f}'.format(model.score(X_test, y_test)))

Здесь R² — коэффициент детерминации. Этот термин представляет собой величину вариации результата (y), объясняемую зависимостью от признаков (переменных x). Следовательно, большее значение R² указывает на лучшую производительность модели или лучшее соответствие.

Когда R² равен единице, тогда RSS равен 0. Это означает, что значения прогнозируемого результата и значения реального результата совпадают. Мы будем использовать термин R² для измерения производительности нашей модели.

plt.figure(figsize=(6,5))
plt.scatter(X, y, marker= 'o', s=50, alpha=0.7)
plt.plot(X, model.coef_*X + model.intercept_, 'r-')
plt.title('Least-squares linear regression model')
plt.xlabel('Variable/feature value (x)')
plt.ylabel('Outcome (y)')
plt.show()

Ридж-регрессия — регуляризация L2

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

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

Этот дополнительный член в основном представляет собой сумму квадратов коэффициентов. Поэтому, когда мы пытаемся минимизировать функцию RSS, мы также минимизируем сумму квадратов коэффициентов, что называется регуляризацией L2. Более того, альфа-константа служит для контроля влияния этой регуляризации. Таким образом, по сравнению с моделью наименьших квадратов, мы можем фактически контролировать сложность нашей модели с помощью альфа-члена. Чем выше альфа-член, тем выше регуляризация и проще будет модель.

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

Давайте посмотрим на его реализацию в python.

from sklearn import datasets
from sklearn.linear_model import Ridge
X,y = datasets.load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y,random_state = 42)
model = Ridge()
model.fit(X_train, y_train)
print('feature coefficients: {}'.format(model.coef_))
print('intercept (c): {:.3f}'.format(model.intercept_))

plt.figure(figsize=(10,5))
alphas = [1,5,10,20,50,100,500]
features = ['w_'+str(i+1) for i,_ in enumerate(model.coef_)]
for alpha in alphas:
   model = Ridge(alpha=alpha).fit(X_train,y_train)
   plt.scatter(features,model.coef_, alpha=0.7,label=('alpha='+str(alpha)))
plt.axhline(0)
plt.xticks(features)
plt.legend(loc='upper left')
plt.show()

Нормализация может быть несправедливо применена к функциям, если они имеют разные масштабы (когда одна функция имеет значения около 0–1, а другая — от 100 до 1000). Это может вызвать неточности в нашей модели, когда мы применяем регуляризацию. В этом случае нам на помощь приходит масштабирование признаков, чтобы нормализовать все значения в наборе данных, чтобы мы могли избавиться от различий в масштабах. Мы рассмотрим масштабирование функций в другом разделе…

Лассо-регрессия — регуляризация L1

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

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

Штрафной член за регуляризацию L1 представляет собой сумму абсолютных значений коэффициентов. Поэтому, когда алгоритм пытается минимизировать RSS, он применяет регуляризацию, сводя к минимуму сумму абсолютных значений коэффициентов.

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

Термин «альфа» снова используется для контроля степени регуляризации.

from sklearn.linear_model import Lasso

model = Lasso()
model.fit(X_train, y_train)
print('feature coefficients: {}'.format(model.coef_))
print('intercept (c): {:.3f}'.format(model.intercept_))

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

import numpy as np
data = datasets.load_diabetes()
np.take(data.feature_names,np.nonzero(model.coef_))

alphas = [0.1,0.5,1,2,5,10]
for alpha in alphas:
  model = Lasso(alpha=alpha).fit(X_train,y_train)
  print('feature coefficients for alpha={}:   \n{}'.format(alpha,model.coef_))
  print('R-squared score (training):{:.3f}'.format(model.score(X_train, y_train)))
  print('R-squared score (test):  {:.3f}\n'.format(model.score(X_test, y_test)))

Ридж или Лассо?

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

Полиномиальная регрессия

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

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

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

Давайте продолжим с примером полиномиальной регрессии. Чтобы преобразовать функции в термины более высокого порядка, мы можем использовать класс PolynomialFeatures из scikit-learn. Затем мы можем использовать модель линейной регрессии для обучения модели.

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

np.random.seed(0)
X = 2 - 3 * np.random.normal(0, 1, 100)
y = X - 2 * (X ** 2)  + np.random.normal(-3, 3, 100)

plt.scatter(X, y, s=10)
plt.show()

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

X = X[:, np.newaxis]
y = y[:, np.newaxis]
model = LinearRegression()
model.fit(X,y)
print('feature coefficients: \n{}'.format(model.coef_))
print('R-squared score (training): {:.3f}'.format(model.score(X, y)))

plt.plot(X, model.coef_*X + model.intercept_, 'r-')
plt.scatter(X,y, s=10)
plt.show()

Как и ожидалось, модель линейной регрессии не очень хорошо соответствует обычным функциям набора данных с таким поведением. Теперь мы можем создавать полиномиальные функции 2-го порядка, используя класс PolynomialFeatures из библиотеки sk-learn. Затем используйте эти новые функции 2-го порядка для обучения той же модели линейной регрессии.

from sklearn.preprocessing import PolynomialFeatures
poly_features= PolynomialFeatures(degree=2)
X_poly = poly_features.fit_transform(X)
model = LinearRegression()
model.fit(X_poly,y)
print('feature coefficients: \n{}'.format(model.coef_))
print('R-squared score (training): {:.3f}'.format(model.score(X_poly, y)))
plt.scatter(X,model.predict(X_poly),s=10,label="polynomial prediction")
plt.scatter(X,y,s=10,label="real data")
plt.legend(loc='lower left')
plt.show()

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

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