from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import lapylace as lp
root = Path("../../ROS-Examples")
def coef_medians(fit):
return pd.Series(
[np.median(fit.alpha_draws()), *np.median(fit.beta_draws(), axis=0)],
index=["Intercept", *fit.columns],
)
def fit_glm(formula, data, family=None, seed=1, prior_scale=2.5, intercept_scale=5, aux_scale=10, **kwargs):
return lp.stan_glm(
formula,
data=data,
family=family or lp.gaussian(),
prior=lp.normal(0, prior_scale),
prior_intercept=lp.normal(0, intercept_scale),
prior_aux=lp.exponential(aux_scale),
chains=2,
parallel_chains=2,
iter_warmup=300,
iter_sampling=500,
seed=seed,
refresh=100,
**kwargs,
)Linear regression across Python tools
Source: DifferentSoftware/linear.Rmd
The comparison page now centers on lapylace for the Bayesian formula interface and NumPy for the closed-form least-squares check.
Simulated data
rng = np.random.default_rng(19001)
dat = pd.DataFrame({"x1": rng.normal(size=80), "x2": rng.normal(size=80)})
dat["y"] = 1 + 2*dat.x1 - dat.x2 + rng.normal(0, .8, size=len(dat))
X = np.column_stack([np.ones(len(dat)), dat[["x1", "x2"]]])
np_coef = np.linalg.lstsq(X, dat.y, rcond=None)[0]
fit = fit_glm("y ~ x1 + x2", dat, seed=19002, prior_scale=5, intercept_scale=5, aux_scale=2)
pd.DataFrame({"numpy_lstsq": np_coef, "lapylace_median": coef_medians(fit).to_numpy()}, index=["Intercept", "x1", "x2"]).round(3)
| numpy_lstsq | lapylace_median | |
|---|---|---|
| Intercept | 0.840 | 0.841 |
| x1 | 1.994 | 1.989 |
| x2 | -0.989 | -0.994 |