Accelerated Failure-Time Models

Michael BrenndoerferOctober 26, 202644 min read

Learn how AFT models fit censored event-time data, interpret coefficients as time ratios, and compare Weibull and log-normal survival curves.

Machine Learning from ScratchAll chapters
Part 6 of 15Survival Analysis
Chapter 51Accelerated Failure-Time Models
Reading the full chapter · 10 sections · 44 min10 sections · 44 min

All 10 sections · 44 min read

Accelerated Failure-Time ModelsFull chapter · Sections in this chapter1 / 10 ↓
Reading tools Definitions, links & notes

Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.

Article links

Make inline references clickable

Notes & comments

Accelerated Failure-Time Models

An AFT coefficient of 0.20.2 corresponds to a time ratio of exp⁡(0.2)≈1.22\exp(0.2)\approx1.22: a one-unit covariate change multiplies each conditional event-time quantile by that factor, with other covariates fixed. This makes the interpretation concrete, but it also states a restriction. The same factor must stretch the entire conditional distribution, rather than changing only one part of it.

Accelerated failure-time models express the logarithm of event time as a linear function of covariates plus an error term with a common scale. A positive coefficient stretches event-time quantiles to the right, while a negative coefficient compresses them. We develop parametric versions that specify the error distribution, handle censoring through a full likelihood, and compare the resulting survival curves. Cox regression instead leaves its baseline hazard unspecified; estimating that baseline still permits survival predictions without choosing a parametric lifetime family.

This chapter develops the log-time regression model, derives the censored likelihood, and explains the two choices developed here, Weibull and log-normal event times. We will see why the Weibull AFT model has a special proportional hazards representation, why that representation does not extend automatically to every AFT distribution, and how to compare fitted survival curves under competing distributional assumptions.

Advantages

The main advantage of an AFT model is interpretability on the time scale. Exponentiating a coefficient gives a time ratio: the factor by which the event time is multiplied when a covariate increases by one unit, holding the other covariates and the individual error term fixed. A time ratio of 1.25 means that the model predicts events about 25 percent later. For a question phrased in time units, this factor describes changes in event-time quantiles directly; a hazard ratio instead describes an instantaneous-rate contrast.

The parametric AFT models studied here provide a full event-time likelihood. That means we can estimate survival curves, event-time quantiles, means when they exist, and prediction intervals directly from the fitted model. We can also compare non-nested distributions with information criteria such as AIC or BIC, provided the models are fitted to the same observations and use the same censoring convention.

The censored likelihood is another practical strength. An observed event contributes its density, while a censored observation contributes its survival probability. This is the same likelihood principle we used in Maximum Likelihood Estimation, now adapted to incomplete event times. AFT models can therefore be fitted to right-censored data without discarding censored subjects or imputing their event times.

Finally, AFT models are useful when the proportional hazards assumption is questionable. A log-normal or log-logistic AFT model can represent non-monotone hazards, where risk rises and later falls. The Weibull AFT model is more restrictive, but it has a direct connection to Cox regression, which helps us translate between time ratios and hazard ratios when that connection is justified.

Disadvantages

The main disadvantage is the distributional assumption. The parametric AFT models studied here require us to choose the distribution of the error term WW in the log-time equation. If that distribution is wrong, coefficient estimates can be biased, standard errors can be misleading, and predicted survival curves can be systematically off. Cox regression avoids this specific assumption, although it imposes proportional hazards. In practice, the choice between Cox and AFT is a choice about which assumption is more defensible for the problem at hand.

AFT models also impose a strong structural assumption: covariates multiply the event time by a constant factor. Equivalently, the effect of a covariate is the same at every quantile of the event-time distribution. If a treatment changes conditional time ratios only for the highest-risk subjects, or if those ratios differ across event-time quantiles, a single time ratio may be too simple. AFT models can include interactions, and generalized formulations can handle time-varying covariates with an explicit event-time model. The static model below does not acquire that ability by inserting measurements obtained after baseline. A single time ratio is not a universal description of heterogeneous treatment effects.

Parametric extrapolation is both an advantage and a risk. Once we fit a distribution, we can predict survival beyond the largest observed time. That extrapolation is only as credible as the distributional assumption. A log-normal model and a Weibull model can agree near the middle of the observed data and diverge sharply in the tail. If the scientific decision depends on long-term survival, we should check whether the data inform that region.

There are also practical identifiability and numerical issues. The scale parameter σ\sigma must be positive, so the implementation below optimizes over log⁡σ\log \sigma. With heavy censoring, small samples, or extreme covariate values, the likelihood can be flat or poorly behaved. The likelihood also assumes independent censoring: if censoring is related to unobserved prognosis after conditioning on covariates, these reduced contributions are not generally justified without addressing the observation mechanism. We should also avoid comparing AIC values from a Cox partial likelihood directly with AIC values from a full AFT likelihood, because the two likelihoods are not on the same footing.

Formula

Positive event times allow us to model log⁡T\log T. The basic AFT model then assumes a linear location on this log scale and a common error distribution and scale across covariate profiles. The log transformation does not guarantee symmetry: normal errors are symmetric, while the minimum Gumbel errors used for Weibull lifetimes are not. A one-unit increase in a linearly entered covariate changes log time by its coefficient, giving a multiplicative factor on the time scale. Doubling a raw covariate is not generally a fixed one-unit change.

We begin with notation. For subject ii, let Ti>0T_i>0 be the true event time, let CiC_i be the censoring time, and let

Yi=min⁡(Ti,Ci)Y_i = \min(T_i, C_i)

be the observed time. Define the event indicator

δi={1,if Ti≤Ci,0,if Ti>Ci.\delta_i = \begin{cases} 1, & \text{if } T_i \leq C_i, \\ 0, & \text{if } T_i > C_i. \end{cases}

Thus δi=1\delta_i=1 means we observed the event, and δi=0\delta_i=0 means the observation was right-censored. Let xi=(1,xi1,…,xip)⊤\mathbf{x}_i=(1,x_{i1},\ldots,x_{ip})^\top include an intercept and pp covariates, and let β=(β0,β1,…,βp)⊤\boldsymbol{\beta}=(\beta_0,\beta_1,\ldots,\beta_p)^\top be the corresponding coefficient vector.

What we ultimately want is the conditional distribution of TiT_i given xi\mathbf{x}_i, but the observed data give only partial information: for events we see TiT_i, for censored subjects we only know that Ti>yiT_i > y_i. The rest of this section does three things in order. We express the covariate effect as a location shift on the log scale and quantify it as a time ratio. We assemble a likelihood that handles events and censored observations in the same expression. We examine the two distributional choices that determine the shape of the resulting survival curves.

Log-time regression and acceleration factors

The AFT model writes the log event time as

log⁡Ti=β0+β1xi1+⋯+βpxip+σWi,\log T_i = \beta_0 + \beta_1 x_{i1} + \cdots + \beta_p x_{ip} + \sigma W_i,

where WiW_i is a standardized error term with a chosen distribution, and σ>0\sigma>0 is a scale parameter. In matrix notation,

log⁡Ti=xi⊤β+σWi.\log T_i = \mathbf{x}_i^\top \boldsymbol{\beta} + \sigma W_i.

Equivalently,

Ti=exp⁡(xi⊤β)exp⁡(σWi).T_i = \exp(\mathbf{x}_i^\top \boldsymbol{\beta}) \exp(\sigma W_i).

The two factors on the right have clearly separated roles. The first, exp⁡(xi⊤β)\exp(\mathbf{x}_i^\top \boldsymbol{\beta}), depends only on covariates and shifts the entire distribution of event times. The second, exp⁡(σWi)\exp(\sigma W_i), is subject-level noise that has the same distribution for every subject. This separation is why AFT coefficients are interpretable: all of the covariate effect is carried by a single location shift on the log scale, and everything else is the shape of the error distribution.

To see what the shift means on the time scale, compare two subjects with covariate vectors that differ only in the jj-th component by one unit, and imagine that the individual noise WiW_i is identical for both. Then

Ti(xj+1)Ti(xj)=exp⁡(xi⊤β+βj)exp⁡(σWi)exp⁡(xi⊤β)exp⁡(σWi)=exp⁡(βj).\frac{T_i(x_j+1)}{T_i(x_j)} = \frac{\exp(\mathbf{x}_i^\top \boldsymbol{\beta}+\beta_j)\exp(\sigma W_i)} {\exp(\mathbf{x}_i^\top \boldsymbol{\beta})\exp(\sigma W_i)} = \exp(\beta_j).

This ratio is the time ratio, also called the acceleration factor. If βj=0.2\beta_j=0.2, then exp⁡(0.2)=1.2214\exp(0.2)=1.2214, so the event time is multiplied by about 1.22, or prolonged by 22.1 percent. If βj=−0.2\beta_j=-0.2, then exp⁡(−0.2)=0.8187\exp(-0.2)=0.8187, so the event time is multiplied by about 0.82, or shortened by 18.1 percent. The same factor applies to every quantile of the event-time distribution, because the pp-th quantile of TiT_i depends on covariates only through the common factor exp⁡(xi⊤β)\exp(\mathbf{x}_i^\top \boldsymbol{\beta}). That is the precise sense in which a covariate "stretches the clock."

For likelihood work it is more convenient to translate the model into a survival function. If SW(w)=P(W>w)S_W(w)=P(W>w) is the survival function of the standardized error, then

ST(t∣x)=P(T>t∣x)=P(W>log⁡t−x⊤βσ)=SW(log⁡t−x⊤βσ).S_T(t\mid \mathbf{x}) = P(T>t\mid \mathbf{x}) = P\left(W>\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right) = S_W\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right).

