AalenAdditive

Aalen additive hazards model with time-varying coefficients.

Usage

Source

AalenAdditive(
    *,
    nmin=None,
    test="aalen",
    qrtol=1e-07,
)

The additive hazards model is an alternative to Cox regression when the proportional hazards assumption fails. Instead of modeling the log-hazard ratio as constant over time, it models the hazard itself as a sum of covariate-specific, time-varying functions:

h(t \mid x) = \beta_0(t) + \sum_{j=1}^{p} \beta_j(t)\,x_j

Estimation proceeds by ordinary least squares at each event time: for each death, the coefficient increment d\hat{B}(t) is obtained by regressing the event indicator on the at-risk covariate matrix. Cumulative coefficients \hat{B}(t) are obtained by summing these increments.

Parameters

nmin: int | None = None

Minimum risk-set size. Event times where the risk set has fewer than nmin subjects are dropped (late-tail instability). Defaults to 3 * (p + 1) where p is the number of covariates.

test: str = "aalen"

Weighting scheme for the summary test statistics. "aalen" (default) uses equal weights, "variance" uses inverse-variance weights, and "nrisk" uses the number at risk.

qrtol: float = 1e-07
QR decomposition tolerance for detecting rank deficiency (default 1e-7).

Examples

Fit the Aalen additive model on the lung dataset:

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")

aalen = gw.AalenAdditive().fit("Surv(time, status) ~ age + sex", data=lung)
aalen
AalenAdditive (additive hazards, test='aalen')

               slope       coef   se(coef)       z        p
Intercept    0.00483   0.005448   0.004703   1.158    0.247
age        8.986e-05  0.0001263  6.903e-05   1.829   0.0674
sex        -0.003151  -0.003938   0.001222  -3.222  0.00127

n = 228, events = 165, event times used = 164

Methods

Name Description
cumulative_coefficients() Return the cumulative regression coefficients \hat{B}(t) as a DataFrame.
fit() Fit the Aalen additive hazards model.
predict() Predict survival or cumulative hazard from the fitted Aalen additive model.
to_frame() Return the summary test table as a DataFrame.

cumulative_coefficients()

Return the cumulative regression coefficients \hat{B}(t) as a DataFrame.

Usage

Source

cumulative_coefficients(
    *,
    format=None,
)

Each row corresponds to an event time. The cumulative coefficient for covariate j at time t is \hat{B}_j(t) = \sum_{s \le t} d\hat{B}_j(s), the running total of OLS increments up to time t.

Parameters

format: str | None = None
Output format: None (default), "pandas", "polars", or "pyarrow".

Returns

DataFrame
Columns: time and one column per term (Intercept plus covariates).

fit()

Fit the Aalen additive hazards model.

Usage

Source

fit(
    surv,
    covariates=None,
    *,
    data=None,
)

At each event time, an OLS regression of the event indicator on the at-risk design matrix produces one coefficient increment per covariate. The cumulative sum of these increments gives the cumulative regression function \hat{B}(t).

Parameters

surv: Surv | Outcome | str

A right-censored or counting-process Surv response. An Outcome or a formula string such as 'Surv(time, status == 2) ~ age + sex' is also accepted, with its columns read from data. The right-hand side sets covariates.

covariates: Any = None

A dataframe (pandas or polars), 2-D array, or formula string evaluated against data. A list of column names in data also works.

data: Any = None
A data frame (pandas, Polars, PyArrow, DuckDB, a lazy frame, …) holding the columns named by the response and covariates. When surv is an Outcome or a formula, rows with a missing value in any column used are dropped before fitting. Covariate formula strings and lists of column names are also resolved here.

Returns

AalenAdditive
The fitted estimator.

Examples

Fit the Aalen additive model on the lung dataset with two covariates. The summary shows the cumulative-regression test for each covariate:

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")

aalen = gw.AalenAdditive().fit("Surv(time, status) ~ age + sex", data=lung)
aalen
AalenAdditive (additive hazards, test='aalen')

               slope       coef   se(coef)       z        p
Intercept    0.00483   0.005448   0.004703   1.158    0.247
age        8.986e-05  0.0001263  6.903e-05   1.829   0.0674
sex        -0.003151  -0.003938   0.001222  -3.222  0.00127

n = 228, events = 165, event times used = 164

The formula interface combines the response and covariates in a single string:

aalen2 = gw.AalenAdditive().fit(
    "Surv(time, status == 2) ~ age + sex", data=lung
)
aalen2
AalenAdditive (additive hazards, test='aalen')

               slope       coef   se(coef)       z        p
Intercept    0.00483   0.005448   0.004703   1.158    0.247
age        8.986e-05  0.0001263  6.903e-05   1.829   0.0674
sex        -0.003151  -0.003938   0.001222  -3.222  0.00127

n = 228, events = 165, event times used = 164

predict()

Predict survival or cumulative hazard from the fitted Aalen additive model.

Usage

Source

predict(
    newdata=None,
    *,
    type="survival",
    times=None,
    format=None,
)

The cumulative hazard for a subject with covariates x at time t is

\hat{H}(t \mid x) = \hat{B}_0(t) + \sum_{j=1}^{p} \hat{B}_j(t)\,x_j

where \hat{B}_j(t) are the estimated cumulative regression coefficients. Survival follows as \hat{S}(t \mid x) = \exp(-\hat{H}(t \mid x)).

Because the additive hazard model can produce negative cumulative hazard increments for some covariate patterns, predicted cumulative hazards are clipped at zero.

Parameters

newdata: Any = None

Covariate values for prediction. A DataFrame, 2-D array, or None. When None, predictions are made for the training data subjects. A data frame may also hold other columns. The covariates are picked out by name and coded as they were at fit time, so the frame the model was fit on can be passed as is.

type: str = "survival"

Prediction type: "survival" (default) or "cumhaz".

times: Any = None

Query times at which to evaluate predictions. An array-like of positive floats. When None, the model’s fitted event times are used.

format: str | None = None
Output format: None (auto-detect), "pandas", "polars", or "pyarrow".

Returns

DataFrame
Columns time and subject_1, subject_2, etc., one row per query time.

Examples

import greenwood as gw

lung = gw.load_dataset("lung", backend="polars")
aalen = gw.AalenAdditive().fit("Surv(time, status) ~ age + sex", data=lung)

aalen.predict(lung[:3], times=[180, 365], format="polars")
shape: (2, 4)
timesubject_1subject_2subject_3
f64f64f64f64
180.00.6020050.6260210.676966
365.00.3001380.3208960.366818

to_frame()

Return the summary test table as a DataFrame.

Usage

Source

to_frame(
    *,
    format=None,
)

One row per term with the slope (weighted average of increments), its standard error, z-statistic, and p-value.

Parameters

format: str | None = None
Output format: None (default), "pandas", "polars", or "pyarrow".

Returns

DataFrame
Columns: term, slope, coef, se, z, p.