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,
)Robit and logit links
Source: Robit/robit.Rmd
lapylace currently supplies the logit GLM path. For comparison with heavier-tailed robit intuition, this page shows the logit fit and a Student-t CDF curve with matched slope.
Simulated data
from scipy.special import expit
from scipy.stats import t
rng = np.random.default_rng(19101)
data = pd.DataFrame({"x": rng.normal(size=180)})
data["p"] = expit(-0.4 + 1.6*data.x)
data["y"] = rng.binomial(1, data.p)
fit = fit_glm("y ~ x", data, family=lp.bernoulli(), seed=19102, prior_scale=2.5, intercept_scale=5)
coef_medians(fit).round(3)
Intercept -0.431
x 1.701
dtype: float64
grid = pd.DataFrame({"x": np.linspace(data.x.min(), data.x.max(), 200)})
eta = fit.linear_predictor(grid).mean(axis=0)
fig, ax = plt.subplots()
ax.scatter(data.x, data.y, alpha=.25)
ax.plot(grid.x, 1/(1+np.exp(-eta)), label="logit")
ax.plot(grid.x, t.cdf(eta, df=4), label="t CDF, df=4")
ax.legend(frameon=False)