Accelerated Failure-Time Models
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 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
Accelerated Failure-Time Models
An AFT coefficient of corresponds to a time ratio of : 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 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 must be positive, so the implementation below optimizes over . 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 . 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 , let be the true event time, let be the censoring time, and let
be the observed time. Define the event indicator
Thus means we observed the event, and means the observation was right-censored. Let include an intercept and covariates, and let be the corresponding coefficient vector.
What we ultimately want is the conditional distribution of given , but the observed data give only partial information: for events we see , for censored subjects we only know that . 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
where is a standardized error term with a chosen distribution, and is a scale parameter. In matrix notation,
Equivalently,
The two factors on the right have clearly separated roles. The first, , depends only on covariates and shifts the entire distribution of event times. The second, , 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 -th component by one unit, and imagine that the individual noise is identical for both. Then
This ratio is the time ratio, also called the acceleration factor. If , then , so the event time is multiplied by about 1.22, or prolonged by 22.1 percent. If , then , 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 -th quantile of depends on covariates only through the common factor . 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 is the survival function of the standardized error, then
Once , , and 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 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 ; 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 has an observed event at , we have observed the value of , so its contribution is the density .
- If subject is censored at , the only information available is that , so its contribution is the probability of that event, the survival function .
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:
Taking logarithms turns the product into a sum:
To express each piece in terms of the standardized error, standardize each observation:
Because , the transformation from to has Jacobian
Therefore the density of is
where is the density of the standardized error. Taking logs gives
The Jacobian contributes to an event log density. For fixed observed times, the 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 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:
Substituting these expressions into the log-likelihood, we obtain the general AFT censored log-likelihood:
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 , differing from its log-time likelihood by the parameter-free sum . Every parametric AFT model, including Weibull, log-normal, and log-logistic, is expressed simply by plugging in the corresponding and 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 and . We compare two error distributions:
- The standard normal error is symmetric and produces a log-normal distribution for . 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 , 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]Expand
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]Expand

For the log-normal AFT model, . Then
where:
- : the standard normal cumulative distribution function
- : the event time
- : the log-time location for the covariate profile
- : the log-time scale parameter
The density is
where is the standard normal density. The hazard is the ratio
Here . The log-normal hazard can rise and later fall; it tends to zero both as and as . This is different from a Weibull hazard, whose direction is controlled by one shape parameter.
For the Weibull AFT model, follows the standard minimum Gumbel distribution, whose survival function is
where:
- : the standardized log-time value
- : the exponential of , which is always positive
- : the Gumbel survival probability, decreasing from 1 toward 0 as increases
Substituting gives
If we set the shape parameter and the scale parameter , this becomes the usual Weibull survival function
The density is
To derive the hazard, we use the definition . Differentiating the survival function with the chain rule,
Since , dividing by gives
This factorization is why the Gumbel error is useful here. Write the hazard as
The sum in the second factor uses only the 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
for a one-unit increase in covariate . The sign flips relative to the AFT coefficient because a positive 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 is the -th quantile of , then the -th quantile of given covariates is
For a one-unit change in , the ratio of quantiles is , independent of . This is the constant time-ratio property, and it is what justifies calling an acceleration factor rather than just a coefficient on the log scale.
The median depends on which we choose. For the log-normal model, the median is because the median of a standard normal is zero. For the Weibull model, the median is
because the minimum Gumbel median is . Solving gives , so the median shift is negative when multiplied by positive . The two models can therefore share the same and 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 as 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]Expand
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]Expand
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]Expand

VisualizationOut [8]Expand

The first figure illustrates the time ratio. If we draw a horizontal line at any survival probability, the intersection with the curve occurs at a time times farther to the right than the intersection with the curve. Here , 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]Expand
# 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]Expand

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 , 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 and , and for the moment there are no covariates, so . One subject experiences an event at . Another subject is censored at . We compute each contribution separately and then multiply them.
For the event at , we first standardize:
The log-normal log density is
Evaluating each term,
The displayed intermediate terms are rounded; the final values use full precision. Adding the unrounded terms gives , so . This is the density contribution of the observed event.
For the censored subject at ,
The survival contribution is
The likelihood for these two subjects is therefore
Using the unrounded likelihood , the log-likelihood is . 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 . The time ratio is
so treatment multiplies the event time by about 1.22. Without treatment, the median is . With treatment, the median is . The entire distribution shifts by the same factor, not just the median.
For comparison, suppose we used a Weibull AFT model with the same and . At , the standardized value is still , but the survival probability is
which is lower than the log-normal survival probability at the same time; the log-normal survival at is . 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]Expand
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]Expand
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 , 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 describe the log-time location; exponentiating a slope gives a time ratio. The scale parameter describes dispersion on the log-time scale; for the Weibull model, the shape parameter is . The event indicator separates density contributions from survival contributions. The chosen error distribution determines and , 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]Expand
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 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]Expand
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.infWe optimize with L-BFGS-B and a small multi-start search. The bounds keep 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]Expand
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.
| 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]Expand
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],
}
)| 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]Expand
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]Expand

VisualizationOut [22]Expand

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, sobeta1 = -0.45corresponds to a time ratio of about 0.64.log_sigma(equivalentlysigma): 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 isk = 1/sigma.- Error distribution: The choice of
f_WandS_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. maxiterand 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 , decreasing when , and constant when . 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 , using multiple starting values, and bounding to a reasonable range such as 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 . Positive 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 for 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 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
With the true continuous conditional survival function, has an exponential distribution with rate one. Applying the same transformation to gives censored residuals that retain the event indicators. A Kaplan-Meier residual-survival curve can be compared with 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 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 : the log-time-to-time transformation supplies , while standardizing log time supplies . 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
Join the discussionAsk a question or share what you learned.
Keep exploring
Reference
Citation details
Cite or share this article.

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!