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,
)Residuals and fitted values
Source: Residuals/residuals.Rmd
The original examples use fitted values and residuals from stan_glm; here those come from posterior expected values under lapylace.
Simulated data
rng = np.random.default_rng(18701)
fake = pd.DataFrame({"x": rng.normal(size=150), "z": rng.binomial(1, .45, size=150)})
fake["y"] = 1 + 2*fake.x + 1.5*fake.z + rng.normal(0, 1, size=len(fake))
fit = fit_glm("y ~ x + z", fake, seed=18702, prior_scale=5, intercept_scale=5, aux_scale=2)
fake["fitted"] = fit.posterior_epred(fake).mean(axis=0)
fake["resid"] = fake["y"] - fake["fitted"]
fake.head()
| x | z | y | fitted | resid | |
|---|---|---|---|---|---|
| 0 | -2.264170 | 0 | -2.156759 | -3.810696 | 1.653937 |
| 1 | 1.134729 | 0 | 5.796919 | 3.185905 | 2.611014 |
| 2 | 0.183398 | 1 | 2.225688 | 2.826868 | -0.601180 |
| 3 | 0.473300 | 0 | 1.628876 | 1.824360 | -0.195484 |
| 4 | -0.435070 | 0 | -0.243358 | -0.045511 | -0.197846 |
fig, axes = plt.subplots(1, 2, figsize=(8,3))
axes[0].scatter(fake.fitted, fake.y, alpha=.5)
axes[0].set_xlabel("Fitted")
axes[0].set_ylabel("Observed")
axes[1].scatter(fake.fitted, fake.resid, alpha=.5)
axes[1].axhline(0, color="black", lw=1)
axes[1].set_xlabel("Fitted")
axes[1].set_ylabel("Residual")Text(0, 0.5, 'Residual')