Once SWS_W, β\boldsymbol{\beta}, and σ\sigma are fixed, the survival curve can be evaluated from the assumed error survival function. Cox regression can also produce survival curves after baseline estimation; the difference here is the explicit parametric event-time distribution. Different choices of SWS_W give different tail shapes and different hazard patterns, which is the source of the modeling decision discussed later.

Censored likelihood contributions

For a censored subject, the observed record does not reveal TiT_i; it gives a lower bound on that time. Evaluating the event density at the censoring time would invent an observed event. The right-censoring decomposition resolves this by assigning the two kinds of observation two structurally different likelihood pieces:

  • If subject ii has an observed event at yiy_i, we have observed the value of TiT_i, so its contribution is the density fT(yi∣xi)f_T(y_i\mid \mathbf{x}_i).
  • If subject ii is censored at yiy_i, the only information available is that Ti>yiT_i>y_i, so its contribution is the probability of that event, the survival function ST(yi∣xi)S_T(y_i\mid \mathbf{x}_i).

Assume independent subjects, conditionally independent censoring, and censoring-law parameters distinct from the event-time parameters. After removing factors that do not depend on the fitted parameters, the likelihood is the product:

L(β,σ)=∏i=1nfT(yi∣xi)δiST(yi∣xi)1−δi.L(\boldsymbol{\beta},\sigma) = \prod_{i=1}^{n} f_T(y_i\mid \mathbf{x}_i)^{\delta_i} S_T(y_i\mid \mathbf{x}_i)^{1-\delta_i}.

Taking logarithms turns the product into a sum:

ℓ(β,σ)=∑i=1n[δilog⁡fT(yi∣xi)+(1−δi)log⁡ST(yi∣xi)].\ell(\boldsymbol{\beta},\sigma) = \sum_{i=1}^{n} \left[ \delta_i \log f_T(y_i\mid \mathbf{x}_i) + (1-\delta_i)\log S_T(y_i\mid \mathbf{x}_i) \right].

To express each piece in terms of the standardized error, standardize each observation:

wi=log⁡yi−xi⊤βσ.w_i = \frac{\log y_i-\mathbf{x}_i^\top \boldsymbol{\beta}}{\sigma}.

Because T=exp⁡(x⊤β+σW)T=\exp(\mathbf{x}^\top \boldsymbol{\beta}+\sigma W), the transformation from WW to TT has Jacobian

dtdw=σexp⁡(x⊤β+σw)=σt.\frac{dt}{dw} = \sigma \exp(\mathbf{x}^\top \boldsymbol{\beta}+\sigma w) = \sigma t.

Therefore the density of TT is

fT(t∣x)=fW(w)σt,f_T(t\mid \mathbf{x}) = \frac{f_W(w)}{\sigma t},

where fWf_W is the density of the standardized error. Taking logs gives

log⁡fT(t∣x)=−log⁡t−log⁡σ+log⁡fW(w).\log f_T(t\mid \mathbf{x}) = -\log t-\log \sigma+\log f_W(w).

The Jacobian contributes −log⁡t−log⁡σ-\log t-\log\sigma to an event log density. For fixed observed times, the −log⁡t-\log t term does not depend on the fitted parameters: omitting that term alone changes absolute time-scale likelihood values, but not the maximizer. It also cancels from AIC differences when both models omit the same term on the same event records. The −log⁡σ-\log\sigma term does depend on a fitted parameter and must remain in the objective. Retaining the complete density avoids mismatched scoring conventions. The survival function transforms without a Jacobian, because it is a probability:

ST(t∣x)=SW(w).S_T(t\mid \mathbf{x})=S_W(w).

Substituting these expressions into the log-likelihood, we obtain the general AFT censored log-likelihood:

ℓ(β,σ)=∑i=1n[δi(−log⁡yi−log⁡σ+log⁡fW(wi))+(1−δi)log⁡SW(wi)].\ell(\boldsymbol{\beta},\sigma) = \sum_{i=1}^{n} \left[ \delta_i\left(-\log y_i-\log \sigma+\log f_W(w_i)\right) + (1-\delta_i)\log S_W(w_i) \right].

Two features of this expression deserve emphasis. First, the two halves of the summand are structurally different: an event contributes a density with its Jacobian, while a censored observation contributes a survival probability. Each subject activates exactly one of the two. Second, if no observation is censored, the second term vanishes. The remaining likelihood gives the same parameter estimates as ordinary log-location-scale regression on log⁡Ti\log T_i, differing from its log-time likelihood by the parameter-free sum −∑ilog⁡yi-\sum_i\log y_i. Every parametric AFT model, including Weibull, log-normal, and log-logistic, is expressed simply by plugging in the corresponding fWf_W and SWS_W in this formula.

Weibull and log-normal event-time models

The general likelihood is now in hand; the remaining decision is what to plug in for fWf_W and SWS_W. We compare two error distributions:

  • The standard normal error is symmetric and produces a log-normal distribution for TT. Its hazard can rise and then fall, which allows a non-monotone risk pattern.
  • The minimum Gumbel error is less familiar but produces the Weibull distribution for TT, which has a special algebraic connection to proportional hazards. That connection is what allows Weibull AFT coefficients to be translated into hazard ratios.

The distributions can give similar fits in part of the observed range while implying different tails. Their agreement in the middle is not guaranteed.

The survival curve comparison can be read alongside the corresponding hazard functions. Holding log-time location and scale fixed, the log-normal hazard is not forced to be monotone, while the Weibull hazard is monotone in this parameterization. The following curves use the same location and scale for both families, so the difference in shape comes from the error distribution rather than from a changed regression coefficient.

