Comparando Regressores Bayesianos Lineares

Beginner

This tutorial is from open-source community. Access the source code

Introdução

Este laboratório utiliza um conjunto de dados sintético para comparar dois regressores Bayesianos diferentes: Determinação Automática de Relevância e Regressão de Ridge Bayesiana. A primeira parte do laboratório compara os coeficientes dos modelos em relação aos coeficientes verdadeiros, utilizando um modelo de Mínimos Quadrados Ordinários (OLS) como linha de base. Na última seção, o laboratório plota previsões e incertezas para as regressões ARD e de Ridge Bayesiana utilizando uma expansão de recursos polinomiais para ajustar uma relação não linear entre X e y.

Dicas da Máquina Virtual

Após o arranque da VM, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Gerar Conjunto de Dados Sintético

Geramos um conjunto de dados sintético onde X e y estão linearmente relacionados. Dez dos recursos de X serão usados para gerar y. Os outros recursos não são úteis na previsão de y. Além disso, geramos um conjunto de dados onde n_samples == n_features. Tal cenário é desafiador para um modelo OLS e pode levar a pesos arbitrariamente grandes. Ter uma prioridade nos pesos e uma penalidade alivia o problema. Finalmente, é adicionado ruído gaussiano.

from sklearn.datasets import make_regression

X, y, true_weights = make_regression(
    n_samples=100,
    n_features=100,
    n_informative=10,
    noise=8,
    coef=True,
    random_state=42,
)

Ajustar os Regressores

Ajustamos os dois modelos Bayesianos e o OLS para posteriormente comparar os coeficientes dos modelos.

import pandas as pd
from sklearn.linear_model import ARDRegression, LinearRegression, BayesianRidge

olr = LinearRegression().fit(X, y)
brr = BayesianRidge(compute_score=True, n_iter=30).fit(X, y)
ard = ARDRegression(compute_score=True, n_iter=30).fit(X, y)
df = pd.DataFrame(
    {
        "Weights of true generative process": true_weights,
        "ARDRegression": ard.coef_,
        "BayesianRidge": brr.coef_,
        "LinearRegression": olr.coef_,
    }
)

Plotar os Coeficientes Verdadeiros e Estimados

Comparamos os coeficientes de cada modelo com os pesos do modelo gerador verdadeiro.

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.colors import SymLogNorm

plt.figure(figsize=(10, 6))
ax = sns.heatmap(
    df.T,
    norm=SymLogNorm(linthresh=10e-4, vmin=-80, vmax=80),
    cbar_kws={"label": "valores dos coeficientes"},
    cmap="seismic_r",
)
plt.ylabel("modelo linear")
plt.xlabel("coeficientes")
plt.tight_layout(rect=(0, 0, 1, 0.95))
_ = plt.title("Coeficientes dos Modelos")

Plotar a Log-verossimilhança Marginal

Plotamos a log-verossimilhança marginal de ambos os modelos.

import numpy as np

ard_scores = -np.array(ard.scores_)
brr_scores = -np.array(brr.scores_)
plt.plot(ard_scores, color="navy", label="ARD")
plt.plot(brr_scores, color="red", label="BayesianRidge")
plt.ylabel("Log-verossimilhança")
plt.xlabel("Iterações")
plt.xlim(1, 30)
plt.legend()
_ = plt.title("Log-verossimilhança dos Modelos")

Gerar Conjunto de Dados Sintético

Criamos um alvo que é uma função não linear da característica de entrada. É adicionado ruído que segue uma distribuição uniforme padrão.

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures, StandardScaler

rng = np.random.RandomState(0)
n_samples = 110

## ordenar os dados para facilitar a plotagem mais tarde
X = np.sort(-10 * rng.rand(n_samples) + 10)
noise = rng.normal(0, 1, n_samples) * 1.35
y = np.sqrt(X) * np.sin(X) + noise
full_data = pd.DataFrame({"input_feature": X, "target": y})
X = X.reshape((-1, 1))

## extrapolação
X_plot = np.linspace(10, 10.4, 10)
y_plot = np.sqrt(X_plot) * np.sin(X_plot)
X_plot = np.concatenate((X, X_plot.reshape((-1, 1))))
y_plot = np.concatenate((y - noise, y_plot))

Ajustar os Regressores

Experimentamos um polinómio de grau 10 para potencialmente sobreajustar, embora os modelos lineares bayesianos regularizem o tamanho dos coeficientes polinomiais. Como fit_intercept=True por defeito para ARDRegression e BayesianRidge, então PolynomialFeatures não deve introduzir um recurso de viés adicional. Ao definir return_std=True, os regressores bayesianos retornam o desvio padrão da distribuição posterior para os parâmetros do modelo.

ard_poly = make_pipeline(
    PolynomialFeatures(degree=10, include_bias=False),
    StandardScaler(),
    ARDRegression(),
).fit(X, y)
brr_poly = make_pipeline(
    PolynomialFeatures(degree=10, include_bias=False),
    StandardScaler(),
    BayesianRidge(),
).fit(X, y)

y_ard, y_ard_std = ard_poly.predict(X_plot, return_std=True)
y_brr, y_brr_std = brr_poly.predict(X_plot, return_std=True)

Plotting Polynomial Regressions with Standard Errors of the Scores

The error bars represent one standard deviation of the predicted gaussian distribution of the query points. Notice that the ARD regression captures the ground truth the best when using the default parameters in both models, but further reducing the lambda_init hyperparameter of the Bayesian Ridge can reduce its bias. Finally, due to the intrinsic limitations of a polynomial regression, both models fail when extrapolating.

ax = sns.scatterplot(
    data=full_data, x="input_feature", y="target", color="black", alpha=0.75
)
ax.plot(X_plot, y_plot, color="black", label="Ground Truth")
ax.plot(X_plot, y_brr, color="red", label="BayesianRidge with polynomial features")
ax.plot(X_plot, y_ard, color="navy", label="ARD with polynomial features")
ax.fill_between(
    X_plot.ravel(),
    y_ard - y_ard_std,
    y_ard + y_ard_std,
    color="navy",
    alpha=0.3,
)
ax.fill_between(
    X_plot.ravel(),
    y_brr - y_brr_std,
    y_brr + y_brr_std,
    color="red",
    alpha=0.3,
)
ax.legend()
_ = ax.set_title("Polynomial fit of a non-linear feature")

Resumo

Este laboratório compara dois regressores Bayesianos diferentes usando um conjunto de dados sintético. A primeira parte do laboratório compara os coeficientes dos modelos em relação aos coeficientes verdadeiros, utilizando um modelo de Mínimos Quadrados Ordinários (MQO) como linha de base. Na última secção, o laboratório plota as previsões e incertezas para as regressões ARD e Bayesian Ridge utilizando uma expansão de características polinomiais para ajustar uma relação não linear entre X e y.