Accelerated Failure Time (AFT) Models
A fully parametric family of survival regression models that expresses covariate effects as multiplicative stretching or compression of the event-time axis, producing a "time ratio" — how many times longer or shorter the event takes — rather than a hazard ratio; the preferred choice when the proportional hazards assumption fails and when a direct time-scale interpretation is clinically or economically needed.
In plain language
An accelerated failure time (AFT) model is a statistical method for comparing how long two groups take to reach an outcome — such as disease progression or death — using a single number called the time ratio. If the time ratio is 1.5, the treatment multiplies every patient's expected time to the outcome by 1.5: a patient who would progress at 10 months on the control treatment would instead progress at 15 months on the new treatment, and the same 50% stretch applies whether we look at early progressors or late progressors. Unlike the more common hazard ratio (which measures event rates at each moment of follow-up), the time ratio directly says "how much longer" in calendar time — a framing that clinicians, patients, and health economists often find more intuitive.
The accelerated failure time model
The AFT model specifies that log(T) = Xβ + σε, where T is the time to event, X is the covariate matrix, β are the log-time-scale regression coefficients, σ is a scale parameter, and ε is a standardized error term. Every exp(β_k) is a time ratio (TR): a multiplicative factor that stretches or compresses the entire event-time distribution for covariate k. The choice of distribution for ε defines the model family: an extreme-value ε gives the Weibull AFT (monotone hazards, the only family that is simultaneously a valid PH model), a Gaussian ε gives the log-normal AFT (arc-shaped, non-monotone hazard), a logistic ε gives the log-logistic AFT (arc-shaped hazard, closed-form survivor function), and the generalized gamma (GG) nests all three as special limiting cases via two shape parameters.
The time ratio is the fundamental AFT estimand. If TR = 1.5, every quantile of the treated event-time distribution is 1.5 times the corresponding quantile of the control distribution. A patient who would progress at 10 months under control progresses at 15 months under treatment; one who would progress at 4 months progresses at 6 months; one who would progress at 20 months progresses at 30 months. This invariance — the same multiplicative shift at every quantile — is the core mathematical property of the AFT family and is what makes the time ratio interpretation clean and distribution-agnostic within the chosen family.
Interpreting the output
A Weibull AFT model fit to a comparative cohort study on time to progression returns: treatment log-time coefficient 0.405 (95% CI 0.10 to 0.71); scale parameter σ = 0.78 (Weibull shape k = 1/σ ≈ 1.28).
Formal interpretation. exp(0.405) = 1.50 is the time ratio (also called the acceleration factor). Conditional on the Weibull model and the fitted covariates, every quantile of the treated progression-time distribution is 1.50 times the corresponding control quantile. The 95% CI on the log-time scale (0.10 to 0.71) maps to a time-ratio CI of approximately exp(0.10) to exp(0.71), roughly 1.11 to 2.03 — the data are compatible with treatment stretching time to progression by between 11% and 103%. The Weibull shape k ≈ 1.28 allows a parallel proportional-hazards reading: HR = TR^(−k) = 1.50^(−1.28) ≈ 0.59, meaning the hazard is approximately 41% lower under treatment. For non-Weibull AFT families (log-normal, log-logistic), no simple closed-form HR exists; the time ratio is the native and only well-defined covariate effect estimate.
Practical interpretation. A time ratio of 1.50 means treatment stretches time to progression by about 50%. A patient who would typically progress at 10 months under control typically progresses at 15 months under treatment; one who would progress early at 4 months progresses at 6 months; one who would progress late at 20 months progresses at 30 months. Clinicians often find this more natural than "the hazard is 41% lower at any given instant in follow-up," because time-ratio language maps directly onto how patients and oncologists discuss disease course — months of progression-free life, not instantaneous rates. For payers and HTA analysts, a time ratio also directly quantifies the economic value of delay: multiplying the control arm's expected time-on-therapy cost by the time ratio gives the treated arm's expected cost under the AFT assumption.
AFT versus proportional hazards
The Cox PH model estimates a hazard ratio assumed constant across follow-up. When hazards converge, cross, or show a delayed treatment effect — the canonical pattern in immuno-oncology, where treated patients may initially show similar or slightly higher hazard before the immune response matures into durable benefit — PH fails and a single averaged HR is a misleading summary that obscures both the early and late treatment profile. AFT models make no PH assumption. The time ratio is identified through the distributional parameters and remains well-defined even under non-PH data, provided the chosen distributional family fits adequately.
The Weibull distribution is the sole family that admits both a PH and an AFT reparameterization. All other AFT families (log-normal, log-logistic, generalized gamma) can only be expressed in AFT form. This makes the Weibull the natural starting point for AFT analysis: if Weibull fits adequately, results can be stated in either HR or TR language to satisfy different reviewer expectations across regulatory and HTA contexts.
The generalized gamma (GG) acts as a diagnostic umbrella: it nests Weibull (shape q = 1), log-normal (q → 0), and gamma as sub-models. Fitting GG first and using likelihood-ratio tests to select the most parsimonious sub-family is the principled approach for HTA extrapolation. When GG AIC is only marginally better than a sub-family's AIC, prefer the sub-family for interpretability and probabilistic sensitivity analysis stability.
RWE and HTA context
In claims data, heavy administrative censoring from disenrollment or Medicare Advantage enrollment without continuous fee-for-service coverage means fitted AFT distribution parameters depend heavily on what the model assumes about the hazard in the unobserved tail — the same fundamental tension that makes HTA extrapolation challenging. AFT distributions with a declining late hazard (log-normal, log-logistic) extrapolate more optimistically than Weibull or Gompertz given identical in-sample data. NICE DSU TSD 14 (Latimer 2013) mandates evaluating the full six-distribution candidate set, overlaying on the Kaplan-Meier, inspecting projected hazards beyond the data, and flooring all-cause hazard against the general-population mortality envelope. The four standard AFT families (Weibull, log-normal, log-logistic, generalized gamma) are four of those six TSD-14 candidates; AFT parameterization adds interpretable time ratios to the distributional selection exercise.
For real-world progression-free survival (rwPFS) and time-to-discontinuation endpoints, time ratios are increasingly reported alongside hazard ratios in HTA dossiers, especially in immuno-oncology where PH is often violated. A rank-based estimation approach (Prentice-Storer), which is consistent without a distributional assumption, exists for robustness checks, though regulatory submissions typically require maximum-likelihood parametric AFT fits from the TSD-14 candidate set.
Diagnostics
(1) Log(−log(KM)) vs log(t) plot: a straight line supports Weibull; a non-linear but single-humped trajectory supports log-normal or log-logistic. (2) Fitted survivor curve vs KM overlay: the parametric S(t) should track the KM closely in the observable window; systematic deviation indicates inadequate distributional fit. (3) AIC/BIC comparison across all candidate families: select the most parsimonious model with competitive AIC and a plausible projected hazard; AIC alone does not determine extrapolation quality because in-sample fit and tail behavior can diverge sharply. (4) Standardized residual Q-Q plot: residuals r_i = (log(t_i) − X_i β-hat) / σ-hat should follow the assumed error distribution — normal for log-normal AFT, extreme-value for Weibull AFT; heavy-tailed residuals or systematic curvature indicate a more flexible model is needed.
Pros, cons, and trade-offs
Pros of AFT over Cox PH: time ratios are interpretable when PH is violated and when clinicians think in terms of time rather than instantaneous rates; the time ratio is invariant to the choice of error distribution within the AFT class; fully parametric maximum-likelihood estimation is efficient when the distributional form is correct; direct quantile prediction is available without a Breslow baseline estimator; natural for HTA extrapolation where a distributional assumption is unavoidable and where the time ratio directly quantifies the economic value of delay.
Cons: commits to a distributional family — misspecification biases all estimates; when the hazard ratio is the pre-specified regulatory primary endpoint (FDA oncology registration trial) and PH holds well, Cox is preferred and more efficient; cure fractions and time-varying covariates require extensions that are less mature than standard Cox in regulatory software.
When to use
Use AFT models when: (a) PH is violated (Schoenfeld test significant, visual crossing or convergence of hazards) and a single averaged HR would be misleading; (b) a direct time-scale effect — "treatment stretches event time by X%" — is the preferred clinical or HTA communication; (c) the endpoint is rwPFS or time-to-discontinuation in an HTA extrapolation and the TSD-14 candidate set is being evaluated; (d) a Weibull, log-normal, or log-logistic distributional form is biologically motivated by prior literature on the endpoint; or (e) the research context is aging or chronic disease where the acceleration-factor framing — does the exposure age subjects faster or slower? — is conceptually natural and supported by domain literature.
When NOT to use
Do not use AFT models when: (a) the hazard ratio is the pre-specified primary estimand and PH holds well — Cox PH is more efficient and imposes no distributional commitment; (b) a genuine cure fraction or long-term survivor plateau is clinically supported — mixture or non-mixture cure models are the appropriate tool; (c) time-varying covariates are central to the causal question — Cox PH with a counting-process layout handles them more naturally and with more mature regulatory software support; (d) competing risks dominate the analysis — cause-specific or Fine-Gray models are preferred and do not naturally map to the AFT framework; or (e) the entire analysis is on the hazard scale for regulatory or communication reasons and the audience is not positioned to interpret time ratios alongside or in place of hazard ratios.
Worked example
Scenario
A pharmacoepidemiology team is comparing time to cancer progression between 6 patients who received a new therapy (treated arm) and 6 patients who received standard care (control arm) in a small registry cohort. All 12 patients experienced the event (no censoring in this illustration). The team fits a Weibull AFT model to estimate the time ratio for treatment. The model returns a log-time coefficient for treatment of 0.405, which the team uses to predict how the full distribution of progression times — not just the median — is shifted by treatment.
Dataset
One row per patient. time_months is months from study entry to cancer progression. event = 1 for all rows (complete data, no censoring in this example). The treated-arm times are approximately 1.5 times the control-arm times, consistent with a time ratio of 1.5 produced by the fitted Weibull AFT model.
| person_id | arm | time_months | event |
|---|---|---|---|
| C1 | control | 3 | 1 |
| C2 | control | 4 | 1 |
| C3 | control | 8 | 1 |
| C4 | control | 12 | 1 |
| C5 | control | 20 | 1 |
| C6 | control | 25 | 1 |
| T1 | treated | 4.5 | 1 |
| T2 | treated | 6 | 1 |
| T3 | treated | 12 | 1 |
| T4 | treated | 18 | 1 |
| T5 | treated | 30 | 1 |
| T6 | treated | 37.5 | 1 |
Steps
Sort the 6 control-arm times: 3, 4, 8, 12, 20, 25 months. The sample median is the average of the 3rd and 4th sorted values: (8 + 12) / 2 = 10 months. The first quartile (25th percentile, 2nd sorted value) is 4 months; the third quartile (75th percentile, 5th sorted value) is 20 months.
The Weibull AFT model is fit to all 12 patients. The model returns a log-time coefficient for treatment of 0.405 (95% CI approximately 0.10 to 0.71). Taking the exponential gives the time ratio: TR = exp(0.405) ≈ 1.50.
The time ratio means every quantile of the treated progression-time distribution is 1.50 times the corresponding control quantile. Apply this to the control median: treated median = 10 × 1.5 = 15 months.
Verify with the treated-arm data: sorted treated times are 4.5, 6, 12, 18, 30, 37.5. Treated median = (12 + 18) / 2 = 15 months. This matches the AFT prediction exactly.
First quartile scaling: control Q1 = 4 months; treated Q1 = 4 × 1.5 = 6 months. Check: 2nd treated value = 6 months. Third quartile scaling: control Q3 = 20 months; treated Q3 = 20 × 1.5 = 30 months. Check: 5th treated value = 30 months.
Result
Weibull AFT model fit to 12 patients (6 per arm). Control median = (8 + 12) / 2 = 10 months. Time ratio TR = exp(0.405) ≈ 1.50. Treated median = 10 × 1.5 = 15 months; verified by data: (12 + 18) / 2 = 15 months. Q1 scaling: 4 × 1.5 = 6 months (data: 6 months). Q3 scaling: 20 × 1.5 = 30 months (data: 30 months). Every quantile is multiplied by the same factor of 1.5, demonstrating the AFT property that the time ratio is invariant across the entire progression-time distribution.
Runnable example
python implementation
Fit Weibull and log-normal AFT models using lifelines and extract time ratios directly from the model summary. Required input DataFrame `cohort` with columns: time : float, time to event or censoring (> 0) event : int, 1 = event occurred, 0 = censored arm :...
import pandas as pd
from lifelines import WeibullAFTFitter, LogNormalAFTFitter
# cohort: analysis-ready DataFrame described in the header above.
cohort = pd.read_parquet("cohort.parquet")
# ── 1. Weibull AFT ──────────────────────────────────────────────────────────
waf = WeibullAFTFitter()
waf.fit(cohort, duration_col="time", event_col="event")
print("=== Weibull AFT: time ratios ===")
print(waf.summary[["coef", "exp(coef)", "exp(coef) lower 95%",
"exp(coef) upper 95%", "p"]])
# exp(coef) for 'arm' is the time ratio TR:
# TR > 1 → treatment stretches time to event (beneficial if the event is harmful)
# TR < 1 → treatment compresses time to event
# ── 2. Predict median event time by arm ─────────────────────────────────────
newdata = pd.DataFrame({"arm": [0, 1]})
medians = waf.predict_median(newdata)
print(f"\nControl median: {medians.iloc[0]:.1f} Treated median: {medians.iloc[1]:.1f}")
print(f"Empirical time ratio from medians: {medians.iloc[1] / medians.iloc[0]:.3f}")
# ── 3. Log-normal AFT for comparison ────────────────────────────────────────
lnaf = LogNormalAFTFitter()
lnaf.fit(cohort, duration_col="time", event_col="event")
print("\n=== Log-normal AFT: time ratios ===")
print(lnaf.summary[["coef", "exp(coef)", "exp(coef) lower 95%",
"exp(coef) upper 95%", "p"]])
# ── 4. Compare AIC (lower is better; inspect tail before selecting) ──────────
print(f"\nWeibull AIC : {waf.AIC_:.2f}")
print(f"Log-normal AIC: {lnaf.AIC_:.2f}")
# AIC alone does not determine extrapolation quality. Overlay fitted curves on the
# KM and inspect projected hazard beyond the data before selecting a distribution.r implementation
Fit Weibull and log-normal AFT models with survreg() from the survival package and the generalized gamma with flexsurvreg() from flexsurv. Compute time ratios by exponentiating the treatment coefficient and predict quantiles at each covariate profile....
library(survival)
library(flexsurv)
# cohort: analysis-ready data.frame (described in the header above).
cohort <- readRDS("cohort.rds")
cohort$arm <- relevel(factor(cohort$arm), ref = "control")
# ── 1. Weibull AFT via survreg() ─────────────────────────────────────────────
fit_wb <- survreg(Surv(time, event) ~ arm,
data = cohort, dist = "weibull")
print(summary(fit_wb))
# exp(coef) is the time ratio; survreg 'scale' = sigma = 1 / Weibull_shape_k
TR_wb <- exp(coef(fit_wb)["armtreated"])
k <- 1 / fit_wb$scale # Weibull shape parameter
cat(sprintf("Weibull TR: %.3f shape k: %.3f equivalent HR: %.3f\n",
TR_wb, k, TR_wb^(-k)))
# Predict median (p = 0.50 quantile) and quartiles by arm
q_vals <- c(0.25, 0.50, 0.75)
for (p in q_vals) {
q_preds <- predict(fit_wb,
newdata = data.frame(arm = c("control", "treated")),
type = "quantile", p = p)
cat(sprintf("Q%.0f: control %.1f treated %.1f ratio %.3f\n",
p * 100, q_preds[1], q_preds[2], q_preds[2] / q_preds[1]))
}
# ── 2. Log-normal AFT via survreg() ──────────────────────────────────────────
fit_ln <- survreg(Surv(time, event) ~ arm,
data = cohort, dist = "lognormal")
TR_ln <- exp(coef(fit_ln)["armtreated"])
cat(sprintf("\nLog-normal TR: %.3f\n", TR_ln))
# ── 3. Generalized gamma via flexsurvreg() (diagnostic umbrella) ────────────
fit_gg <- flexsurvreg(Surv(time, event) ~ arm,
data = cohort, dist = "gengamma")
print(fit_gg)
# AIC comparison: lower is better; inspect tail plausibility before selecting.
aic_compare <- data.frame(
model = c("weibull", "lognormal", "gengamma"),
AIC = c(AIC(flexsurvreg(Surv(time, event) ~ arm, data = cohort, dist = "weibull")),
AIC(flexsurvreg(Surv(time, event) ~ arm, data = cohort, dist = "lnorm")),
AIC(fit_gg))
)
print(aic_compare[order(aic_compare$AIC), ])