Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Cox partial likelihood and hazard-ratio interpretation

Last updated: 5 Oct 20265 min read
tutorial
AdvancedBy AITrove Editorial

A Cox model relates covariates to the instantaneous event rate among cases still at risk, while leaving the baseline hazard shape unspecified.

Define the event before the ratio

For support operations, let the event be recorded resolution and time zero be case creation. A binary covariate marks whether a case entered the priority queue at creation. Under a proportional-hazards model, exp(beta) compares the resolution hazard for priority versus standard cases at the same elapsed age, conditional on modeled covariates. A value above one means a higher instantaneous resolution rate among still-unresolved cases. It is not a ratio of six-day resolution probabilities, and it does not directly express saved case-days. Restricted mean open time answers a different decision question.

See how the risk set enters fitting

At each distinct resolution time, the partial-likelihood contribution compares the event case’s exp(beta times covariate) with the sum of those terms among every case still at risk just before that event. A right-censored case remains in earlier denominators and leaves after its censor time. This teaching implementation scans a no-ties, one-covariate ledger over a coefficient grid. It makes the mechanism inspectable; a production fit needs a vetted optimizer, tie handling, uncertainty estimation and careful treatment of delayed entry. Risk-set accounting is the foundation.

Do not promote a baseline attribute that arrived later

Priority assignment recorded after case creation cannot be copied back to day zero. Doing so grants the eventual priority group guaranteed unresolved time before assignment. Use only covariates known at time zero for this static illustration, or represent later changes as time-varying intervals with an explicit observation design. Landmark analysis shows one conditional alternative.

State what the model assumes

The hazard ratio is assumed constant over elapsed time for a fixed covariate contrast, even while the baseline hazard can rise or fall. Cases also need a defensible censoring mechanism and consistent outcome coding. A priority queue may receive more complex cases, so the fitted association is not automatically the causal effect of priority routing. Check available pre-assignment severity measures, case mix, and model stability before drawing an operational conclusion. Diagnostics test whether one ratio hides a changing relationship.

Use a risk ratio only for its intended output

A hazard ratio can summarize a relative association for a model whose assumptions hold. A queue manager deciding staffing needs actual six-day resolution probabilities and open-time costs as well. Estimate those on a supported horizon and validate them on later cases; a model can rank cases reasonably while predicting the wrong absolute rate. Horizon calibration checks that absolute prediction.

Implementation

python
from math import exp, log

def cox_log_partial_likelihood(case_records, coefficient):
    if len({case_id for case_id, _, _, _ in case_records}) != len(case_records):
        raise ValueError("duplicate case ID")
    if any(day <= 0 or resolved not in (0, 1) or priority not in (0, 1)
           for _, day, resolved, priority in case_records):
        raise ValueError("invalid case record")
    event_days = [day for _, day, resolved, _ in case_records if resolved]
    if len(event_days) != len(set(event_days)):
        raise ValueError("this teaching calculation requires untied events")
    score = 0.0
    for _, event_day, resolved, priority in case_records:
        if not resolved:
            continue
        risk_weight = sum(exp(coefficient * peer_priority)
                          for _, peer_day, _, peer_priority in case_records
                          if peer_day >= event_day)
        score += coefficient * priority - log(risk_weight)
    return score

cases = [("P61", 2, 1, 1), ("P62", 3, 1, 0), ("P63", 4, 0, 0),
         ("P64", 5, 1, 1), ("P65", 6, 0, 1), ("P66", 7, 1, 0),
         ("P67", 8, 1, 1), ("P68", 9, 0, 0)]
grid = [step / 100 for step in range(-200, 201)]
best_coefficient = max(grid, key=lambda value: cox_log_partial_likelihood(cases, value))
priority_hazard_ratio = exp(best_coefficient)
assert priority_hazard_ratio > 0
assert cox_log_partial_likelihood(cases, best_coefficient) >= (
    cox_log_partial_likelihood(cases, 0))

Performance and operating cost

With N records, E event times and G grid coefficients, the direct risk-set scan is O(G × E × N) time and O(N) space for the ledger. Production partial-likelihood fitting precomputes risk information and handles ties; this grid is an explanation and input check, not an inference engine.

Common Mistakes

  • Do not interpret a hazard ratio as a fixed-horizon probability ratio.
  • Do not treat a post-creation queue assignment as a baseline feature.
  • Do not use this no-ties grid as a production replacement for an established survival fitter.

Read next

Continue the workflow: Counting-process intervals for a time-varying Cox model.

Continue the workflow: From cause-specific event rates to absolute risk.

ai-data
data-science
Storage details