PythonIn [3]
CollapseExpand
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

# Fixed illustrative values, not estimates. No random sampling or fitting is used.
t_hazard = np.linspace(0.25, 8.0, 400)
eta_hazard = 1.0
sigma_hazard = 0.6

z_hazard = (np.log(t_hazard) - eta_hazard) / sigma_hazard
hazard_lognormal = stats.norm.pdf(z_hazard) / (
    sigma_hazard * t_hazard * stats.norm.sf(z_hazard)
)
hazard_weibull = (1.0 / (sigma_hazard * t_hazard)) * np.exp(z_hazard)
hazard_ylim = (0.0, 1.15 * max(hazard_lognormal.max(), hazard_weibull.max()))
VisualizationOut [4]
CollapseExpand
Log-normal hazard rises then falls while Weibull hazard increases monotonically.
Log-normal and Weibull hazard functions at log-time location 1 and scale 0.6. The Weibull hazard increases monotonically because its shape parameter is 1/0.6, while the log-normal hazard rises and then falls. Equal location and scale therefore do not imply equal risk patterns.

For the log-normal AFT model, W∼N(0,1)W\sim N(0,1). Then

ST(t∣x)=1−Φ(log⁡t−x⊤βσ)=Φ(x⊤β−log⁡tσ),S_T(t\mid \mathbf{x}) = 1-\Phi\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right) = \Phi\left(\frac{\mathbf{x}^\top \boldsymbol{\beta}-\log t}{\sigma}\right),

where:

  • Φ\Phi: the standard normal cumulative distribution function
  • tt: the event time
  • x⊤β\mathbf{x}^\top \boldsymbol{\beta}: the log-time location for the covariate profile
  • σ\sigma: the log-time scale parameter

The density is

fT(t∣x)=1tσϕ(log⁡t−x⊤βσ),f_T(t\mid \mathbf{x}) = \frac{1}{t\sigma}\phi\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right),

where ϕ\phi is the standard normal density. The hazard is the ratio

hT(t∣x)=fT(t∣x)ST(t∣x)=ϕ(w)σt Φ(−w).h_T(t\mid \mathbf{x}) = \frac{f_T(t\mid \mathbf{x})}{S_T(t\mid \mathbf{x})} = \frac{\phi(w)}{\sigma t\,\Phi(-w)}.

Here w=(log⁡t−x⊤β)/σw=(\log t-\mathbf{x}^\top\boldsymbol{\beta})/\sigma. The log-normal hazard can rise and later fall; it tends to zero both as t↓0t\downarrow0 and as t→∞t\to\infty. This is different from a Weibull hazard, whose direction is controlled by one shape parameter.

For the Weibull AFT model, WW follows the standard minimum Gumbel distribution, whose survival function is

SW(w)=exp⁡(−ew),S_W(w)=\exp(-e^w),

where:

  • ww: the standardized log-time value (log⁡t−x⊤β)/σ(\log t-\mathbf{x}^\top \boldsymbol{\beta})/\sigma
  • ewe^w: the exponential of ww, which is always positive
  • exp⁡(−ew)\exp(-e^w): the Gumbel survival probability, decreasing from 1 toward 0 as ww increases

Substituting w=(log⁡t−x⊤β)/σw=(\log t-\mathbf{x}^\top \boldsymbol{\beta})/\sigma gives

ST(t∣x)=exp⁡[−exp⁡(log⁡t−x⊤βσ)].S_T(t\mid \mathbf{x}) = \exp\left[-\exp\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right)\right].

If we set the shape parameter k=1/σk=1/\sigma and the scale parameter λ(x)=exp⁡(x⊤β)\lambda(\mathbf{x})=\exp(\mathbf{x}^\top \boldsymbol{\beta}), this becomes the usual Weibull survival function

ST(t∣x)=exp⁡[−(tλ(x))k].S_T(t\mid \mathbf{x}) = \exp\left[-\left(\frac{t}{\lambda(\mathbf{x})}\right)^k\right].

The density is

fT(t∣x)=kλ(x)(tλ(x))k−1exp⁡[−(tλ(x))k].f_T(t\mid \mathbf{x}) = \frac{k}{\lambda(\mathbf{x})} \left(\frac{t}{\lambda(\mathbf{x})}\right)^{k-1} \exp\left[-\left(\frac{t}{\lambda(\mathbf{x})}\right)^k\right].

To derive the hazard, we use the definition hT(t)=fT(t)/ST(t)h_T(t)=f_T(t)/S_T(t). Differentiating the survival function with the chain rule,

ddtST(t∣x)=−ST(t∣x)exp⁡(log⁡t−x⊤βσ)1σt.\frac{d}{dt}S_T(t\mid \mathbf{x}) = -S_T(t\mid \mathbf{x}) \exp\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right) \frac{1}{\sigma t}.

Since fT(t)=−dST(t)/dtf_T(t)=-dS_T(t)/dt, dividing by ST(t)S_T(t) gives

hT(t∣x)=1σtexp⁡(log⁡t−x⊤βσ).h_T(t\mid \mathbf{x}) = \frac{1}{\sigma t} \exp\left(\frac{\log t-\mathbf{x}^\top \boldsymbol{\beta}}{\sigma}\right).

This factorization is why the Gumbel error is useful here. Write the hazard as

hT(t∣x)=[1σtexp⁡(log⁡t−β0σ)]exp⁡(−∑j=1pxjβjσ).h_T(t\mid \mathbf{x}) = \left[ \frac{1}{\sigma t} \exp\left(\frac{\log t-\beta_0}{\sigma}\right) \right] \exp\left(-\frac{\sum_{j=1}^{p}x_j\beta_j}{\sigma}\right).

The sum in the second factor uses only the pp slope terms, excluding the intercept. The term in brackets depends only on time and the baseline parameters, and the remaining factor is constant over time. That is the proportional hazards structure, with hazard ratio

HRj=exp⁡(−βjσ)\text{HR}_j=\exp\left(-\frac{\beta_j}{\sigma}\right)

for a one-unit increase in covariate jj. The sign flips relative to the AFT coefficient because a positive βj\beta_j lengthens event times and therefore lowers the hazard. Among the two families studied here, the Weibull model has this proportional-hazards conversion; a log-normal AFT model does not generally have proportional hazards, because its hazard ratio changes with time. That distinction is the practical meaning of choosing one error distribution over the other.

Mathematical Properties

The acceleration interpretation can be made exact through the quantile function. If qpq_p is the pp-th quantile of WW, then the pp-th quantile of TT given covariates is

tp(x)=exp⁡(x⊤β+σqp).t_p(\mathbf{x}) = \exp\left(\mathbf{x}^\top \boldsymbol{\beta}+\sigma q_p\right).

For a one-unit change in xjx_j, the ratio of quantiles is exp⁡(βj)\exp(\beta_j), independent of pp. This is the constant time-ratio property, and it is what justifies calling exp⁡(βj)\exp(\beta_j) an acceleration factor rather than just a coefficient on the log scale.

The median depends on which WW we choose. For the log-normal model, the median is exp⁡(x⊤β)\exp(\mathbf{x}^\top \boldsymbol{\beta}) because the median of a standard normal is zero. For the Weibull model, the median is

exp⁡(x⊤β+σlog⁡(log⁡2)),\exp\left(\mathbf{x}^\top \boldsymbol{\beta}+\sigma \log(\log 2)\right),

because the minimum Gumbel median is log⁡(log⁡2)≈−0.3665\log(\log2)\approx-0.3665. Solving exp⁡(−ew)=1/2\exp(-e^w)=1/2 gives ew=log⁡2e^w=\log2, so the median shift is negative when multiplied by positive σ\sigma. The two models can therefore share the same x⊤β\mathbf{x}^\top \boldsymbol{\beta} and σ\sigma while having different medians and different tails.

