Spec-Zone.ru › scikit-learn

Примечание

Перейти в конец, чтобы скачать полный код примера или запустить этот пример в браузере через JupyterLite или Binder.

Выбор модели Лассо: AIC-BIC / перекрёстная проверка

В этом примере рассматривается выбор модели для моделей Лассо — линейных моделей с L1-штрафом для задач регрессии.

Для выбора значения параметра регуляризации можно использовать несколько стратегий: перекрёстную проверку или информационный критерий, а именно AIC или BIC.

Далее мы подробно рассмотрим различные стратегии.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Набор данных

В этом примере мы будем использовать набор данных о диабете.

from sklearn.datasets import load_diabetes

X, y = load_diabetes(return_X_y=True, as_frame=True)
X.head()
age sex bmi bp s1 s2 s3 s4 s5 s6
0 0.038076 0.050680 0.061696 0.021872 -0.044223 -0.034821 -0.043401 -0.002592 0.019907 -0.017646
1 -0.001882 -0.044642 -0.051474 -0.026328 -0.008449 -0.019163 0.074412 -0.039493 -0.068332 -0.092204
2 0.085299 0.050680 0.044451 -0.005670 -0.045599 -0.034194 -0.032356 -0.002592 0.002861 -0.025930
3 -0.089063 -0.044642 -0.011595 -0.036656 0.012191 0.024991 -0.036038 0.034309 0.022688 -0.009362
4 0.005383 -0.044642 -0.036385 0.021872 0.003935 0.015596 0.008142 -0.002592 -0.031988 -0.046641


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

import numpy as np
import pandas as pd

rng = np.random.RandomState(42)
n_random_features = 14
X_random = pd.DataFrame(
    rng.randn(X.shape[0], n_random_features),
    columns=[f"random_{i:02d}" for i in range(n_random_features)],
)
X = pd.concat([X, X_random], axis=1)
# Show only a subset of the columns
X[X.columns[::3]].head()
age bp s3 s6 random_02 random_05 random_08 random_11
0 0.038076 0.021872 -0.043401 -0.017646 0.647689 -0.234137 -0.469474 -0.465730
1 -0.001882 -0.026328 0.074412 -0.092204 -1.012831 -1.412304 0.067528 0.110923
2 0.085299 -0.005670 -0.032356 -0.025930 -0.601707 -1.057711 0.208864 0.196861
3 -0.089063 -0.036656 -0.036038 -0.009362 -1.478522 1.057122 0.324084 0.611676
4 0.005383 0.021872 0.008142 -0.046641 0.331263 -0.185659 0.812526 1.003533


Выбор модели Лассо с помощью информационного критерия

LassoLarsIC — оцениватель Лассо, который использует информационный критерий Акаике (AIC) или байесовский информационный критерий (BIC) для выбора оптимального значения параметра регуляризации alpha.

Перед обучением модели мы стандартизируем данные с помощью StandardScaler. Кроме того, мы измерим время обучения и настройки гиперпараметра alpha, чтобы сравнить этот подход со стратегией перекрёстной проверки.

Сначала обучим модель Лассо с критерием AIC.

import time

from sklearn.linear_model import LassoLarsIC
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

start_time = time.time()
lasso_lars_ic = make_pipeline(StandardScaler(), LassoLarsIC(criterion="aic")).fit(X, y)
fit_time = time.time() - start_time

Мы сохраняем метрику AIC для каждого значения alpha, использованного во время fit.

results = pd.DataFrame(
    {
        "alphas": lasso_lars_ic[-1].alphas_,
        "AIC criterion": lasso_lars_ic[-1].criterion_,
    }
).set_index("alphas")
alpha_aic = lasso_lars_ic[-1].alpha_

Теперь проведём такой же анализ с использованием критерия BIC.

lasso_lars_ic.set_params(lassolarsic__criterion="bic").fit(X, y)
results["BIC criterion"] = lasso_lars_ic[-1].criterion_
alpha_bic = lasso_lars_ic[-1].alpha_

Можно проверить, какое значение alpha приводит к минимальным значениям AIC и BIC.

def highlight_min(x):
    x_min = x.min()
    return ["font-weight: bold" if v == x_min else "" for v in x]


results.style.apply(highlight_min)
Критерий AIC Критерий BIC
alphas
45.160030 5244.764779 5244.764779
42.300343 5208.250639 5212.341949
21.542052 4928.018900 4936.201520
15.034077 4869.678359 4881.952289
6.189631 4815.437362 4831.802601
5.329616 4810.423641 4830.880191
4.306012 4803.573491 4828.121351
4.124225 4804.126502 4832.765671
3.820705 4803.621645 4836.352124
3.750389 4805.012521 4841.834310
3.570655 4805.290075 4846.203174
3.550213 4807.075887 4852.080295
3.358295 4806.878051 4855.973770
3.259297 4807.706026 4860.893055
3.237703 4809.440409 4866.718747
2.850031 4805.989341 4867.358990
2.384338 4801.702266 4867.163224
2.296575 4802.594754 4872.147022
2.031555 4801.236720 4874.880298
1.618263 4798.484109 4876.218997
1.526599 4799.543841 4881.370039
0.586798 4794.238744 4880.156252
0.445978 4795.589715 4885.598533
0.259031 4796.966981 4891.067109
0.032179 4794.662409 4888.762537
0.019069 4794.652739 4888.752867
0.000000 4796.626286 4894.817724


