Buckley-James rank-based accelerated failure time regression.
BuckleyJames(
*,
max_iter=200,
tol=1e-06,
n_boot=None,
seed=None,
conf_level=0.95,
)
Fits \log(T) = X\beta + \varepsilon without assuming a distribution for \varepsilon, by alternating Kaplan-Meier-based imputation of censored log-times with ordinary least squares refitting until \beta stabilizes. This is a semiparametric alternative to AFT: it avoids committing to a parametric error distribution, at the cost of an iterative fit, occasional slow or oscillating convergence, and no closed-form standard errors (available here only via optional bootstrap resampling, n_boot=).
When there is no censoring at all, every residual is exact and the algorithm converges in a single step to the ordinary least squares fit of \log(T) on X.
Parameters
max_iter: int = 200
-
Maximum number of Buckley-James iterations (default 200).
tol: float = 1e-06
-
Convergence tolerance on the largest change in any coefficient between iterations (default 1e-6).
n_boot: int | None = None
-
Number of bootstrap resamples for standard errors and confidence intervals. If None (the default), std_error_, conf_low_, and conf_high_ are nan (Buckley-James has no closed-form variance).
seed: int | None = None
-
Random seed for bootstrap resampling (ignored if n_boot is None).
conf_level: float = 0.95
-
Confidence level for bootstrap coefficient intervals (default
0.95).
Returns
Fitted estimator
-
Call fit() to produce a fitted estimator with cached results (
coef_, std_error_, z_, p_value_, conf_low_, conf_high_, n_iter_, converged_, loglik_-free since there is no likelihood), accessible as arrays or exported to DataFrames.
Details
Call fit(surv, covariates) with a right-censored Surv response and a covariate design (a 2-D array, a dataframe, or a formula string with data). An intercept is added automatically.
Examples
import greenwood as gw
# Load the data
lung = gw.load_dataset("lung", backend="polars")
# Fit a Buckley-James model
bj = gw.BuckleyJames().fit("Surv(time, status) ~ age + sex", data=lung)
bj
BuckleyJames (rank-based accelerated failure time regression)
coef se(coef) z p
(Intercept) 6.379 NA NA NA
age -0.02306 NA NA NA
sex 0.4912 NA NA NA
n = 228, events = 165
iterations = 13, converged = True
Methods
|
Name
|
Description
|
|
fit()
|
Fit the Buckley-James model to survival data.
|
|
predict()
|
Predict the linear predictor or survival probabilities from the fitted model.
|
|
to_frame()
|
Return the coefficient table as a DataFrame.
|
fit()
Fit the Buckley-James model to survival data.
fit(
surv,
covariates=None,
*,
data=None,
)
Parameters
surv: Surv | Outcome | str
-
A right-censored Surv response, built with gw.Surv(time=..., event=...). 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), a 2-D array, or a formula string (e.g., "age + sex") evaluated against the data argument. 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
BuckleyJames
-
The fitted estimator itself (for method chaining) with cached coefficient arrays (
coef_, std_error_, z_, p_value_) and convergence diagnostics (n_iter_, converged_).
Examples
import greenwood as gw
lung = gw.load_dataset("lung", backend="polars")
bj = gw.BuckleyJames().fit("Surv(time, status) ~ age + sex", data=lung)
bj
BuckleyJames (rank-based accelerated failure time regression)
coef se(coef) z p
(Intercept) 6.379 NA NA NA
age -0.02306 NA NA NA
sex 0.4912 NA NA NA
n = 228, events = 165
iterations = 13, converged = True
predict()
Predict the linear predictor or survival probabilities from the fitted model.
predict(
newdata=None,
*,
type="survival",
times=None,
format=None,
)
Parameters
newdata: Any = None
-
Covariate values for prediction. A DataFrame (Pandas or Polars), 2-D array, or None (the default, uses the training data). 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"
-
"survival" (default): survival probabilities S(t \mid x) at times, evaluated by shifting the fitted residual Kaplan-Meier curve by each subject’s linear predictor. "lp": the linear predictor X\beta (log-time location) only; returns an array.
times: Any = None
-
Query times for type="survival" (ignored for "lp"). Required for "survival".
format: str | None = None
-
Output format for
type="survival": None (auto-detect), "pandas", "polars", or "pyarrow". Ignored for type="lp" (which always returns an array).
Returns
ndarray or DataFrame
-
An array of shape
(n_subjects,) for type="lp". A DataFrame with a time column and one column per subject for type="survival".
Details
Because Buckley-James makes no distributional assumption, survival predictions reuse the empirical Kaplan-Meier curve of the fitted residuals rather than a closed-form survival function: S(t \mid x) = \hat{S}_{\text{resid}}(\log t - x^\top\hat\beta). This curve is only as reliable as the residual sample size and is not smooth like AFT’s or RoystonParmar’s predictions.
Examples
import greenwood as gw
lung = gw.load_dataset("lung", backend="polars")
bj = gw.BuckleyJames().fit("Surv(time, status) ~ age + sex", data=lung)
bj.predict(lung[:2], type="survival", times=[180, 365, 730],
format="polars")
shape: (3, 3)| time | subject_1 | subject_2 |
|---|
| f64 | f64 | f64 |
| 180.0 | 0.540495 | 0.604915 |
| 365.0 | 0.240099 | 0.278609 |
| 730.0 | 0.026538 | 0.059712 |
to_frame()
Return the coefficient table as a DataFrame.
to_frame(
*,
format=None,
)
Exports one row per term, including the intercept. std_error, p_value, conf_low, and conf_high are nan unless the model was fit with n_boot=.
Parameters
format: str | None = None
-
Output format:
None (default), "pandas", "polars", or "pyarrow".
Returns
pandas.DataFrame, polars.DataFrame, or pyarrow.Table
-
A tidy table with columns
term, estimate, std_error, statistic, p_value, conf_low, and conf_high.
Examples
import greenwood as gw
lung = gw.load_dataset("lung", backend="polars")
bj = gw.BuckleyJames(n_boot=200, seed=0).fit("Surv(time, status) ~ age + sex", data=lung)
bj.to_frame(format="polars")
shape: (3, 7)| term | estimate | std_error | statistic | p_value | conf_low | conf_high |
|---|
| str | f64 | f64 | f64 | f64 | f64 | f64 |
| "(Intercept)" | 6.379093 | 0.562108 | 11.348514 | 7.5433e-30 | 5.277381 | 7.480805 |
| "age" | -0.023064 | 0.009091 | -2.537153 | 0.011176 | -0.040881 | -0.005247 |
| "sex" | 0.491199 | 0.150234 | 3.269557 | 0.001077 | 0.196746 | 0.785653 |