在本例中,将比较两种不同的贝叶斯回归器:自动相关性确定(ARD)和贝叶斯岭回归。首先,使用普通最小二乘法(OLS)模型作为基线,比较模型系数与真实系数之间的关系。然后,将展示这些模型的估计值是通过迭代最大化观测值的边际对数似然来完成的。在最后的部分,将使用多项式特征展开来绘制ARD和贝叶斯岭回归的预测和不确定性,以适应X和y之间的非线性关系。
生成了一个数据集,其中X和y是线性关联的:X的10个特征被用来生成y。其他特征对于预测y没有用处。此外,生成了一个样本数等于特征数的数据集。这样的设置对于OLS模型来说是一个挑战,可能导致任意大的权重。在权重上有一个先验和一个惩罚可以缓解这个问题。最后,添加了高斯噪声。
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)
现在拟合了两种贝叶斯模型和OLS,以便稍后比较模型的系数。
import pandas as pd
from sklearn.linear_model import ARDRegression, BayesianRidge, LinearRegression
olr = LinearRegression().fit(X, y)
brr = BayesianRidge(compute_score=True, max_iter=30).fit(X, y)
ard = ARDRegression(compute_score=True, max_iter=30).fit(X, y)
df = pd.DataFrame({
"真实生成过程的权重": true_weights,
"ARD回归": ard.coef_,
"贝叶斯岭回归": brr.coef_,
"线性回归": olr.coef_,
})
现在将比较每个模型的系数与真实生成模型的权重。由于添加了噪声,没有一个模型能够恢复真实的权重。实际上,所有模型总是有超过10个非零系数。与OLS估计器相比,使用贝叶斯岭回归的系数稍微向零偏移,这稳定了它们。ARD回归提供了一个更稀疏的解决方案:一些非信息系数被精确地设置为零,而其他系数则更接近零。一些非信息系数仍然存在并保留大值。
绘制了ARD和贝叶斯岭回归的边际对数似然。实际上,两种模型都最小化了对数似然,直到由max_iter参数定义的任意截止值。
import numpy as np
ard_scores = -np.array(ard.scores_)
brr_scores = -np.array(brr.scores_)
# 绘制代码省略
创建了一个目标,它是输入特征的非线性函数。添加了遵循标准均匀分布的噪声。
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import PolynomialFeatures, StandardScaler
rng = np.random.RandomState(0)
n_samples = 110
# 数据生成代码省略
X = X.reshape((-1, 1))
# 外推
X_plot = np.linspace(-10, 10, 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))
# 拟合回归器代码省略
在这里,尝试了一个10度的多项式来可能过拟合,尽管贝叶斯线性模型对多项式系数的大小进行了正则化。由于ARD回归和贝叶斯岭回归默认情况下fit_intercept=True,那么PolynomialFeatures不应该引入一个额外的偏差特征。通过设置return_std=True,贝叶斯回归器返回模型参数的后验分布的标准差。
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)
# 绘制代码省略