Наконец, построим график значений AIC и BIC для разных значений alpha. Вертикальные линии на графике соответствуют значению alpha, выбранному для каждого критерия. Выбранное значение alpha соответствует минимуму критерия AIC или BIC.

ax = results.plot()
ax.vlines(
    alpha_aic,
    results["AIC criterion"].min(),
    results["AIC criterion"].max(),
    label="alpha: AIC estimate",
    linestyles="--",
    color="tab:blue",
)
ax.vlines(
    alpha_bic,
    results["BIC criterion"].min(),
    results["BIC criterion"].max(),
    label="alpha: BIC estimate",
    linestyle="--",
    color="tab:orange",
)
ax.set_xlabel(r"$\alpha$")
ax.set_ylabel("criterion")
ax.set_xscale("log")
ax.legend()
_ = ax.set_title(
    f"Information-criterion for model selection (training time {fit_time:.2f}s)"
)
Information-criterion for model selection (training time 0.01s)

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

Кроме того, эти модели часто дают сбой при плохой обусловленности задачи (признаков больше, чем образцов). В таком случае необходимо предоставить оценку дисперсии шума.

Выбор модели Лассо с помощью перекрёстной проверки

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

В scikit-learn доступны два оценивателя со встроенной перекрёстной проверкой: LassoCV и LassoLarsCV, которые решают задачу соответственно с помощью покоординатного спуска и регрессии наименьшего угла.

В оставшейся части раздела мы рассмотрим оба подхода. Для обоих алгоритмов будем использовать стратегию перекрёстной проверки с 20 блоками.

Лассо с помощью покоординатного спуска

Начнём с настройки гиперпараметров с помощью LassoCV.

from sklearn.linear_model import LassoCV

start_time = time.time()
model = make_pipeline(StandardScaler(), LassoCV(cv=20)).fit(X, y)
fit_time = time.time() - start_time
import matplotlib.pyplot as plt

ymin, ymax = 2300, 3800
lasso = model[-1]
plt.semilogx(lasso.alphas_, lasso.mse_path_, linestyle=":")
plt.plot(
    lasso.alphas_,
    lasso.mse_path_.mean(axis=-1),
    color="black",
    label="Average across the folds",
    linewidth=2,
)
plt.axvline(lasso.alpha_, linestyle="--", color="black", label="alpha: CV estimate")

plt.ylim(ymin, ymax)
plt.xlabel(r"$\alpha$")
plt.ylabel("Mean square error")
plt.legend()
_ = plt.title(
    f"Mean square error on each fold: coordinate descent (train time: {fit_time:.2f}s)"
)
Mean square error on each fold: coordinate descent (train time: 0.32s)

Лассо с помощью регрессии наименьшего угла

Начнём с настройки гиперпараметров с помощью LassoLarsCV.

from sklearn.linear_model import LassoLarsCV

start_time = time.time()
model = make_pipeline(StandardScaler(), LassoLarsCV(cv=20)).fit(X, y)
fit_time = time.time() - start_time
lasso = model[-1]
plt.semilogx(lasso.cv_alphas_, lasso.mse_path_, ":")
plt.semilogx(
    lasso.cv_alphas_,
    lasso.mse_path_.mean(axis=-1),
    color="black",
    label="Average across the folds",
    linewidth=2,
)
plt.axvline(lasso.alpha_, linestyle="--", color="black", label="alpha CV")

plt.ylim(ymin, ymax)
plt.xlabel(r"$\alpha$")
plt.ylabel("Mean square error")
plt.legend()
_ = plt.title(f"Mean square error on each fold: Lars (train time: {fit_time:.2f}s)")
Mean square error on each fold: Lars (train time: 0.10s)

Итоги использования перекрёстной проверки

Оба алгоритма дают примерно одинаковые результаты.

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

Обратите внимание, что оптимальное значение alpha различается для каждого блока. Это показывает, почему вложенная перекрёстная проверка — хорошая стратегия при оценке производительности метода, параметр которого выбирается с помощью перекрёстной проверки: выбранный параметр может оказаться неоптимальным при окончательной оценке только на новой тестовой выборке.

Заключение

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

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

Поэтому оптимизация гиперпараметров с помощью кросс-валидации — надежная стратегия: она работает в разных условиях.

Общее время выполнения скрипта: (0 минут 1.077 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_lasso_model_selection.ipynb

Download Python source code: plot_lasso_model_selection.py

Download zipped: plot_lasso_model_selection.zip

Связанные примеры

Выбор модели Lasso с помощью информационных критериев

Траектории Lasso, Lasso-LARS и Elastic Net

Модели на основе L1 для разреженных сигналов

Совместный выбор признаков с помощью многозадачного Lasso

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/auto_examples/linear_model/plot_lasso_model_selection.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API