Finally, fitting requires numerical care. The log-likelihood is not guaranteed to be globally concave in all parameters. For example, joint concavity can fail in the log-normal location and log-scale parameterization even without censoring. In practice we optimize numerically, parameterize σ\sigma as exp⁡(γ)\exp(\gamma) so that it stays positive, and use good starting values or multiple starts. Each parameterization needs its own existence and convergence checks; multiple starts do not establish a global optimum.

Visualizing Accelerated Failure-Time Models

The first figure shows how a positive covariate coefficient stretches log-normal survival to the right. At any fixed survival probability, the event-time quantile is multiplied by the same factor. The second figure holds log-time location and scale fixed and changes the error distribution from normal to minimum Gumbel. Equal location and scale do not imply equal medians across these families.

PythonIn [5]
CollapseExpand
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

beta0_vis = 1.00
beta1_vis = 0.45
sigma_vis = 0.60
t_grid_vis = np.linspace(0.15, 8.0, 400)


def lognormal_survival(t, eta, sigma):
    t = np.asarray(t, dtype=float)
    if sigma <= 0 or np.any(t < 0):
        raise ValueError("Use nonnegative times and a positive log-time scale.")
    with np.errstate(divide="ignore"):
        z = (np.log(t) - eta) / sigma
    return stats.norm.sf(z)


def weibull_survival(t, eta, sigma):
    t = np.asarray(t, dtype=float)
    if sigma <= 0 or np.any(t < 0):
        raise ValueError("Use nonnegative times and a positive log-time scale.")
    with np.errstate(divide="ignore", over="ignore"):
        z = (np.log(t) - eta) / sigma
        return np.exp(-np.exp(z))


eta0_vis = beta0_vis
eta1_vis = beta0_vis + beta1_vis
surv_ln0_vis = lognormal_survival(t_grid_vis, eta0_vis, sigma_vis)
surv_ln1_vis = lognormal_survival(t_grid_vis, eta1_vis, sigma_vis)
surv_w0_vis = weibull_survival(t_grid_vis, eta0_vis, sigma_vis)
time_ratio_vis = np.exp(beta1_vis)
ConsoleOut [6]
CollapseExpand
Time ratio exp(beta1): 1.568

The time ratio is computed from the generating coefficient rather than inserted by hand, so the printed value and the horizontal stretch in the first figure are guaranteed to agree.

VisualizationOut [7]
CollapseExpand
Two decreasing log-normal survival curves, with the x equals one curve to the right of the x equals zero curve.
Log-normal AFT survival curves for a coefficient of 0.45 comparing x = 0 and x = 1. The x = 1 curve sits to the right, showing that every conditional event-time quantile is multiplied by exp(0.45), about 1.568. Both curves decrease monotonically, and the gap between them is constant on the log time scale: at any fixed survival probability the x = 1 curve lies a factor of exp(0.45) farther to the right, so the additive horizontal gap grows with time. These are illustrative model curves.
VisualizationOut [8]
CollapseExpand
Two decreasing survival curves with the log-normal curve above the Weibull curve over the displayed grid.
Comparison of log-normal and Weibull survival curves at log-time location 1 and scale 0.6. The log-normal curve stays above the Weibull curve over this plotted grid, and the two diverge with different shapes rather than merely a shift. The gap illustrates how the error distribution changes the assumed survival curve despite equal location and scale.

The first figure illustrates the time ratio. If we draw a horizontal line at any survival probability, the intersection with the x=1x=1 curve occurs at a time exp⁡(β1)\exp(\beta_1) times farther to the right than the intersection with the x=0x=0 curve. Here exp⁡(0.45)=1.568\exp(0.45)=1.568, so the entire event-time distribution is stretched by about 57 percent. The second figure shows that the Weibull and log-normal models need not agree even when we give them the same log-time location and scale. Near the middle of the distribution they can be similar, while their tails differ. A model comparison should therefore emphasize the region of the survival curve that matters for the decision, not only the overall fit near the median.

The same comparison can be expressed as a hazard ratio between the two covariate profiles. For the Weibull model the ratio is constant because the proportional hazards representation holds. For the log-normal model the ratio generally changes with time, so a single hazard ratio does not summarize the covariate effect. The following calculation reuses the fixed coefficient and scale values from the survival-curve comparison; no estimation or random sampling is involved.

PythonIn [9]
CollapseExpand
# Reuse the fixed illustrative parameters and time grid from the preceding comparison.
t_hazard_ratio = t_grid_vis[(t_grid_vis >= 0.35) & (t_grid_vis <= 6.0)]
eta_hr0 = beta0_vis
eta_hr1 = beta0_vis + beta1_vis
sigma_hr = sigma_vis

z_hr0 = (np.log(t_hazard_ratio) - eta_hr0) / sigma_hr
z_hr1 = (np.log(t_hazard_ratio) - eta_hr1) / sigma_hr

hr_lognormal = (
    stats.norm.pdf(z_hr1) / (sigma_hr * t_hazard_ratio * stats.norm.sf(z_hr1))
) / (stats.norm.pdf(z_hr0) / (sigma_hr * t_hazard_ratio * stats.norm.sf(z_hr0)))

hr_weibull = np.full_like(
    t_hazard_ratio,
    np.exp(-beta1_vis / sigma_hr),
    dtype=float,
)

hr_ylim = (
    0.0,
    1.15 * max(hr_lognormal.max(), hr_weibull.max(), 1.0),
)
VisualizationOut [10]
CollapseExpand
Weibull hazard ratio stays constant while log-normal hazard ratio changes over time.
Hazard ratio for x = 1 versus x = 0 under the fixed log-normal and Weibull specifications. The Weibull hazard ratio is constant at exp(-0.45/0.6), while the log-normal hazard ratio varies with time. This is the practical difference between a Weibull proportional hazards representation and a log-normal AFT model.

Example

The censored likelihood can look abstract until we evaluate it with actual numbers. The example below computes it by hand for two observations, one event and one censored, and then shows how adding a treatment covariate changes the picture. Working through the numbers rather than trusting the optimizer makes each piece of the formula visible: the standardized residual ww, the density contribution of an event, the survival contribution of a censored observation, and the time ratio of a covariate.

Suppose the log-normal AFT parameters are β0=1.0\beta_0=1.0 and σ=0.5\sigma=0.5, and for the moment there are no covariates, so μ=1.0\mu=1.0. One subject experiences an event at t=3t=3. Another subject is censored at t=2t=2. We compute each contribution separately and then multiply them.

For the event at t=3t=3, we first standardize:

w=log⁡3−1.00.5=1.0986−1.00.5=0.1972.w = \frac{\log 3-1.0}{0.5} = \frac{1.0986-1.0}{0.5} = 0.1972.

The log-normal log density is

log⁡fT(3)=−log⁡3−log⁡0.5−12log⁡(2π)−12(0.1972)2.\log f_T(3) = -\log 3-\log 0.5-\frac{1}{2}\log(2\pi)-\frac{1}{2}(0.1972)^2.

Evaluating each term,

−log⁡3=−1.0986,−log⁡0.5=0.6931,-\log 3=-1.0986,\qquad -\log 0.5=0.6931, −12log⁡(2π)=−0.9189,−12(0.1972)2=−0.0194.-\frac{1}{2}\log(2\pi)=-0.9189,\qquad -\frac{1}{2}(0.1972)^2=-0.0194.

