Автор: Trent Hauck
Переводчик: muxuezi
Лицензия: CC BY-NC-SA 4.0
В этой главе рассматриваются следующие темы:
Линейные модели являются основой статистики и машинного обучения. Множество методов используют линейные комбинации переменных для описания отношений между данными. Часто требуется много усилий для выполнения различных преобразований данных, чтобы они могли быть представлены в виде линейной комбинации.
В этой главе мы рассмотрим модели от простого линейного аппроксиматора до классификаторов, а также байесовскую岭回归.# 2.1 Линейная регрессия
Начнем работу с созданием модели! Мы начнем с самого простого — линейной регрессии. Линейная регрессия является одной из самых ранних и базовых моделей — она аппроксимирует данные прямой линией.
Датасет boston
отлично подходит для демонстрации линейной регрессии. Датасет boston
содержит медианную стоимость домов в Бостоне. Также есть несколько факторов, которые могут влиять на цену дома, такие как уровень преступности (crime rate).
Сначала загрузим данные:
from sklearn import datasets
boston = datasets.load_boston()
На самом деле использование линейной регрессии из scikit-learn очень просто, его API аналогично API других моделей.
Сначала импортируем класс LinearRegression
и создаем объект:
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
Теперь передаем признаки и целевые значения в метод fit
класса LinearRegression
:
lr.fit(boston.data, boston.target)
Линейная регрессия(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
В этом разделе мы рассмотрим качество аппроксимации данных моделью линейной регрессии. В предыдущем разделе мы обучили модель на данных, но не уделили особого внимания качеству обучения. После того как обучение завершено, первым вопросом, который следует задать, является "Какова эффективность обучения?" Этот раздел ответит на этот вопрос.## Подготовка
Мы продолжаем использовать объект lr
и набор данных boston
, использованные в предыдущем разделе. Объект lr
уже обучен на данных, поэтому теперь доступно множество методов для его использования.
from sklearn import datasets
boston = datasets.load_boston()
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(boston.data, boston.target)
Линейная регрессия(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
predictions = lr.predict(boston.data)
Мы можем просмотреть некоторые простые метрики и графики. Давайте посмотрим на график остатков, представленный в предыдущем разделе:
%matplotlib inline
from matplotlib import pyplot as plt
f, ax = plt.subplots(figsize=(7, 5))
f.tight_layout()
ax.hist(boston.target - predictions, bins=40, label='Остатки линейной регрессии', color='b', alpha=.5);
ax.set_title("Гистограмма остатков")
ax.legend(loc='best');
Если вы используете IPython Notebook, то используйте команду %matplotlib inline
для отображения графиков Matplotlib прямо в браузере. Если нет, то используйте f.savefig('myfig.png')
для сохранения графика для последующего использования.
Библиотека для построения графиков — Matplotlib, которая не является основной темой данной книги, но имеет отличные возможности для визуализации.Как и раньше, ошибки распределены нормально с нулевым средним значением. Остатки представляют собой ошибки, поэтому этот график также должен приближаться к нормальному распределению. Похоже, что модель хорошо обучена, хотя немного смещена. Давайте посчитаем среднее значение остатков; оно должно быть очень близко к нулю:
mean_residuals = np.mean(residuals)
print("Среднее значение остатков:", mean_residuals)
``````python
import numpy as np
np.mean(boston.target - predictions)
Выходит:
6.0382090193051989e-16
Другой полезный график — график Q-Q (квантиль-квантиль), который можно построить с помощью Scipy, поскольку он предоставляет встроенную функциональность для построения таких графиков:
from scipy.stats import probplot
f = plt.figure(figsize=(7, 5))
ax = f.add_subplot(111)
probplot(boston.target - predictions, plot=ax);
```
На этом графике наклоненные данные более четко видны по сравнению с тем, что мы видели ранее.
Можно также рассмотреть другие метрики аппроксимации, самыми распространенными являются среднеквадратичная ошибка (Mean Squared Error, MSE) и средняя абсолютная ошибка (Mean Absolute Deviation, MAD). Давайте реализуем эти две метрики на Python. Впоследствии мы будем использовать встроенные метрики scikit-learn для оценки качества регрессионной модели.
```python
def MSE(target, predictions):
squared_deviation = np.power(target - predictions, 2)
return np.mean(squared_deviation)
MSE(boston.target, predictions)
21.897779217687496
def MAD(target, predictions):
absolute_deviation = np.abs(target - predictions)
return np.mean(absolute_deviation)
MAD(boston.target, predictions)
3.2729446379969396
Формула вычисления MSE:
$$\frac{1}{n} \sum_{i=1}^{n} (\hat y_i - y_i)^2$$ Вычисление среднего значения квадратического отклонения между прогнозируемым значением и фактическим значением. Это то же самое, что и цель при поиске наилучшего коэффициента корреляции. Теорема Гаусса-Маркова уже доказала, что коэффициенты линейной регрессии являются наилучшим линейным несмещенным оценщиком (BLUE), если условием является то, что ошибочные переменные не коррелированы, имеют нулевое среднее значение и одинаковую дисперсию. В разделе "Исправление недостатков линейной регрессии с помощью岭回归" мы увидим, что происходит, когда наши коэффициенты корреляции являются смещенными оценками.
В разделе "Исправление недостатков линейной регрессии с помощью岭回归" заменим "岭回归" на "ridge regression":
Вычисление среднего значения квадратического отклонения между прогнозируемым значением и фактическим значением. Это то же самое, что и цель при поиске наилучшего коэффициента корреляции. Теорема Гаусса-Маркова уже доказала, что коэффициенты линейной регрессии являются наилучшим линейным несмещенным оценщиком (BLUE), если условием является то, что ошибочные переменные не коррелированы, имеют нулевое среднее значение и одинаковую дисперсию. В разделе "Исправление недостатков линейной регрессии с помощью ridge regression" мы увидим, что происходит, когда наши коэффициенты корреляции являются смещенными оценками.MAD представляет собой среднюю абсолютную ошибку, её формула следующая:
$$\frac{1}{N} \sum_{i=1}^{N} |\hat{y}_t - y_i|$$
При линейной регрессии MAD обычно не используется, но стоит обратить внимание. Почему? Поскольку можно увидеть каждую метрику отдельно и понять, какая из них важнее. Например, используя MSE, большие ошибки получают большее наказание, так как они увеличиваются путём возведения в квадрат.
Ещё одним моментом, который следует отметить, является то, что коэффициенты корреляции являются случайными величинами, поэтому они имеют распределение. Давайте воспользуемся методом бутстрapping (повторного выбора), чтобы посмотреть на распределение коэффициентов корреляции преступности. Бутстрapping — это распространённый способ обучения параметрам оценки неопределённости:
n_bootstraps = 1000
len_boston = len(boston.target)
subsample_size = np.int(0.5 * len_boston)
subsample = lambda: np.random.choice(
np.arange(0, len_boston),
size=subsample_size,
)
coefs = np.ones(n_bootstraps) # начальное значение коэффициентов установлено равным 1
for i in range(n_bootstraps):
subsample_idx = subsample()
subsample_X = boston.data[subsample_idx]
subsample_y = boston.target[subsample_idx]
lr.fit(subsample_X, subsample_y)
coefs[i] = lr.coef_[0]
Можно заметить распределение коэффициентов корреляции в виде гистограммы:
f = plt.figure(figsize=(7, 5))
ax = f.add_subplot(111)
ax.hist(coefs, bins=50, color='b', alpha=.5)
ax.set_title("Гистограмма распределения lr.coef_[0]");
```
Также мы хотели бы взглянуть на доверительный интервал после повторных экспериментов:
```python
np.percentile(coefs, [2.5, 97.5])
Доверительный интервал указывает, что уровень преступности фактически не влияет на стоимость недвижимости, так как ноль находится внутри доверительного интервала, что свидетельствует о том, что уровень преступности может быть не связан с стоимостью недвижимости.
Замечательно, что метод бутстрapping позволяет получить более точные оценки коэффициентов корреляции, поскольку среднее значение, полученное с помощью этого метода, быстрее сходится к истинному среднему значению.
В этом разделе будет рассмотрена岭回归。С ней отличается от линейной регрессии тем, что она вводит параметр регуляризации для "сужения" коэффициентов корреляции. Когда данные содержат мультиколлинеарность,岭回归 становится особенно полезной.
Предположим, что мы загружаем набор данных с низким рангом (low effective rank) для сравнения岭回归 и линейной регрессии. Ранг — это количество линейно независимых групп в матрице, полный ранг означает, что для матрицы размером $m \times n$, число линейно независимых групп равно $\text{min}(m,n)$.
Сначала создадим набор данных с тремя признаками с использованием make_regression
, но его ранг равен двум, поэтому среди трёх признаков два имеют зависимость друг от друга.
from sklearn.datasets import make_regression
reg_data, reg_target = make_regression(n_samples=2000, n_features=3, effective_rank=2, noise=10)
```Сначала обучим обычную линейную регрессию:
```python
import numpy as np
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
def fit_2_regression(lr):
n_bootstraps = 1000
coefs = np.ones((n_bootstraps, 3))
len_data = len(reg_data)
subsample_size = np.int(0.75 * len_data)
subsample = lambda: np.random.choice(np.arange(0, len_data), size=subsample_size)
for i in range(n_bootstraps):
subsample_idx = subsample()
subsample_X = reg_data[subsample_idx]
subsample_y = reg_target[subsample_idx]
lr.fit(subsample_X, subsample_y)
coefs[i][0] = lr.coef_[0]
coefs[i][1] = lr.coef_[1]
coefs[i][2] = lr.coef_[2]
%matplotlib inline
import matplotlib.pyplot as plt
f, axes = plt.subplots(nrows=3, sharey=True, sharex=True, figsize=(7, 5))
f.tight_layout()
for i, ax in enumerate(axes):
ax.hist(coefs[:, i], color='b', alpha=.5)
ax.set_title("Коэффициент {}".format(i))
return coefs
coefs = fit_2_regression(lr)
Теперь снова обучим данные с помощью Ridge
и сравним результаты:
from sklearn.linear_model import Ridge
coefs_r = fit_2_regression(Ridge())
Результаты двух алгоритмов регрессии кажутся похожими, но это не так. Коэффициенты корреляции при использовании метода Ridge ближе к нулю. Давайте рассмотрим разницу между коэффициентами корреляции обоих методов:
np.mean(coefs - coefs_r, axis=0)
Среднее значение показывает, что коэффициенты корреляции линейной регрессии значительно выше, чем у Ridge. Разница средних значений указывает на скрытую дисперсию в коэффициентах корреляции линейной регрессии. Но какова же польза от использования Ridge? Давайте посмотрим на дисперсию коэффициентов корреляции:```python np.var(coefs, axis=0)
```python
np.var(coefs_r, axis=0)
Дисперсия коэффициентов корреляции при использовании Ridge также значительно меньше. Это известная концепция в машинном обучении — баланс между смещением и дисперсией (Bias-Variance Trade-off). В следующем разделе мы рассмотрим, как настраивать параметры регуляризации Ridge, что является ключевой частью этого баланса.
Перед тем как рассматривать параметры регуляризации, давайте ещё раз сравним Ridge и линейную регрессию. Как было упомянуто ранее, цель линейной регрессии заключается в минимизации $ {\begin{Vmatrix} \hat y - X \beta \end{Vmatrix}}^2 $.
Цель Ridge заключается в минимизации $ {\begin{Vmatrix} \hat y - X \beta \end{Vmatrix}}^2 + {\begin{Vmatrix} \Gamma X \end{Vmatrix}}^2 $,
где $\Gamma$ представляет собой параметр alpha
в Ridge, который равен единичному масштабированному матрице. Пример использует значение по умолчанию. Мы можем вывести параметры Ridge следующим образом:
Ridge()
```Решение для коэффициентов корреляции Ridge имеет вид:
$$\beta = {(X^TX + \Gamma^T \Gamma)}^{-1}X \hat{y}$$
Первая половина формулы имеет то же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена $(\Gamma^T \Gamma)$. Матрица $A$, при умножении которой на саму себя и транспонированную версию ($AA^T$), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора $x$ выполняется условие $x^TAx \geq 0$). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и Ridge Regression.```markdown
Первая половина формулы имеет такое же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена (\(\Gamma^T \Gamma\)). Матрица \(A\), при умножении которой на саму себя и транспонированную версию (\(AA^T\)), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора \(x\) выполнено условие \(x^TAx \ge 0\)). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и岭回归。
# 2.4 Оптимизация параметров岭回归
Когда вы используете модель岭回归 для моделирования, следует учитывать параметр `alpha` в классе `Ridge`.
Например, использование OLS (обычного метода наименьших квадратов) может показать некоторые отношения между двумя переменными; однако после регуляризации с помощью параметра `alpha`, эти отношения могут исчезнуть. При принятии решений важно учитывать эти зависимости.
Первая половина формулы имеет такое же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена (\(\Gamma^T \Gamma\)). Матрица \(A\), при умножении которой на саму себя и транспонированную версию (\(AA^T\)), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора \(x\) выполнено условие \(x^TAx \ge 0\)). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и岭回归。
# 2.4 Оптимизация параметров岭回归
Когда вы используете модель岭回归 для моделирования, следует учитывать параметр `alpha` в классе `Ridge`.
Например, использование OLS (обычного метода наименьших квадратов) может показать некоторые отношения между двумя переменными; однако после регуляризации с помощью параметра `alpha`, эти отношения могут исчезнуть. При принятии решений важно учитывать эти зависимости.
Первая половина формулы имеет такое же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена (\(\Gamma^T \Gamma\)). Матрица \(A\), при умножении которой на саму себя и транспонированную версию (\(AA^T\)), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора \(x\) выполнено условие \(x^TAx \ge 0\)). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и岭回归。
# 2.4 Оптимизация параметров岭回归
Когда вы используете модель岭回归 для моделирования, следует учитывать параметр `alpha` в классе `Ridge`.
Например, использование OLS (обычного метода наименьших квадратов) может показать некоторые отношения между двумя переменными; однако после регуляризации с помощью параметра `alpha`, эти отношения могут исчезнуть. При принятии решений важно учитывать эти зависимости.
Первая половина формулы имеет такое же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена (\(\Gamma^T \Gamma\)). Матрица \(A\), при умножении которой на саму себя и транспонированную версию (\(AA^T\)), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора \(x\) выполнено условие \(x^TAx \ge 0\)). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и岭回归。
# 2.4 Оптимизация параметров岭回归
Когда вы используете модель岭回归 для моделирования, следует учитывать параметр `alpha` в классе `Ridge`.
Например, использование OLS (обычного метода наименьших квадратов) может показать некоторые отношения между двумя переменными; однако после регуляризации с помощью параметра `alpha`, эти отношения могут исчезнуть. При принятии решений важно учитывать эти зависимости.
Первая половина формулы имеет такое же решение, как и для коэффициента корреляции в линейной регрессии, но с добавлением одного члена (\(\Gamma^T \Gamma\)). Матрица \(A\), при умножении которой на саму себя и транспонированную версию (\(AA^T\)), даёт симметричную матрицу, которая является положительно полуопределенной (для любого ненулевого вектора \(x\) выполнено условие \(x^TAx \ge 0\)). Это эквивалентно увеличению большого числа в знаменателе целевой функции линейной регрессии, что приводит к тому, что коэффициент корреляции стремится к нулю. Такое объяснение довольно грубое; для более глубокого понимания рекомендую обратиться к связи SVD (разложение матрицы по сингулярным значениям) и岭回归。
# 2.4 Оптимизация параметров岭回归
Когда вы используете модель岭回归 для моделирования, следует учитывать параметр `alpha` в классе `Ridge`.
Например, использование OLS (обычного метода наименьших квадратов) может показать некоторые отношения между двумя переменными; однако после регуляризации с помощью параметра `alpha`, эти отношения могут исчезнуть. При принятии решений важно учитывать эти зависимости.
```<!-- TEASER_END -->
## Подготовка
Это наш первый пример оптимизации параметров модели, который обычно выполняется с использованием кросс-валидации. В последующих разделах будут рассмотрены более простые способы выполнения этой задачи, но здесь мы будем делать это шаг за шагом для оптимизации岭回归.
В библиотеке scikit-learn параметр $\Gamma$ в岭回归 является параметром `alpha`. Таким образом, вопрос заключается в том, какой параметр `alpha` является оптимальным. Сначала создаем набор данных для регрессии:
```python
from sklearn.datasets import make_regression
reg_data, reg_target = make_regression(n_samples=100, n_features=2, effective_rank=1, noise=10)
В модуле linear_models
есть объект RidgeCV
, представляющий кросс-валидацию岭回归. Этот процесс похож на метод leave-one-out (LOOCV). Он состоит в том, чтобы при обучении оставить одну выборку и использовать её для тестирования.
import numpy as np
from sklearn.linear_model import RidgeCV
rcv = RidgeCV(alphas=np.array([.1, .2, .3, .4]))
rcv.fit(reg_data, reg_target)
После обучения модели, параметр alpha
будет оптимальным значением:
rcv.alpha_
Здесь значение 0.1
является оптимальным. Чтобы найти более точное значение рядом с 0.1
, можно использовать следующий подход:
rcv = RidgeCV(alphas=np.array([.08, .09, .1, .11, .12]))
rcv.fit(reg_data, reg_target)
``` RidgeCV(alphas=array([ 0.08, 0.09, 0.1 , 0.11, 0.12]), cv=None,
fit_intercept=True, gcv_mode=None, normalize=False, scoring=None,
store_cv_values=False)
```python
rcv.alpha_
0.080000000000000002
Можно продолжать этот процесс до достижения желаемой точности. Здесь демонстрация ограничивается указанными значениями, но в дальнейшем будут рассмотрены более эффективные методы.## Как это работает...
Приведенный выше пример довольно прост, но давайте рассмотрим причины такого подхода и как определить оптимальное значение. На каждом шаге кросс-валидации качество модели оценивается с помощью ошибки на тестовых данных. По умолчанию используется квадратичная ошибка. Подробнее см. раздел Еще подробнее...
.
Можно заставить объект RidgeCV
хранить данные кросс-валидации, чтобы визуализировать весь процесс:
alphas_to_test = np.linspace(0.0001, 0.05)
rcv3 = RidgeCV(alphas=alphas_to_test, store_cv_values=True)
rcv3.fit(reg_data, reg_target)
RidgeCV(alphas=array([ 0.0001 , 0.00112, 0.00214, 0.00316, 0.00417, 0.00519,
0.00621, 0.00723, 0.00825, 0.00927, 0.01028, 0.0113 ,
0.01232, 0.01334, 0.01436, 0.01538, 0.01639, 0.01741,
0.01843, 0.01945, 0.02047, 0.02149, 0.0225 , 0.02352,
0.02454, 0.02556...4185,
0.04287, 0.04389, 0.04491, 0.04593, 0.04694, 0.04796,
0.04898, 0.05 ]),
cv=None, fit_intercept=True, gcv_mode=None, normalize=False,
scoring=None, store_cv_values=True)
Вы заметите, что мы проверяем значения от 0.0001 до 0.05, используя 50 точек. Поскольку мы установили store_cv_values
равным True
, мы можем видеть результаты для каждого значения альфа:```python
rcv3.cv_values_.shape
(100, 50)
Используя набор данных из 100 образцов, мы получаем 50 различных значений `alpha`. Мы можем увидеть 50 значений ошибки, минимальное среднее значение ошибки соответствует оптимальному значению `alpha`:
```python
smallest_idx = rcv3.cv_values_.mean(axis=0).argmin()
alphas_to_test[smallest_idx]
0.014357142857142857
Теперь вопрос сводится к тому, "Подтверждает ли RidgeCV наш выбор?" Можно получить значение alpha
следующим образом:
rcv3.alpha_
0.014357142857142857
Для более наглядной визуализации можно построить график зависимости ошибки от значений alpha
. Нарисуем графики для 50 проверенных значений alpha
:
%matplotlib inline
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(7, 5))
ax.set_title("Различные значения $\\alpha$")
xy = (alphas_to_test[smallest_idx], rcv3.cv_values_.mean(axis=0)[smallest_idx])
xytext = (xy[0] + .01, xy[1] + .1)
ax.annotate('Выбранное $\\alpha$', xy=xy, xytext=xytext,
arrowprops=dict(facecolor='black', shrink=0, width=0)
)
ax.plot(alphas_to_test, rcv3.cv_values_.mean(axis=0));
```
## Есть ещё больше...
Если мы хотим использовать другие функции ошибок для создания пользовательских метрик, это тоже возможно. Ранее мы рассматривали MAD (среднее абсолютное отклонение) как одну такую функцию. Мы можем использовать её для оценки модели. В первую очередь нам нужно определить функцию потерь:
```python
def MAD(target, prediction):
absolute_deviation = np.abs(target - prediction)
return absolute_deviation.mean()
```После того как мы определили функцию потерь, мы можем воспользоваться функцией `make_scorer` из модуля `sklearn`. Это позволяет стандартизировать нашу пользовательскую функцию, чтобы объекты scikit-learn могли её использовать. Кроме того, поскольку это функция потерь, а не метрика качества, которая должна максимизироваться, то нам нужно преобразовать задачу минимизации в задачу максимизации с помощью `sklearn`:
```python
import sklearn
MAD = sklearn.metrics.make_scorer(MAD, greater_is_better=False)
rcv4 = RidgeCV(alphas=alphas_to_test, store_cv_values=True, scoring=MAD)
rcv4.fit(reg_data, reg_target)
smallest_idx = rcv4.cv_values_.mean(axis=0).argmin()
alphas_to_test[smallest_idx]
0.05
Метод лассо (least absolute shrinkage and selection operator, минимальное абсолютное сжатие и оператор выбора) очень похож на метод регрессии с岭回归和LARS(最小角度回归)。与岭回归一样,它也通过添加惩罚项来解决特征之间的多重共线性问题。与LARS类似,它可以用于参数选择,并且通常会产生稀疏的相关系数向量。
Регрессия с岭回归并不是万能药。有时需要使用LASSO回归进行建模。本主题将使用不同的损失函数,因此需要相应的评估方法。
Сначала создаем набор данных с помощью функции make_regression
:
from sklearn.datasets import make_regression
reg_data, reg_target = make_regression(n_samples=200, n_features=50 Yöntemleri, n_informative=5, noise=5)
Затем импортируем объект lasso
:
from sklearn.linear_model import Lasso
lasso = Lasso()
```Объект `lasso` имеет множество параметров, но наиболее важным является параметр `alpha`, который используется для настройки штрафной функции лассо. Этот параметр будет подробно рассмотрен в разделе **Как это работает...**. Сейчас мы используем значение по умолчанию `1`. Также, как и в случае с岭回归, если установить его равным `0`, то `lasso` становится обычной линейной регрессией:
岭回归 ->岭 регрессия```python
lasso.fit(reg_data, reg_target)
Рассмотрим ещё раз количество ненулевых коэффициентов корреляции:
import numpy as np
np.sum(lasso.coef_ != 0)
9
lasso_0 = Lasso(0)
lasso_0.fit(reg_data, reg_target)
np.sum(lasso_0.coef_ != 0)
d:\programfiles\Miniconda3\lib\site-packages\IPython\kernel\__main__.py:2: UserWarning: With alpha=0, this algorithm does not converge well. You are advised to use the LinearRegression estimator
from IPython.kernel.zmq import kernelapp as app
d:\programfiles\Miniconda3\lib\site-packages\sklearn\linear_model\coordinate_descent.py:432: UserWarning: Coordinate descent with alpha=0 may lead to unexpected results and is discouraged.
positive
500
Как мы и ожидали, если использовать линейную регрессию, ни один коэффициент корреляции не становится равным нулю. Кроме того, если вы запустите этот код, scikit-learn выдаст предупреждение, как показано выше.
Для линейной регрессии мы минимизируем сумму квадратов остатков. В случае регрессии LASSO мы также минимизируем сумму квадратов остатков, но добавляем штраф, который приводит к сжатости данных. Это можно представить следующим образом:
$$ \sum e_i + \lambda \left| \beta \right|_1 $$
Ещё одно выражение для минимизации суммы квадратов остатков:
$$ RSS(\beta), где \left| \beta \right|_1 < \beta $$Это ограничение делает данные сжатыми. Ограничение в регрессии LASSO создаёт гиперкуб, где коэффициенты корреляции являются осями, что означает, что большинство точек находятся на вершинах, где коэффициенты корреляции равны нулю. В то время как в регрессии Ridge ограничение представляет собой гиперплоскость, так как его ограничение является нормой L2, которая имеет одно ограничение, но даже при наличии ограничений коэффициенты корреляции никогда не становятся равными нулю.### Кросс-валидация LASSO
В вышеприведённой формуле выбор правильного значения (\lambda) (или alpha
в Lasso
scikit-learn, хотя в книге используется (\lambda)) является ключевым моментом. Мы можем установить его самостоятельно или получить оптимальное значение через кросс-валидацию:
from sklearn.linear_model import LassoCV
lassocv = LassoCV()
lassocv.fit(reg_data, reg_target)
Атрибут lassocv
позволяет определить наиболее подходящее значение (\lambda):
lassocv.alpha_
Вы можете заметить вычисленные коэффициенты корреляции:
lassocv.coef_[:5]
После применения ближайших параметров lassocv
имеет 29 ненулевых коэффициентов корреляции:
np.sum(lassocv.coef_ != 0)
LASSO часто используется для выбора признаков для других методов. Например, вы можете использовать регрессию LASSO для получения подходящих признаков, а затем использовать эти признаки в других алгоритмах.
Для получения нужных признаков вам потребуется создать вектор столбцов с ненулевыми коэффициентами корреляции, а затем применить этот вектор к другому алгоритму:
mask = lassocv.coef_ != 0
new_reg_data = reg_data[:, mask]
new_reg_data.shape
LARS — это метод регрессии, предназначенный для решения задач высокой размерности, когда $p >> n$, где $p$ представляет количество колонок или признаков, а $n$ — количество образцов данных.
Сначала импортируем необходимые объекты. В данном случае мы используем набор данных, содержащий 200 образцов и 500 признаков. Мы также установили низкий уровень шума и небольшое количество информативных признаков:
import numpy as np
from sklearn.datasets import make_regression
reg_data, reg_target = make_regression(n_samples=200, n_features=500, n_informative=10, noise=2)
Имея 10 информативных признаков, нам следует установить 10 ненулевых коэффициентов корреляции для LARS. Хотя мы можем не знать точное количество информативных признаков заранее, но для эксперимента это вполне приемлемо:
from sklearn.linear_model import Lars
lars = Lars(n_nonzero_coefs=10)
lars.fit(reg_data, reg_target)
Можно проверить сумму ненулевых коэффициентов корреляции LARS:
np.sum(lars.coef_ != 0)
Результат:
10
Проблема заключается в том, почему меньшее количество признаков становится более эффективным. Чтобы это показать, обучим две модели LARS с половиной количества признаков — одна модель будет иметь 12 ненулевых коэффициентов корреляции, а другая — значение по умолчанию. Мы используем 12, поскольку у нас есть некоторое представление о количестве важных признаков, но мы можем не точно знать его.```python train_n = 100 lars_12 = Lars(n_nonzero_coefs=12) lars_12.fit(reg_data[:train_n], reg_target[:train_n])
lars_500 = Lars() # По умолчанию равно 500 lars_500.fit(reg_data[:train_n], reg_target[:train_n])
Теперь давайте посмотрим, как эти модели работают на данных обучения:
```python
np.mean(np.power(reg_target[train_n:] - lars.predict(reg_data[train_n:]), 2))
np.mean(np.power(reg_target[train_n:] - lars_12.predict(reg_data[train_n:]), 2))
np.mean(np.power(reg_target[train_n:] - lars_500.predict(reg_data[train_n:]), 2))
Просмотрите эту группу результатов; ошибки тестового набора значительно выше. Проблема переобучения заключается именно здесь; обычно сложно найти модель, которая хорошо аппроксимирует тренировочный набор при большом количестве признаков, но переобучение является ещё большим проблемой.
LARS выбирает характеристики, повторно выбрав те, которые связаны с изменениями остатка. Графически говоря, связь фактически представляет собой минимальный угол между характеристикой и остатками; отсюда и название LARS.
После выбора первой характеристики, LARS продолжает двигаться в направлении минимального угла до тех пор, пока следующая характеристика не станет так же сильно связана с остатками. Затем LARS начинает двигаться в направлении углов, образованных двумя характеристиками вместе. Это можно наглядно представить на графике:
%matplotlib inline
import matplotlib.pyplot as plt
```def unit(*args):
squared = map(lambda x: x**2, args)
distance = sum(squared) ** (0.5)
return map(lambda x: x / distance, args)
```f, ax = plt.subplots(nrows=3, figsize=(5, 10))
plt.tight_layout()
ax[0].set_ylim(0, 1.1)
ax[0].set_xlim(0, 1.1)
x, y = unit(1, 0.02)
ax[0].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[0].text(x + .05, y + .05, r"$x_1$")
x, y = unit(.5, 1)
ax[0].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[0].text(x + .05, y + .05, r"$x_2$")
x, y = unit(1, .45)
ax[0].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[0].text(x + .05, y + .05, r"$y$")
ax[0].set_title("Без шагов")
# Шаг 1
ax[1].set_title("Шаг 1")
ax[1].set_ylim(0, 1.1)
ax[1].set_xlim(0, 1.1)
x, y = unit(1, 0.02)
ax[1].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[1].text(x + .05, y + .05, r"$x_1$")
x, y = unit(.5, 1)
ax[1].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[1].text(x + .05, y + .05, r"$x_2$")
x, y = unit(.5, 1)
ax[1].arrow(.5, 0.01, x, y, ls='dashed', edgecolor='black', facecolor='black')
ax[1].text(x + .5 + .05, y + .01 + .05, r"$x_2$")
ax[1].arrow(0, 0, .47, .01, width=.0015, edgecolor='black', facecolor='black')
ax[1].text(.47 - .15, .01 + .03, "Шаг 1")
x, y = unit(1, .45)
ax[1].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[1].text(x + .05, y + .05, r"$y$")
# Шаг 2
ax[2].set_title("Шаг 2")
ax[2].set_ylim(0, 1.1)
ax[2].set_xlim(0, 1.1)
x, y = unit(1, 0.02)
ax[2].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[2].text(x + .05, y + .05, r"$x_1$")
x, y = unit(.5, 1)
ax[2].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[2].text(x + .05, y + .05, r"$x_2$")
x, y = unit(.5, 1)
ax[2].arrow(.5, 0.01, x, y, ls='dashed', edgecolor='black', facecolor='black')
ax[2].text(x + .5 + .05, y + .01 + .05, r"$x_2$")
ax[2].arrow(0, 0, .47, .01, width=.0015, edgecolor='black', facecolor='black')
ax[2].text(.47 - .15, .01 + .03, "Шаг 1")
## Шаг 2
x, y = unit(1, .45)
ax[2].arrow(.5, .02, .4, .35, width=.0015, edgecolor='black', facecolor='black')
ax[2].text(x, y - .1, "Шаг 2")
x, y = unit(1, .45)
ax[2].arrow(0, 0, x, y, edgecolor='black', facecolor='black')
ax[2].text(x + .05, y + .05, r"$y$");
```
Конкретный процесс состоит в том, что мы перемещаем \( x2 \) в направлении \( x1 \) до точки, где скалярное произведение между \( x1 \) и \( y \) равно скалярному произведению между \( x1 \) и \( y \). После достижения этой точки мы продолжаем движение в направлении, образованном половиной угла между \( x1 \) и \( x2 \).
## Есть ещё больше...
Как и в случае использования кросс-валидации для оптимизации модели линейной регрессии, мы можем применять кросс-валидацию к LARS:
```python
from sklearn.linear_model import LarsCV
lcv = LarsCV()
lcv.fit(reg_data, reg_target)
d:\Miniconda3\lib\site-packages\sklearn\linear_model\least_angle.py:285: ConvergenceWarning: Regressors in active set degenerate. Dropping a regressor, после 168 итераций, то есть при alpha=2.278e-02, с активным набором из 132 регрессоров, и минимальным элементом холецкого разложения равным 6.144e-08
ConvergenceWarning)
d:\Miniconda3\lib\site-packages\sklearn\linear_model\least_angle.py:285: ConvergenceWarning: Regressors in active set degenerate. Dropping a regressor, после 168 итераций, то есть при alpha=2.105e-02, с активным набором из 132 регрессоров, и минимальным элементом холецкого разложения равным 9.771e-08
ConvergenceWarning)
LarsCV(copy_X=True, cv=None, eps=2.2204460492503131e-16, fit_intercept=True,
max_iter=500, max_n_alphas=1000, n_jobs=1, normalize=True,
precompute='auto', verbose=False)
Кросс-валидация помогает нам определить оптимальное количество ненулевых коэффициентов корреляции. Валидация показывает следующее:
np.sum(lcv.coef_ != 0)
``` 43
Честно говоря, пока не до конца понял суть LARS, но обязательно вернусь к этому вопросу позже и переведу оригинальный текст.
[1] Efron, Bradley; Hastie, Trevor; Johnstone, Iain и Tibshirani, Robert (2004). "[Метод наименьшего угла](http://web.stanford.edu/~hastie/Papers/LARS/LeastAngle_2002.pdf)". Annals of Statistics 32(2): c. 407–499. doi:10.1214/009053604000000067. MR 2060166.
# 2.7 Обработка задач классификации с помощью линейных методов — логистическая регрессия
На самом деле, линейные модели также могут использоваться для решения задач классификации. Для этого линейная модель обучается на данных, представляющих собой распределение вероятностей определённого типа, а затем применяется функция порогового значения для определения принадлежности объекта к одной из категорий.
<!-- TEASER_END -->
## Подготовка
Здесь используется классический логистический функционал. Очень простая функция:
$$f(x) = \frac{1}{1 + e^{-t}}$$
Его графическое представление показано ниже:
```python
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
f, ax = plt.subplots(figsize=(10, 5))
rng = np.linspace(-5, 5)
log_f = np.apply_along_axis(lambda x:1 / (1 + np.exp(-x)), 0, rng)
ax.set_title("Логистическая функция между [-5, 5]")
ax.plot(rng, log_f);
Давайте создадим набор данных с помощью метода make_classification
, чтобы выполнить классификацию:
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000, n_features=4)
LogisticRegression
аналогично использованию других линейных моделей:from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
Мы будем использовать первые 200 данных в качестве тренировочного набора, а последние 200 — как тестовый набор. Поскольку это случайный набор данных, использование последних 200 данных допустимо. Однако если вы работаете с данными, имеющими некоторую структуру (например, ваш набор данных представляет собой временной ряд), то такой подход был бы неправильным.
X_train = X[:-200]
X_test = X[-200:]
y_train = y[:-200]
y_test = y[-200:]
В более поздних разделах этой книги мы подробнее рассмотрим кросс-валидацию. Здесь нам достаточно просто обучить модель логистической регрессией. Мы будем обращать внимание на прогнозы, сделанные на основе тренировочного набора, так же как и на основе тестового набора. Часто полезно сравнивать правильность прогнозов на двух наборах данных; обычно вы получаете лучшие результаты на тренировочном наборе, а также важно знать процент ошибок модели при прогнозировании на тестовом наборе.
lr.fit(X_train, y_train)
y_train_predictions = lr.predict(X_train)
y_test_predictions = lr.predict(X_test)
Теперь, когда у нас есть прогнозы, давайте посмотрим, насколько они точны. В данном случае мы просто посмотрим на долю правильных ответов; далее мы подробно рассмотрим методы оценки производительности классификаторов.Вычисление простое: число правильных ответов делится на общее количество примеров:
(y_train_predictions == y_train).sum().astype(float) / y_train.shape[0]
(y_test_predictions == y_test).sum().astype(float) / y_test.shape[0]
Как видно, правильность прогнозов на тестовом наборе почти такая же, как и на тренировочном наборе. Однако в реальной жизни часто бывает заметна большая разница.
Теперь вопрос заключается в том, как преобразовать логистическую функцию в метод классификации. Сначала линейная регрессия стремится найти линейное уравнение, которое аппроксимирует среднее значение зависимой переменной Y при данном значении независимых переменных X, то есть E(Y|X) = xβ. Здесь значения Y представляют собой вероятность того или иного типа события. Таким образом, задача классификации сводится к решению E(p|X) = xβ. Затем, если пороговое значение определено, будет выполнено Logit(p) = Xβ. Эта идея может быть расширена до различных видов регрессий, таких как процесс Пуассона (Poisson).
X, y = make_classification(n_samples=5000, n_features=4, weights=[.95])
sum(y) / (len(y) * 1.) # проверка невзвешенного типа
X_train = X[:-500]
X_test = X[-500:]
y_train = y[:-500]
y_test = y[-500:]
lr.fit(X_train, y_train)
y_train_predictions = lr.predict(X_train)
y_test_predictions = lr.predict(X_test)
Теперь давайте посмотрим, как наша модель обучилась:
(y_train_predictions == y_train).sum().astype(float) / y_train.shape[0]
(y_test_predictions == y_test).sum().astype(float) / y_test.shape[0]
(y_test[y_test == 1] == y_test_predictions[y_test == 1]).sum().astype(float) / y_test[y_test == 1].shape[0]
Результаты выглядят неплохо, но это говорит о том, что если мы предсказываем транзакцию как нормальную (или тип 0), то у нас около 95% шансов правильно предсказать. Однако, если мы захотим посмотреть, как модель предсказывает тип 1, то результаты могут оказаться хуже.
Если мы больше заботимся о фальшивых транзакциях по сравнению с обычными, то это зависит от бизнес-правил, и мы можем изменить вес правильных и неправильных предсказаний.Обычно вес фальшивых транзакций относительно обычных пропорционален обратному отношению между весами типов в тренировочном наборе данных. Но поскольку нам важнее качество предсказания фальшивых транзакций, давайте используем метод переобучения (oversampling) для представления этих весов.
lr = ЛогистическаяРегрессия(class_weight={0: .15, 1: .85})
lr.fit(X_train, y_train)
lr = логистическая_регрессия(class_weight={0: .15, 1: .85})
lr.fit(X_train, y_train)
``` Логистическая регрессия (C=1.0, class_weight={0: 0.15, 1: 0.85}, dual=False,
fit_intercept=True, intercept_scaling=1, max_iter=100,
multi_class='ovr', penalty='l2', random_state=None,
solver='liblinear', tol=0.0001, verbose=0)
Давайте снова сделаем прогноз:
```python
y_train_predictions = lr.predict(X_train)
y_test_predictions = lr.predict(X_test)
(y_test[y_test==1] == y_test_predictions[y_test==1]).sum().astype(float) / y_test[y_test==1].shape[0]
0.7083333333333334
Но какой ценой? Давайте посмотрим:
(y_test_predictions == y_test).sum().astype(float) / y_test.shape[0]
0.94
Как видите, точность снизилась на 3%. Подходит ли это вам, зависит от вашего вопроса. Если стоимость ошибочной оценки очень высока, то она может компенсировать затраты на её выявление.
В разделе "Улучшение линейной регрессии с помощью岭回归" мы рассмотрели ограничения оптимизации в Ridge Regression. Мы также представили байесовское объяснение априорного распределения коэффициентов корреляции, которое сильно влияет на априорное распределение, обычно имеющее среднее значение 0.
Теперь давайте продемонстрируем, как использовать эту интерпретацию с помощью scikit-learn.
Байесовская версия Ridge Regression и Lasso Regression могут быть интерпретированы с точки зрения байесовской теории, что противоположно частотному подходу. Scikit-learn реализует только байесовскую версию Ridge Regression, но в разделе "Как это работает..." мы сравним эти две методики.Сначала создадим набор данных для регрессии:
from sklearn.datasets import make_regression
X, y = make_regression(n_samples=1000, n_features=10, n_informative=2, noise=20)
Мы можем загрузить байесовскую версию Ridge Regression и обучить модель:
from sklearn.linear_model import BayesianRidge
br = BayesianRidge()
Есть два набора коэффициентов корреляции — alpha_1 / alpha_2
и lambda_1 / lambda_2
. Здесь alpha_*
являются гиперпараметрами $\alpha$ априорного распределения, а lambda_*
— гиперпараметрами $\lambda$ априорного распределения.
Сначала обучим модель без изменения параметров:
br.fit(X, y)
br.coef_
array([-1.39241213, 0.14671513, -0.08150797, 37.50250891,
0.21850082, -0.78482779, -0.26717555, -0.71319956,
0.7926308 , 5.74658302])
Теперь мы будем корректировать гиперпараметры, обратив внимание на изменения коэффициентов корреляции:
br_alphas = BayesianRidge(alpha_1=10, lambda_ Yöntem=10)
br_alphas.fit(X, y)
br_alphas.coef_
array([ -1.38807423, 0.14050794, -0.08309391, 37.3032803 ,
0.2254332 , -0.77031801, -0.27005478, -0.71632657,
0.78501276, 5.71928608])
Поскольку используется байесовская регрессия с岭回归,мы предполагаем, что априорное распределение ошибок и параметра $\alpha$ имеют $\Gamma$-распределение.
$\Gamma$-распределение представляет собой очень гибкую вероятностную функцию. Различные формы параметров и масштабов $\Gamma$-распределения приводят к различным формам. 1e-06 является значением по умолчанию для параметра формы в scikit-learn для BayesianRidge
.
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.stats import gamma
import numpy as np
form = lambda x, y: "loc={}, scale={}".format(x, y)
g = lambda x, y=1e-06, z=1e-06: gamma.pdf(x, y, z)
g2 = lambda x, y=1e-06, z=1: gamma.pdf(x, y, z)
g3 = lambda x, y=1e-06, z=2: gamma.pdf(x, y, z)
rng = np.linspace(0, 5)
f, ax = plt.subplots(figsize=(8, 5))
```ax.plot(rng, list(map(g, rng)), label=form(1e-06, 1e-06), color='r')
ax.plot(rng, list(map(g2, rng)), label=form(1e-06, 1), color='g')
ax.plot(rng, list(map(g3, rng)), label=form(1e-06, 2), color='b')
ax.set_title("Различные формы распределения Гамма")
ax.legend();
Вы заметите, что коэффициенты корреляций в конечном итоге сжимаются до нуля, особенно когда значение параметра формы очень маленькое.
Как я уже упомянул ранее, существует также байесовское объяснение лассо-регрессии. Мы рассматриваем предположительное распределение как функцию от коэффициентов корреляций; они сами являются случайными величинами. Для лассо-регрессии мы выбираем распределение, которое может порождать ноль, например двойное экспоненциальное распределение (Double Exponential Distribution, также известное как Laplace distribution).
from scipy.stats import laplace
form = lambda x, y: "loc={}, scale={}".format(x, y)
g = lambda x: laplace.pdf(x)
rng = np.linspace(-5, 5)
f, ax = plt.subplots(figsize=(8, 5))
ax.plot(rng, list(map(g, rng)), color='r')
ax.set_title("Пример двойного экспоненциального распределения");
```
Обратите внимание на вершину в точке x = 0. Это приведёт к корреляционному коэффициенту ошибок, равному нулю. Управление гиперпараметрами может также создать ситуации с корреляционным коэффициентом, равным нулю, что зависит от конкретной задачи.
# 2.10 Обучение с использованием градиентного бустингаГрадиентный бустинг регрессии (Gradient Boosting Regression, GBR) представляет собой метод обучения, основанный на анализе ошибок модели. В основе этого подхода лежит идея объединения множества слабых моделей для создания более мощной модели. Две важные особенности следует отметить:
- Каждая слабая модель имеет ограниченную производительность, но их совместное использование позволяет достичь высокой точности.
- Эти модели применяются последовательно, то есть каждая следующая модель обучается на ошибках предыдущей.
<!-- TEASER_END -->
## Подготовка
Для демонстрации GBR используем базовый набор данных для регрессии.
```python
import numpy as np
from sklearn.datasets import make_regression
X, y = make_regression(n_samples=1000, n_features=2, noise=10)
GBR можно рассматривать как интегрированную модель, так как он представляет собой интеграцию нескольких слабых моделей для создания более мощной модели.
from sklearn.ensemble import GradientBoostingRegressor as GBR
gbr = GBR()
gbr.fit(X, y)
gbr_preds = gbr.predict(X)
Очевидно, здесь используется несколько моделей, но сейчас мы рассмотрим простую реализацию. Теперь сравним её с базовой моделью регрессии.
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X, y)
lr_preds = lr.predict(X)
```Сравнивая эти две модели, давайте посмотрим, как GBR работает лучше линейной регрессии. Для создания графиков можно использовать ту же процедуру, которая была описана в главе о нормальном распределении случайных процессов. Начнём с вычислений ошибок:```python
gbr_residuals = y - gbr_preds
lr_residuals = y - lr_preds
%matplotlib inline
from matplotlib import pyplot as plt
f, ax = plt.subplots(figsize=(7, 5))
f.tight_layout()
ax.hist(gbr_residuals, bins=20, label='GBR ошибки', color='b', alpha=.5);
ax.hist(lr_residuals, bins=20, label='ЛР ошибки', color='r', alpha=.5);
ax.set_title("Ошибки GBR против ЛР")
ax.legend(loc='best');
Похоже, что GBR лучше всего подходит для прогнозирования, хотя различия могут быть незначительными. Давайте сравним их с помощью доверительного интервала (confidence interval, CI) на уровне 95%.
np.percentile(gbr_residuals, [2.5, 97.5])
np.percentile(lr_residuals, [2.5, 97.5])
Доверительный интервал GBR меньше, данные более сконцентрированы, поэтому его прогнозирующая способность лучше; мы также можем внести некоторые изменения в алгоритм GBR для улучшения качества модели. Ниже приведён пример демонстрации этого процесса, а затем будет рассмотрена методика оптимизации:
n_estimators = np.arange(100, 1100, 350)
gbrs = [GBR(n_estimators=n_estimator) for n_estimator in n_estimators]
residuals = {}
for i, gbr in enumerate(gbrs):
gbr.fit(X, y)
residuals[gbr.n_estimators] = y - gbr.predict(X)
f, ax = plt.subplots(figsize=(7, 5))
f.tight_layout()
colors = {800:'r', 450:'g', 100:'b'}
for k, v in residuals.items():
ax.hist(v, bins=20, label='n_estimators: %d' % k, color=colors[k], alpha=.5);
ax.set_title("Остатки при различных количествах оценщиков")
ax.legend(loc='best');
График выглядит немного запутанным, но всё же можно заметить, что с увеличением количества оценщиков, ошибка снижается. Однако это не всегда так. Во-первых, мы не провели кросс-валидацию, во-вторых, с увеличением количества оценщиков время обучения также возрастает. В данном случае это ещё не проблема, но если объём данных увеличится в два или три раза, то вопрос становится более актуальным.## Как это работает...
В примере выше первый параметр n_estimators
указывает количество используемых алгоритмов обучения в GBR. Обычно, если ваше оборудование имеет лучшие характеристики, вы можете установить значение n_estimators
больше, что улучшит качество модели. Также стоит отметить несколько других параметров.
Перед тем как оптимизировать остальные параметры, рекомендуется сначала настроить параметр max_depth
. Поскольку каждый алгоритм обучения представляет собой дерево решений, параметр max_depth
определяет количество уровней, которое генерируется деревом. Выбор правильного количества уровней может лучше подогнать модель под данные, а слишком большое количество уровней может привести к переобучению.
Параметр loss
определяет функцию потерь, которая напрямую влияет на ошибку. По умолчанию используется значение ls
, что означает метод наименьших квадратов (least squares). Есть также другие варианты, такие как минимальная абсолютная величина ошибки, Huber loss и функции потерь для квартилей (quantiles).
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )