Примечание
Перейти к концу для загрузки полного примера кода. или для запуска этого примера в вашем браузере через JupyterLite или Binder
Выбор модели Lasso: AIC-BIC / перекрестная проверка
Этот пример посвящен выбору модели для моделей Lasso, которые являются линейными моделями с 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()
Кроме того, мы добавляем некоторые случайные признаки к исходным данным, чтобы лучше проиллюстрировать выбор признаков, выполняемый моделью Lasso.
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()
Выбор Lasso с помощью информационного критерия
LassoLarsIC предоставляет оценщик Lasso, который использует информационный критерий Акаике (AIC) или байесовский информационный критерий (BIC) для выбора оптимального значения параметра регуляризации alpha.
Перед обучением модели мы стандартизуем данные с помощью StandardScaler. Кроме того, мы измерим время обучения и настройки гиперпараметра alpha, чтобы сравнить со стратегией перекрестной проверки.
Сначала мы обучим модель Lasso с критерием 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 для различных значений 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)"
)

Отбор модели с помощью информационного критерия очень быстр. Он основан на вычислении критерия на предоставленном fit внутривыборочном множестве. Оба критерия оценивают ошибку обобщения модели на основе ошибки на обучающем множестве и штрафуют эту чрезмерно оптимистичную ошибку. Однако этот штраф основан на правильной оценке степеней свободы и дисперсии шума. Оба выводятся для больших выборок (асимптотические результаты) и предполагают, что модель верна, то есть что данные фактически генерируются этой моделью.
Эти модели также склонны к сбоям, когда задача плохо обусловлена (больше признаков, чем выборок). В этом случае требуется предоставить оценку дисперсии шума.
Выбор Lasso с помощью перекрёстной проверки
Модель Lasso может быть реализована с разными решателями: метод сопряжённого градиента и метод наименьших углов. Они отличаются по скорости выполнения и источникам численных ошибок.
В scikit-learn доступны два разных оценщика с интегрированной перекрёстной проверкой: LassoCV и LassoLarsCV, которые соответственно решают задачу с помощью метода сопряжённого градиента и метода наименьших углов.
В оставшейся части этого раздела мы представим оба подхода. Для обоих алгоритмов мы будем использовать стратегию перекрёстной проверки по 20 фолдам.
Lasso с помощью метода сопряжённого градиента
Начнём с настройки гиперпараметров с помощью 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)"
)

Lasso с помощью метода наименьших углов
Начнём с настройки гиперпараметров с помощью 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)")

Резюме подхода перекрёстной проверки
Оба алгоритма дают примерно одинаковые результаты.
Lars вычисляет траекторию решения только для каждой точки перегиба на траектории. В результате он очень эффективен, когда есть только несколько точек перегиба, что имеет место, если мало признаков или образцов. Также он может вычислить полную траекторию без установки каких-либо гиперпараметров. В противоположность этому, метод сопряжённого градиента вычисляет точки траектории на заранее заданной сетке (здесь мы используем значение по умолчанию). Таким образом, он более эффективен, если количество точек на сетке меньше, чем количество точек перегиба на траектории. Такая стратегия может быть интересной, если количество признаков действительно велико, и достаточно образцов для выбора в каждом из фолдов перекрёстной проверки. С точки зрения численных ошибок, при сильно коррелированных переменных Lars будет накапливать больше ошибок, в то время как алгоритм сопряжённого градиента будет только выборочно брать точки на траектории на заданной сетке.
Обратите внимание, как оптимальное значение альфа меняется для каждого фолда. Это демонстрирует, почему перекрёстная проверка со вложенными циклами — хорошая стратегия при попытке оценить эффективность метода, для которого параметр выбирается с помощью перекрёстной проверки: этот выбор параметра может быть не оптимальным для окончательной оценки на невидимом тестовом наборе.
Заключение
В этом руководстве мы представили два подхода к выбору лучшего гиперпараметра alpha: одна стратегия находит оптимальное значение alpha только используя обучающий набор и некоторые критерии информации, а другая стратегия основана на перекрёстной проверке.
В этом примере оба подхода работают аналогично. Выбор гиперпараметров на обучающем наборе демонстрирует свою эффективность с точки зрения вычислительной производительности. Однако он может использоваться только тогда, когда количество образцов достаточно велико по сравнению с количеством признаков.
Вот почему оптимизация гиперпараметров с помощью перекрёстной проверки является безопасной стратегией: она работает в различных сценариях.
Общее время выполнения скрипта: (0 минут 0,929 секунды)
Связанные примеры
© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/linear_model/plot_lasso_model_selection.html