The displayed intermediate terms are rounded; the final values use full precision. Adding the unrounded terms gives log⁡fT(3)≈−1.3439\log f_T(3)\approx -1.3439, so fT(3)≈0.2608f_T(3)\approx 0.2608. This is the density contribution of the observed event.

For the censored subject at t=2t=2,

w=log⁡2−1.00.5=0.6931−1.00.5=−0.6137.w = \frac{\log 2-1.0}{0.5} = \frac{0.6931-1.0}{0.5} = -0.6137.

The survival contribution is

ST(2)=1−Φ(−0.6137)=Φ(0.6137)≈0.7303.S_T(2) = 1-\Phi(-0.6137) = \Phi(0.6137) \approx 0.7303.

The likelihood for these two subjects is therefore

L=fT(3) ST(2)≈0.2608×0.7303≈0.1905.L = f_T(3)\,S_T(2) \approx 0.2608 \times 0.7303 \approx 0.1905.

Using the unrounded likelihood L≈0.19048934L\approx0.19048934, the log-likelihood is log⁡L≈−1.6582\log L\approx -1.6582. Notice the asymmetry in how censoring enters: the event contributes a density, while the censored subject contributes a probability of surviving past the censoring time.

Now add a binary treatment covariate with coefficient β1=0.2\beta_1=0.2. The time ratio is

exp⁡(0.2)=1.2214,\exp(0.2)=1.2214,

so treatment multiplies the event time by about 1.22. Without treatment, the median is exp⁡(1.0)=2.7183\exp(1.0)=2.7183. With treatment, the median is exp⁡(1.2)=3.3201\exp(1.2)=3.3201. The entire distribution shifts by the same factor, not just the median.

For comparison, suppose we used a Weibull AFT model with the same μ=1.0\mu=1.0 and σ=0.5\sigma=0.5. At t=3t=3, the standardized value is still w=0.1972w=0.1972, but the survival probability is

ST(3)=exp⁡(−e0.1972)=exp⁡(−1.2180)≈0.2958,S_T(3) = \exp(-e^{0.1972}) = \exp(-1.2180) \approx 0.2958,

which is lower than the log-normal survival probability at the same time; the log-normal survival at t=3t=3 is 1−Φ(0.1972)≈0.42181-\Phi(0.1972)\approx 0.4218. The likelihood contributions would differ accordingly. This is the practical meaning of a distributional assumption: it changes how much probability mass is assigned to events and censoring times, especially in the tails.

PythonIn [11]
CollapseExpand
mu_ex = 1.0
sigma_ex = 0.5
t_event = 3.0
t_censored = 2.0

w_event = (np.log(t_event) - mu_ex) / sigma_ex
w_censored = (np.log(t_censored) - mu_ex) / sigma_ex

log_density_event = (
    -np.log(t_event)
    - np.log(sigma_ex)
    - 0.5 * np.log(2 * np.pi)
    - 0.5 * w_event**2
)
log_survival_censored = stats.norm.logcdf(-w_censored)
likelihood_example = np.exp(log_density_event + log_survival_censored)
ConsoleOut [12]
CollapseExpand
Standardized event value: 0.1972
Standardized censoring value: -0.6137
Event density contribution: 0.2608
Censored survival contribution: 0.7303
Two-subject likelihood: 0.1905
Log-likelihood: -1.6582

The printed values reproduce the hand calculation: the standardized event value is about 0.20, the censored survival contribution is about 0.73, and the two-subject likelihood is about 0.19. Agreement between the printed numbers and the algebra above is the intended check; a mismatch would point to an error in the standardized residual, the density, or the survival contribution.

Implementation in NumPy and SciPy

We now fit both a log-normal and a Weibull AFT model from primitives. Working from primitives rather than calling a library routine lets each step of the derivation become a piece of code: the standardized residual wiw_i, the density contribution of an event, the survival contribution of a censored observation, and the optimization over regression coefficients and the log-scale. The sample is deliberately small (one binary covariate, forty subjects, with sixteen censored observations in this realization) because the point is to see the likelihood machinery clearly, not to showcase a large data set. The data-generating process is fixed by a seed so the chapter is reproducible, but the fitted results are computed from the actual simulated observations rather than inserted by hand.

Setting Up the Censored Likelihood

The fitted output mixes several conceptually distinct quantities, and it helps to name them before looking at any numbers. The regression coefficients β\boldsymbol{\beta} describe the log-time location; exponentiating a slope gives a time ratio. The scale parameter σ\sigma describes dispersion on the log-time scale; for the Weibull model, the shape parameter is k=1/σk=1/\sigma. The event indicator separates density contributions from survival contributions. The chosen error distribution determines fWf_W and SWS_W, and therefore determines the shape of the fitted hazard. Reading the code below with these roles in mind makes the connection to the formula immediate.

PythonIn [13]
CollapseExpand
import numpy as np
import pandas as pd
from scipy import optimize, stats
from scipy.special import log_ndtr

rng = np.random.default_rng(20250308)
n = 40
x = rng.integers(0, 2, size=n)
true_log_time = 2.00 - 0.45 * x + 0.55 * rng.normal(size=n)
true_time = np.exp(true_log_time)
censor_time = rng.uniform(3.0, 14.0, size=n)
observed_time = np.minimum(true_time, censor_time)
event = (true_time <= censor_time).astype(int)

X = np.column_stack([np.ones(n), x])
log_observed_time = np.log(observed_time)

The generating coefficients place the true log-time mean at 2.00 for the control group and 1.55 for the treated group, with a log-scale of 0.55. For the correctly specified log-normal fit, these generating values provide useful references, although estimates from forty subjects can differ through sampling variation. The Weibull fit uses a different error family, so its location and scale need not recover the normal generating parameters. A divergence between fit and truth here would signal either finite-sample variability, misspecification, or a problem with the numerical procedure.

The helper functions below encode the two likelihoods exactly as derived. For the log-normal model we use log_ndtr(-z) to compute log⁡Φ(−z)\log \Phi(-z) stably, rather than taking the logarithm of a potentially tiny survival probability. For the Weibull model, overflow in an extreme parameter region returns an infinite objective rather than clipping the exponent and changing the likelihood. Contributions are indexed by event status so a zero weight never multiplies an infinite log term.

PythonIn [14]
CollapseExpand
def lognormal_negll(params, X, log_time, event):
    if not np.all(np.isfinite(params)):
        return np.inf
    beta, log_sigma = params[:-1], params[-1]
    with np.errstate(over="ignore", under="ignore"):
        sigma = np.exp(log_sigma)
    if not np.isfinite(sigma) or sigma <= 0:
        return np.inf
    z = (log_time - X @ beta) / sigma
    observed = event == 1
    with np.errstate(over="ignore", invalid="ignore"):
        log_pdf = (
            -log_time[observed]
            - log_sigma
            - 0.5 * np.log(2 * np.pi)
            - 0.5 * z[observed] ** 2
        )
        log_surv = log_ndtr(-z[~observed])
        loglik = log_pdf.sum() + log_surv.sum()
    return float(-loglik) if np.isfinite(loglik) else np.inf


def weibull_negll(params, X, log_time, event):
    if not np.all(np.isfinite(params)):
        return np.inf
    beta, log_sigma = params[:-1], params[-1]
    with np.errstate(over="ignore", under="ignore"):
        sigma = np.exp(log_sigma)
    if not np.isfinite(sigma) or sigma <= 0:
        return np.inf
    z = (log_time - X @ beta) / sigma
    observed = event == 1
    with np.errstate(over="ignore", invalid="ignore"):
        exp_z = np.exp(z)
        loglik = (
            -log_time[observed] - log_sigma + z[observed]
        ).sum() - exp_z.sum()
    return float(-loglik) if np.isfinite(loglik) else np.inf

