Time-to-Event Data, Censoring, and Hazard Functions › Example
Machine Learning from ScratchAll chapters Time-to-Event Data, Censoring, and Hazard Functions › ExampleSection view · Sections in this chapter6 / 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
To see the likelihood in action, let us work through a small hand-computable example. Suppose we observe six subjects, each of whose observed times and event indicators are as follows.
| Subject | Observed time | Event |
|---|---|---|
| 1 | 2 | 1 |
| 2 | 3 | 1 |
| 3 | 5 | 0 |
| 4 | 1 | 1 |
| 5 | 4 | 1 |
| 6 | 6 | 0 |
Four of the six records are observed events, and two are right-censored. We do not know the underlying or . All we know is that and . Those two censored records are the entire reason this example is worth doing. If we knew all six event times, the exercise would be an ordinary exponential fit. Because we do not, the example shows how the likelihood turns partial information into a usable estimate. Suppose we adopt an exponential model, for all , so that , , and . The log-likelihood becomes
where is the number of events and the sum inside the second term is over all records, not just the events.
The two sufficient statistics are
To maximize , take the derivative with respect to :
which is the standard one-variable calculus problem from Maximum Likelihood Estimation. Setting it to zero gives . The second derivative is , so this is a maximum. Notice what the estimator is doing. It divides the number of observed events by the total time that subjects were under observation. Censored records still contribute exposure time to the denominator, which is exactly how they inform the hazard without pretending that their events were observed.
Two alternative estimates reveal what the correct likelihood is protecting us from.
If we treat every observed record as an event, that is, we ignore censoring completely, we would maximize the product of densities over all six records, , whose logarithm is , since . The maximizer is , which is fifty percent higher than the honest estimate. That corresponds to an expected lifetime of time units, versus for the correct fit.
If instead we drop the two censored records, the "complete cases" approach, we maximize , where the total observed time only includes the four observed events. The maximizer is , which is times the censoring-aware estimate, or more than double it. That corresponds to an expected lifetime of time units.
PythonIn [10]Expand
Y_ex = np.array([2.0, 3.0, 5.0, 1.0, 4.0, 6.0])
d_ex = np.array([1, 1, 0, 1, 1, 0])
D_ex = int(d_ex.sum())
sumY_ex = float(Y_ex.sum())
lam_hat = D_ex / sumY_ex
lam_naive = len(Y_ex) / sumY_ex
sumY_event = float(Y_ex[d_ex == 1].sum())
lam_drop = D_ex / sumY_event
# Independent library comparison: an exponential distribution with fixed location.
reference_data = CensoredData.right_censored(Y_ex, d_ex == 0)
reference_loc, reference_scale = expon.fit(reference_data, floc=0.0)
lam_reference = 1.0 / reference_scale
np.testing.assert_allclose(lam_reference, lam_hat, rtol=1e-10, atol=1e-12)
ll_hat = D_ex * np.log(lam_hat) - lam_hat * sumY_ex
ll_naive = len(Y_ex) * np.log(lam_naive) - lam_naive * sumY_ex
ll_drop = D_ex * np.log(lam_drop) - lam_drop * sumY_event| estimate | lambda_hat | expected_lifetime | |
|---|---|---|---|
| 0 | correct MLE | 0.1905 | 5.25 |
| 1 | treat censored as events | 0.2857 | 3.50 |
| 2 | drop censored | 0.4000 | 2.50 |
SciPy's CensoredData.right_censored marks the two censored observations, and expon.fit(..., floc=0) estimates the exponential scale while holding the location at zero. Its reciprocal agrees with to the tolerance asserted in the executed cell. This checks the six-record exponential case against an established censored-distribution implementation; it is not a check of covariate regression or delayed entry.
On these six records, treating censorings as events increases the rate from to , and dropping them gives . The censored durations contribute eleven units of known event-free exposure. Dropping them removes that exposure without changing the event count. This calculation demonstrates the effect on this dataset; it is not proof of the direction of every regression bias. The three fits use different observation rules, so their maximized objective values would not be valid likelihood comparisons on a common dataset.
To see the maximum visually, plot the log-likelihood as a function of .
PythonIn [12]Expand
lam_grid = np.linspace(0.05, 0.45, 200)
ll_grid = D_ex * np.log(lam_grid) - lam_grid * sumY_exPythonIn [13]Expand
import matplotlib.pyplot as plt
from book_plot_style import PALETTE, polish_axes, use_book_style
use_book_style()
fig, ax = plt.subplots(figsize=(6.0, 4.0))
ax.plot(lam_grid, ll_grid, color=pal(0), linewidth=1.1, label="log-likelihood")
ax.axvline(
lam_hat,
color=pal(1),
linestyle="--",
linewidth=1.0,
label=f"MLE $\\hat\\lambda = {lam_hat:.4f}$",
)
ax.axvline(
lam_naive,
color=pal(2),
linestyle=":",
linewidth=1.0,
label=f"naive $\\hat\\lambda = {lam_naive:.4f}$",
)
ax.scatter([lam_hat], [ll_hat], color=pal(1), zorder=5)
ax.set_xlabel("$\\lambda$")
ax.set_ylabel("log-likelihood $\\ell(\\lambda)$")
ax.set_title("Exponential rate: six-record likelihood")
ax.legend(loc="upper center", bbox_to_anchor=(0.5, -0.2))
polish_axes(ax)
plt.tight_layout()
plt.show()VisualizationOut [13]Expand

For this exponential rate objective, and positive total exposure imply a strictly negative second derivative and a unique positive maximizer. The claim is about this parameterization and dataset, not a general concavity guarantee for every survival family or optimizer. The dashed line marks the maximum; the dotted naive estimate sits to its right. Next we compare the analytic estimate, a primitive numerical objective, and a library fit that directly accepts censored observations.
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!