Skip to main content

BayesianRidge

#include <Skigen/LinearModel>

template <typename Scalar = double>
class Skigen::BayesianRidge(max_iter=300, tol=1e-3, alpha_1=1e-6, alpha_2=1e-6, lambda_1=1e-6, lambda_2=1e-6, alpha_init=std::nullopt, lambda_init=std::nullopt, compute_score=false, fit_intercept=true, copy_X=true, verbose=false)

Bayesian ridge regression.

Fit a Bayesian ridge model with Gamma hyper-priors on the noise precision α\alpha and the weight precision λ\lambda. The implementation follows Appendix A of (Tipping, 2001) with MacKay's (1992) update rules for the regularization parameters.

Mirrors sklearn.linear_model.BayesianRidge.

The objective maximised by the iterative procedure is the (log) marginal likelihood

logp(yα,λ)=12[Nlogα+plogλαyXw2λw2+logΣNlog2π]+const.\log p(y \mid \alpha, \lambda) = \tfrac{1}{2}\bigl[ N\log\alpha + p\log\lambda - \alpha \lVert y - Xw \rVert^2 - \lambda \lVert w \rVert^2 + \log |\Sigma| - N \log 2\pi \bigr] + \mathrm{const.}

Attributes:

  • max_iter : int

  • tol : Scalar

  • alpha_1 : Scalar

  • alpha_2 : Scalar

  • lambda_1 : Scalar

  • lambda_2 : Scalar

  • alpha_init : std::optional< Scalar >

  • lambda_init : std::optional< Scalar >

  • compute_score : bool

  • fit_intercept : bool

  • verbose : bool

  • coef : RowVectorType Posterior mean of the weights, shape (1 × n_features).

  • intercept : Scalar Independent term in the decision function.

  • alpha : Scalar Estimated noise precision α\alpha.

  • lambda_ : Scalar Estimated weight precision λ\lambda.

  • sigma : MatrixType Posterior covariance of the weights, shape (n_features × n_features).

  • scores : VectorType Log-marginal-likelihood values recorded during fitting.

  • n_iter : int Number of iterations executed.

  • X_offset : RowVectorType Centering offsets used for X (zeros if fit_intercept=false).

  • X_scale : RowVectorType Per-feature scaling (always ones in this implementation).

  • y_offset : Scalar Centering offset used for y.


Methods

SKIGEN_PARAMS()

Fit the Bayesian Ridge model via SVD-based evidence maximisation.


fit(X, y)

Fit from a sparse design matrix (densifies internally).


predict(X)

Predictive mean y^=Xw+b\hat{y} = X w + b.


score(X, y)

R2R^2 score.


predict(X)

Predictive mean and standard deviation.

Tag-dispatch overload selected by passing Skigen::with_std. Returns {y_mean, y_std}. The standard deviation is the marginal predictive std-dev: σy^2(x)=xΣx+1/α\sigma_{\hat{y}}^2(x_*) = x_*^\top \Sigma\, x_* + 1/\alpha.


predict(X)

Tag overload (with_std) — calls predict(X, std::true_type{}).


Example

Skigen::BayesianRidge<double> model(
/*max_iter=*/300, /*tol=*/1e-3,
/*alpha_1=*/1e-6, /*alpha_2=*/1e-6,
/*lambda_1=*/1e-6, /*lambda_2=*/1e-6,
/*alpha_init=*/std::nullopt, /*lambda_init=*/std::nullopt,
/*compute_score=*/true);
model.fit(X, y);

std::cout << "=== BayesianRidge ===\n";
std::cout << " alpha (noise precision) = " << model.alpha() << "\n";
std::cout << " lambda (weight precision)= " << model.lambda_() << "\n";
std::cout << " n_iter = " << model.n_iter() << "\n";
std::cout << " coef = " << model.coef() << "\n";
std::cout << " intercept = " << model.intercept() << "\n";
std::cout << " R^2 (train) = " << model.score(X, y) << "\n";

// Predict with confidence intervals on the first 5 samples.
Eigen::MatrixXd X_test = X.topRows(5);
auto [y_mean, y_std] = model.predict(X_test, Skigen::with_std);
std::cout << "\nPredictions with 95% CI (first 5 rows):\n";
for (Eigen::Index i = 0; i < y_mean.size(); ++i) {
std::cout << " y_pred = " << std::setw(7) << y_mean(i)
<< " +/- " << std::setw(6) << 1.96 * y_std(i)
<< " (true=" << y(i) << ")\n";
}