We optimize with L-BFGS-B and a small multi-start search. The bounds keep log⁡σ\log\sigma in a numerically reasonable range. This does not replace careful modeling, but it prevents an optimizer from exploring absurd scale values during early iterations.

PythonIn [15]
CollapseExpand
def fit_aft(negll, start):
    bounds = [(None, None)] * X.shape[1] + [(-4.0, 3.0)]
    candidates = [
        start,
        start + np.array([0.0, 0.0, 0.5]),
        start - np.array([0.0, 0.0, 0.5]),
    ]
    fits = [
        optimize.minimize(
            negll,
            candidate,
            args=(X, log_observed_time, event),
            method="L-BFGS-B",
            bounds=bounds,
            options={"maxiter": 2000},
        )
        for candidate in candidates
    ]
    successful = [
        result for result in fits if result.success and np.isfinite(result.fun)
    ]
    if not successful:
        raise RuntimeError(
            "No AFT starting point produced a finite converged fit."
        )
    return min(successful, key=lambda result: result.fun)


start = np.array([np.mean(log_observed_time), 0.0, np.log(0.6)])
res_ln = fit_aft(lognormal_negll, start)
res_w = fit_aft(weibull_negll, start)

The table reports the fitted intercept, slope, log-time scale, time ratio for the binary covariate, maximized log-likelihood, and AIC. The log-likelihoods are comparable because both models are fitted to the same observations with the same censoring indicator and both are full likelihoods. Smaller AIC is better, but AIC is only one piece of evidence; a model with a better AIC can still have the wrong tail shape for the decision at hand. Reading the table alongside the survival-curve plots is therefore essential: coefficients summarize the acceleration effect, while the curves show where the distributional assumption is doing the most work.

Out[17]:
Model beta0 beta1 sigma time_ratio_x1 log_likelihood AIC converged
0 Log-normal 2.031439 -0.331528 0.625007 0.717826 -67.866745 141.733490 True
1 Weibull 2.391341 -0.534171 0.448551 0.586155 -66.839888 139.679777 True

Checking an intercept-only reference

SciPy's censored univariate distribution fit provides a separate check of a simpler case. We remove the covariate from the design and fit an intercept-only log-normal model to the same observed durations and censoring indicators. This validates the two-parameter special case of the likelihood, rather than claiming a library check of the full covariate model.

PythonIn [18]
CollapseExpand
X_intercept = np.ones((n, 1))
intercept_fit = optimize.minimize(
    lognormal_negll,
    np.array([np.mean(log_observed_time), np.log(0.6)]),
    args=(X_intercept, log_observed_time, event),
    method="L-BFGS-B",
    bounds=[(None, None), (-4.0, 3.0)],
    options={"maxiter": 2000},
)
if not intercept_fit.success:
    raise RuntimeError(intercept_fit.message)
censored_data = stats.CensoredData.right_censored(observed_time, event == 0)
reference_sigma, reference_location, reference_scale = stats.lognorm.fit(
    censored_data, floc=0.0
)
reference_beta0 = np.log(reference_scale)
reference_params = np.array([reference_beta0, np.log(reference_sigma)])
reference_nll = lognormal_negll(
    reference_params, X_intercept, log_observed_time, event
)
np.testing.assert_allclose(
    intercept_fit.x, reference_params, rtol=0.0, atol=3e-4
)
np.testing.assert_allclose(
    intercept_fit.fun, reference_nll, rtol=0.0, atol=1e-5
)
reference_comparison = pd.DataFrame(
    {
        "fit": ["Primitive intercept-only", "SciPy censored log-normal"],
        "beta0": [intercept_fit.x[0], reference_beta0],
        "sigma": [np.exp(intercept_fit.x[1]), reference_sigma],
        "negative_log_likelihood": [intercept_fit.fun, reference_nll],
    }
)
Out[19]:
fit beta0 sigma negative_log_likelihood
0 Primitive intercept-only 1.794534 0.637115 68.778574
1 SciPy censored log-normal 1.794531 0.637113 68.778574

The assertions compare both parameters and the objective within stated numerical tolerances. Holding SciPy's location at zero matches the positive lifetime model; its scale equals exp(beta0), and its shape equals the log-time scale sigma. Agreement checks the intercept-only numerical likelihood, not the distributional adequacy of the pooled data or the precision of the covariate effect.

Fitting and Evaluating Survival Curves

The fitted curves use the estimated coefficients in the survival functions derived above. We compare them with group-specific Kaplan-Meier estimates, which do not impose a parametric lifetime family but still require appropriate censoring assumptions. In a forty-subject sample, a gap can reflect sampling variation as well as misspecification. The overlays are diagnostics rather than a proof that a family is correct or wrong.

PythonIn [20]
CollapseExpand
t_pred = np.linspace(0.2, 15.0, 400)

eta_ln0 = res_ln.x[0]
eta_ln1 = res_ln.x[0] + res_ln.x[1]
sigma_ln = np.exp(res_ln.x[-1])
surv_ln_x0 = lognormal_survival(t_pred, eta_ln0, sigma_ln)
surv_ln_x1 = lognormal_survival(t_pred, eta_ln1, sigma_ln)

eta_w0 = res_w.x[0]
eta_w1 = res_w.x[0] + res_w.x[1]
sigma_w = np.exp(res_w.x[-1])
surv_w_x0 = weibull_survival(t_pred, eta_w0, sigma_w)
surv_w_x1 = weibull_survival(t_pred, eta_w1, sigma_w)


def kaplan_meier(time, event):
    order = np.argsort(time)
    time = time[order]
    event = event[order]
    event_times = np.unique(time[event == 1])

    step_times = [0.0]
    step_survival = [1.0]
    survival = 1.0

    for current_time in event_times:
        at_risk = np.sum(time >= current_time)
        deaths = np.sum((time == current_time) & (event == 1))
        survival *= 1.0 - deaths / at_risk
        step_times.append(current_time)
        step_survival.append(survival)

    if len(time) and step_times[-1] < time.max():
        step_times.append(time.max())
        step_survival.append(survival)
    return np.array(step_times), np.array(step_survival)


km_t0, km_s0 = kaplan_meier(observed_time[x == 0], event[x == 0])
km_t1, km_s1 = kaplan_meier(observed_time[x == 1], event[x == 1])
VisualizationOut [21]
CollapseExpand
A Kaplan-Meier step curve and fitted log-normal and Weibull survival lines for group 0.
Censored-likelihood log-normal and Weibull fits for group x = 0, compared with its Kaplan-Meier estimate. Each parametric family uses its own fitted coefficients, and the nonparametric step curve shows how well each family follows the observed survival. The Kaplan-Meier line stops at observed follow-up; the parametric curves extend to time 15 under their distributional assumptions.
VisualizationOut [22]
CollapseExpand
A Kaplan-Meier step curve and fitted log-normal and Weibull survival lines for group 1.
Censored-likelihood log-normal and Weibull fits for group x = 1, compared with its Kaplan-Meier estimate. Each parametric family uses its own fitted coefficients, so the fitted lines reflect the treated-group estimates. The Kaplan-Meier line stops at observed follow-up, while the parametric curves extend to time 15 under their distributional assumptions.

The comparison is deliberately visual and local. If one parametric curve follows the Kaplan-Meier steps closely in the region where most events occur but diverges after the last few observations, that divergence may be an extrapolation issue rather than evidence about the middle of the distribution. If the fitted curve misses the early steps systematically, the distribution or the linear log-time predictor is suspect. The printed coefficient table and the plotted curves should be read together: coefficients summarize the acceleration effect, while the curves show where the distributional assumption is doing the most work.

