Split out of #149. That issue predates the shared-frailty implementation and its wording no longer matches the code — this is the part of it that is genuinely still open.
Status: maybe / not scheduled.
What exists
Shared frailty with a parametric baseline, shipped since #149 was written:
from surpyval import Frailty, Weibull
model = Frailty(Weibull).fit(x, Z=Z, c=c, groups=unit_id)
model.beta, model.theta, model.frailties, model.n_groups
h(x | Z, u) = u · h₀(x) · exp(β'Z), with u drawn once per group from a Gamma with mean 1 and variance theta, and h₀ a fitted distribution. Prebuilt as ExponentialFrailty, WeibullFrailty, LogNormalFrailty, GammaFrailty; FrailtyFitter composes any distribution. It has fit_from_df, serialisation, standard errors and an API reference page. The Gamma frailty's closed-form marginal likelihood is what keeps the fit fast.
What is missing
The same model with h₀ left unspecified — a Cox-style baseline rather than a fitted distribution. This is what #149 originally meant by filing frailty under semi-parametric regression.
Two standard routes:
- Penalised partial likelihood. Treat the log-frailties as random effects penalised toward zero, maximise the penalised partial likelihood, profile out
theta via REML-like criteria. This is what coxph(... + frailty(id)) does in R's survival package.
- EM over the frailties. E-step gives the posterior mean of each
u given current (β, Λ₀) — closed form for the Gamma; M-step is an ordinary Cox fit with those as offsets, plus a Breslow baseline.
The EM route reuses machinery that already exists: CoxPH fits with offsets, and the Breslow baseline is already implemented for it. That likely makes it the cheaper of the two here.
One clarification carried over from #149
#149 described "a subject-level random effect". A frailty shared within a group is what is estimable — with one observation per subject a subject-level frailty is not identified. The implemented model takes groups= for that reason, and any semi-parametric version should do the same.
Why it is not scheduled
The parametric version covers the modelling need; this is about relaxing the baseline assumption, not about capability that is otherwise absent.
Split out of #149. That issue predates the shared-frailty implementation and its wording no longer matches the code — this is the part of it that is genuinely still open.
What exists
Shared frailty with a parametric baseline, shipped since #149 was written:
h(x | Z, u) = u · h₀(x) · exp(β'Z), withudrawn once per group from a Gamma with mean 1 and variancetheta, andh₀a fitted distribution. Prebuilt asExponentialFrailty,WeibullFrailty,LogNormalFrailty,GammaFrailty;FrailtyFittercomposes any distribution. It hasfit_from_df, serialisation, standard errors and an API reference page. The Gamma frailty's closed-form marginal likelihood is what keeps the fit fast.What is missing
The same model with
h₀left unspecified — a Cox-style baseline rather than a fitted distribution. This is what #149 originally meant by filing frailty under semi-parametric regression.Two standard routes:
thetavia REML-like criteria. This is whatcoxph(... + frailty(id))does in R's survival package.ugiven current(β, Λ₀)— closed form for the Gamma; M-step is an ordinary Cox fit with those as offsets, plus a Breslow baseline.The EM route reuses machinery that already exists:
CoxPHfits with offsets, and the Breslow baseline is already implemented for it. That likely makes it the cheaper of the two here.One clarification carried over from #149
#149 described "a subject-level random effect". A frailty shared within a group is what is estimable — with one observation per subject a subject-level frailty is not identified. The implemented model takes
groups=for that reason, and any semi-parametric version should do the same.Why it is not scheduled
The parametric version covers the modelling need; this is about relaxing the baseline assumption, not about capability that is otherwise absent.