Monday, June 6, 2022

Lasso model selection: AIC-BIC and Cross-Validation

 Code 1

(.env) boris@boris-All-Series:~/MATPLOTLIBSR/LASSO$ cat plot_lasso_model_selection.py

"""

=============================================

Lasso model selection: AIC-BIC / cross-validation

=============================================

В этом примере основное внимание уделяется выбору модели для моделей Lasso, которые

линейные модели со штрафом L1 для задач регрессии.

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

параметр регуляризации: через перекрестную проверку или с использованием информации

критерием, а именно AIC или BIC

"""

from sklearn.datasets import load_diabetes

X, y = load_diabetes(return_X_y=True, as_frame=True)

X.head()

# In addition, we add some random features to the original data to

# better illustrate the feature selection performed by the Lasso model.


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()

# :class:`~sklearn.linear_model.LassoLarsIC` предоставляет оценщик Лассо, который

# использует информационный критерий Акаике (AIC) или информацию Байеса

# критерий (БИК) для выбора оптимального значения регуляризации

# параметр альфа.

# Перед подгонкой модели мы стандартизируем данные с помощью

# :class:`~sklearn.preprocessing.StandardScaler`. Кроме того, мы будем

# измерьте время, необходимое для подгонки и настройки гиперпараметра альфа, чтобы

# сравнить со стратегией перекрестной проверки.

# Сначала мы подгоним модель Лассо к критерию AIC.

import time

from sklearn.preprocessing import StandardScaler

from sklearn.linear_model import LassoLarsIC

from sklearn.pipeline import make_pipeline


start_time = time.time()

lasso_lars_ic = make_pipeline(

    StandardScaler(), LassoLarsIC(criterion="aic", normalize=False)

).fit(X, y)

fit_time = time.time() - start_time

# We store the AIC metric for each value of alpha used during `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_

# Now, we perform the same analysis using the BIC criterion.

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_

# We can check which value of `alpha` leads to the minimum AIC and 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 для различных альфа-значений.

# Вертикальные линии на графике соответствуют альфе, выбранной для каждого

# критерий. Выбранная альфа соответствует минимуму 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)"

)

# Выбор Lasso через перекрестную проверку

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

# спуск и регрессия по наименьшему углу. Они различаются по своим

# скоростям выполнения и источникам числовых ошибок.

# В scikit-learn доступны два разных оценщика со встроенной

# перекрестной проверкой: :class:`~sklearn.linear_model.LassoCV` и

# :class:`~sklearn.linear_model.LassoLarsCV`, которые соответственно решают

# проблему с координатным спуском и регрессией по наименьшему углу.

# В оставшейся части представим оба подхода. Для обоих

# алгоритмов, будем использовать стратегию 20-кратной перекрестной проверки.

# Лассо по координатному спуску. Начнем с настройки гиперпараметров с помощью

# :class:`~sklearn.linear_model.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 via least angle regression

# Let's start by making the hyperparameter tuning using

# :class:`~sklearn.linear_model.LassoLarsCV`.

from sklearn.linear_model import LassoLarsCV

start_time = time.time()

model = make_pipeline(StandardScaler(), LassoLarsCV(cv=20, normalize=False)).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)")

plt.show()




























No comments:

Post a Comment