Key Parameters

Below are the main parameters that affect how the AFT fits behave, with practical guidance on how to select them. The same names appear in the derivation and the implementation.

  • beta0: Intercept of the log-time location. It sets the baseline log time when all covariates are zero; centering covariates changes it without changing slopes.
  • beta1 (and other slopes): Log-time effect of each covariate. Exponentiating a slope gives a time ratio, so beta1 = -0.45 corresponds to a time ratio of about 0.64.
  • log_sigma (equivalently sigma): Log-scale dispersion parameterized so positive sigma is represented on the real log scale. Exponentiation makes sigma positive; the bounds restrict it to the chosen finite range, about 0.018 to 20.1; the Weibull shape is k = 1/sigma.
  • Error distribution: The choice of f_W and S_W. The normal error gives a log-normal model with a possibly non-monotone hazard; the minimum Gumbel error gives a Weibull model with a monotone hazard and a proportional hazards representation.
  • maxiter and starting values: Controls for the multi-start L-BFGS-B search. Multiple starts help with flat or non-concave likelihoods, especially under heavy censoring.

Practical Implications

AFT models are most useful when the scientific or operational question is phrased on the time scale: how much longer until recovery, how much sooner until failure, or how much later until churn. In medicine, a time ratio can summarize how a treatment changes the typical time to an event. In reliability engineering, a Weibull AFT model is a standard way to describe how stress or operating conditions accelerate failure. For a stipulated churn example, let the event time run from subscription start to cancellation and let a baseline plan or prespecified onboarding-group indicator enter the covariate vector. Under the stated AFT assumptions, its exponentiated slope is a conditional time ratio. An observational association does not by itself identify the effect of changing the plan or onboarding process. In these settings, exponentiating a slope gives an effect size that collaborators can interpret without translating from instantaneous risk.

The model is a strong candidate when a full survival curve, event-time quantile, or prediction interval is needed and a parametric error distribution is defensible. It is less attractive when the proportional hazards assumption is credible and the event-time distribution is unknown, because Cox regression avoids the distributional commitment. A single acceleration factor is also too simple when the required conditional time ratios differ across subject groups or event-time quantiles. A hazard ratio that varies over time can still be compatible with a log-normal AFT model. When conditional time ratios differ across groups or event-time quantiles, interactions, stratified models, time-varying covariates, or a different modeling framework may be more appropriate than a single acceleration factor.

The main tradeoff is between interpretability and assumption strength. A time ratio describes how conditional quantiles scale, and the full likelihood supports survival-curve estimation, but the tail behavior is determined by the chosen distribution. If long-term extrapolation drives the decision, the AFT model should be treated as a structured hypothesis about the tail rather than as a neutral summary of the data.

Data Requirements and Preprocessing

The minimum data requirements are a positive observed time, an event indicator, and covariates measured before or at the start of follow-up. The censoring mechanism should be independent of the event time after conditioning on covariates. If subjects with worse unobserved prognosis are more likely to leave even after conditioning on the included covariates, the independent-censoring factorization can fail. Changing the event-time family alone does not establish a valid observation model. Time units should be consistent across subjects, zero or negative recorded times need investigation rather than automatic deletion or replacement, and tied event times should be handled with an explicit convention. Coarse measurement can create many ties; this is not fatal, but it can affect standard errors and should be documented.

Covariate scaling is not required for interpretation because a time ratio is defined per unit of the covariate in its original units. Centering changes the intercept but not the slope or time ratio. Standardizing changes the slope to an effect per standard deviation, which can be useful for comparing covariates but should be described explicitly in any report. Scaling is still helpful for numerical stability when covariates differ greatly in magnitude, and missing covariates must be addressed before fitting rather than hidden inside the likelihood. Do not substitute arbitrary event times for censored records in this likelihood. The survival contribution uses their known lower bounds; model-based imputation is a different procedure with its own assumptions.

Best Practices

The choice of error distribution should follow the hazard shape and the decision-relevant region of the survival curve. The Weibull model implies a monotone hazard: increasing when k>1k>1, decreasing when k<1k<1, and constant when k=1k=1. The log-normal model can produce a non-monotone hazard, which is useful when risk rises and later falls. When both distributions are plausible, fitting both and overlaying their survival curves on Kaplan-Meier estimates is a useful sensitivity check. A small AIC difference in a small sample should not override a visible calibration failure in the time region that matters.

Optimization should respect the constrained parameter space. Parameterizing the scale as log⁡σ\log\sigma, using multiple starting values, and bounding log⁡σ\log\sigma to a reasonable range such as (−4,3)(-4,3) reduces the chance of exploring absurd scale values. In the implementation used here, three starts and maxiter=2000 are the settings for this small example, but larger or heavily censored data may require more starts or a different optimizer. Convergence should be checked explicitly, and fitted time ratios should be reported with uncertainty intervals and with the assumed distribution stated alongside them.

Model selection should combine numerical fit with subject-matter plausibility. AIC and BIC are useful when comparing full-likelihood AFT models on the same observations and censoring indicator, but they do not diagnose tail misspecification. A model with a slightly worse AIC may be preferable if it follows the Kaplan-Meier curve more closely in the region where decisions are made, or if its implied hazard shape is more credible. Reporting a single "best" model without that context overstates what the information criterion can decide.

Common Pitfalls

An AFT slope is a log time ratio, not a log hazard ratio. Among the two families studied here, the Weibull model has the proportional-hazards conversion HRj=exp⁡(−βj/σ)\mathrm{HR}_j=\exp(-\beta_j/\sigma). Positive βj\beta_j then gives a hazard ratio below one. The log-normal hazard ratio generally varies with time, so the same constant conversion does not apply. An observational time ratio is a conditional association unless the study design and assumptions support a causal interpretation.

Another pitfall is to treat the distributional choice as a computational detail. Weibull and log-normal models can agree near the median while diverging in the tail. If a decision horizon lies beyond most observed follow-up, that tail difference can change the prediction used for the decision. Extrapolating a fitted curve beyond the largest observed time therefore relies on the assumed event-time family. Similarly, selecting a distribution only because it has the smallest AIC in a small sample can favor a model that fits the middle of the data while missing the region of interest.

Numerical and design problems also matter. With heavy censoring or few events, the likelihood can be flat, and an optimizer may report convergence at an unstable solution. Models with many covariates and few events can produce large time ratios with wide or unreliable intervals; event count alone does not guarantee stability, particularly with collinear or weakly varying covariates. Finally, informative censoring can invalidate this reduced likelihood regardless of how well the model converges, so the censoring process deserves the same scrutiny as the event process.

Computational Considerations

For the likelihoods used here, each dense objective evaluation costs O(n(p+1))O(n(p+1)) for pp covariates plus an intercept: the model matrix is multiplied by the coefficient vector, residuals are formed, and the density and survival contributions are summed over subjects. There is no pairwise distance matrix, so the method scales linearly in the number of observations per evaluation rather than quadratically. Total fitting cost depends on the number and cost of objective and gradient evaluations across all starts. Fitting both families requires separate optimization, and their evaluation counts can differ. With finite-difference gradients, an optimizer iteration can require multiple objective calls, so iteration count alone is not a runtime bound.

Memory is dominated by the model matrix and the vectors used to form residuals and likelihood contributions. Dense matrices are convenient for small or moderate problems; for large data with categorical covariates, sparse design matrices can reduce storage substantially. When nn is very large, it can be helpful to compute the log-likelihood in chunks rather than materializing many temporary arrays at once. The implementation bounds log scale and rejects nonfinite likelihood evaluations instead of clipping the model exponent. These numerical safeguards do not make an unidentified model identifiable.

Model diagnostics and comparison with Cox regression

A useful diagnostic is the Cox-Snell residual. For each subject, define

ri=−log⁡ST(yi∣xi).r_i = -\log S_T(y_i\mid \mathbf{x}_i).

With the true continuous conditional survival function, −log⁡ST(Ti∣xi)-\log S_T(T_i\mid\mathbf{x}_i) has an exponential distribution with rate one. Applying the same transformation to yiy_i gives censored residuals that retain the event indicators. A Kaplan-Meier residual-survival curve can be compared with exp⁡(−r)\exp(-r) over the supported range. When parameters are estimated from the same sample, this is an approximate fitted-model diagnostic, not an exact independent sample from the reference law. Standardized log-time residuals also remain censored; the observed-event subset is selected and should not simply be compared with an uncensored sample from the assumed error distribution. Censoring-aware residual methods require the corresponding observation assumptions.

Model comparison should distinguish between models with the same likelihood and models with different likelihoods. The log-normal and Weibull AFT models are both full likelihoods on the same observed times and event indicators, so AIC and BIC are directly comparable, with the caveat that they reward different complexity penalties. Under regular nested-model asymptotics with identifiable interior parameters, the likelihood-ratio statistic has a chi-square reference law. Log-normal and Weibull are not nested, so the usual nested-model chi-square likelihood-ratio test is not appropriate for choosing between them.

Comparing an AFT model with a Cox model requires more care. The Cox model maximizes a partial likelihood, while the AFT model maximizes a full likelihood. Their AIC values are not on the same scale and should not be compared directly. Instead, we compare out-of-sample predictive performance: concordance, calibration of predicted survival curves, integrated Brier score, or a survival log score. Score models on common held-out records with an appropriate censoring treatment, and assess horizon-specific probabilities only where follow-up has the required support. We can also compare fitted survival curves at clinically or operationally relevant times. If a Weibull AFT model is used, we can translate its coefficients to hazard ratios through exp⁡(−βj/σ)\exp(-\beta_j/\sigma) and check whether that proportional hazards structure is plausible. A time-varying hazard ratio is outside the Weibull AFT model's proportional-hazards restriction. Proportional-hazards diagnostics from a Cox fit can motivate checking that possibility; a log-normal or log-logistic AFT model may fit the pattern better.

Check influence and extrapolation explicitly. A single early event or a very late censoring time can have substantial leverage in a parametric model. Refitting with and without influential observations, checking convergence from multiple starting values, and plotting fitted curves against Kaplan-Meier estimates are simple but effective safeguards. If the fitted curve is stable in the observed range but sensitive to one observation in the tail, the extrapolated portion should not be presented as if it were estimated with the same confidence as the interior of the distribution.

Performance and Deployment

Performance should be judged on the time scale whenever possible. Concordance measures ranking, but it does not show whether predicted survival probabilities are calibrated. Calibration curves at clinically or operationally relevant horizons, the integrated Brier score, and a survival log score provide complementary views. These metrics are especially useful when comparing an AFT model with a Cox model, because they avoid the invalid comparison of partial and full likelihood AIC values. A model that ranks subjects well but assigns systematically optimistic survival probabilities may still be a poor choice for planning.

Deployment requires storing more than the fitted coefficients. The error distribution, the scale parameter, the covariate preprocessing rules, the time unit, and the censoring convention all affect predictions and should be versioned together. Monitoring should track the event rate, the censoring rate, and calibration at the horizons used for decisions, not just overall concordance. If the population or the censoring process shifts, the fitted baseline location and scale may need recalibration or refitting even when the covariate effects remain stable.

The fitted AFT model can supply survival curves, event-time quantiles, and prediction intervals, but those outputs inherit the distributional assumption. In production, it is therefore useful to distinguish between interpolation within the observed follow-up range and extrapolation beyond it. The former is supported mainly by the fit to the observed data; the latter is supported mainly by the assumed error distribution. Treating the two as equally reliable hides how strongly the extrapolated prediction depends on the chosen tail model.

Summary

Accelerated failure-time models describe how covariates multiply the event time. On the log scale, the model is a linear regression with a distributional error term, and exponentiating a coefficient gives a time ratio that applies to every quantile of the event-time distribution. This makes AFT models particularly interpretable when the question is about lengthening or shortening time to an event.

Censoring enters through the likelihood in a natural way. An observed event contributes a density, while a censored observation contributes a survival probability. Transforming the standardized error to event time gives the event log-density terms −log⁡yi−log⁡σ-\log y_i-\log\sigma: the log-time-to-time transformation supplies −log⁡yi-\log y_i, while standardizing log time supplies −log⁡σ-\log\sigma. The Weibull and log-normal models are the two standard choices: the Weibull model has a monotone hazard and a special proportional hazards representation, while the log-normal model can represent non-monotone hazards but does not generally satisfy proportional hazards.

The practical lesson is to define the parameterization before interpreting signs, to check the distributional assumption against nonparametric survival curves and residuals, and to compare AFT models with Cox models using predictive performance rather than mismatched likelihood criteria. When the parametric assumption is credible, the fitted AFT parameters determine time ratios, survival curves, and event-time quantiles. When it is not, the model can still be useful as a smoothed summary, but its tail predictions should be treated with caution.

Quiz

Ready to test your understanding? Take this quick quiz to reinforce what you've learned about accelerated failure-time models.

Accelerated Failure-Time Models

Question 1 of 70 of 7 completed
An AFT coefficient for a covariate is 0.2. Holding other covariates and the individual error term fixed, how should this be interpreted on the time scale?
Join the discussionAsk a question or share what you learned.

Comments

Add to the conversation

A question, a correction, or an example from your own work.

No comments yet. Be the first to share your thoughts!

A different angle
All writing
Machine Learning

Evaluating Survival Predictions

Score censored survival models with concordance and IPCW Brier scores. Learn to compare Cox, Weibull AFT, and Kaplan-Meier forecasts honestly.

77 min read
Machine Learning

Cox Proportional Hazards

Learn how the Cox proportional hazards model estimates covariate effects on hazards using partial likelihood, with NumPy implementation and diagnostics.

57 min read
Machine Learning

Kaplan–Meier and Nelson–Aalen Estimation

Learn Kaplan-Meier and Nelson-Aalen estimation for right-censored data, covering risk sets, ties, Greenwood variance, medians, and NumPy implementation.

39 min read

About the author

Reference

Citation details

Cite or share this article.

BIBTEXAcademic
@misc{brenndoerfer2026acceleratedfailure, author = {Michael Brenndoerfer}, title = {Accelerated Failure-Time Models}, year = {2026}, url = {https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch}, organization = {mbrenndoerfer.com}, note = {Accessed: 2026-10-28} }
APAAcademic
Michael Brenndoerfer (2026). Accelerated Failure-Time Models. Retrieved from https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch
MLAAcademic
Michael Brenndoerfer. "Accelerated Failure-Time Models." 2026. Web. October 28, 2026. <https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch>.
CHICAGOAcademic
Michael Brenndoerfer. "Accelerated Failure-Time Models." Accessed October 28, 2026. https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch.
HARVARDAcademic
Michael Brenndoerfer (2026) 'Accelerated Failure-Time Models'. Available at: https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch (Accessed: October 28, 2026).
SimpleBasic
Michael Brenndoerfer (2026). Accelerated Failure-Time Models. https://mbrenndoerfer.com/writing/accelerated-failure-time-models-from-scratch
Newsletter

Stay up to date

Get new articles, book updates, and notes on AI and technology.

Unsubscribe at any time. Privacy policy