| Crates.io | cox-hazards |
| lib.rs | cox-hazards |
| version | 0.2.1 |
| created_at | 2025-08-27 16:40:18.323067+00 |
| updated_at | 2025-09-09 23:50:32.531268+00 |
| description | A Rust library for Cox proportional hazards regression with elastic net regularization |
| homepage | |
| repository | https://github.com/ethqnol/cox-hazards |
| max_upload_size | |
| id | 1812936 |
| size | 165,062 |
A comprehensive, well-tested Rust library for Cox proportional hazards regression with elastic net regularization. This crate provides robust survival analysis capabilities with modern optimization techniques.
Add this to your Cargo.toml:
[dependencies]
cox-hazards = "0.2.0"
use cox_hazards::{CoxModel, SurvivalData};
use ndarray::Array2;
// Create survival data
let times = vec![1.0, 2.5, 3.2, 4.1, 5.8];
let events = vec![true, false, true, true, false]; // true = event, false = censored
let covariates = Array2::from_shape_vec((5, 2), vec![
1.0, 0.5, // Patient 1: age=1.0, treatment=0.5
2.0, 1.0, // Patient 2: age=2.0, treatment=1.0
1.5, 0.0, // Patient 3: age=1.5, treatment=0.0
3.0, 1.5, // Patient 4: age=3.0, treatment=1.5
2.5, 0.8, // Patient 5: age=2.5, treatment=0.8
]).unwrap();
let data = SurvivalData::new(times, events, covariates)?;
// Fit Cox model
let mut model = CoxModel::new();
model.fit(&data)?;
// Make predictions
let risk_scores = model.predict(data.covariates())?;
let hazard_ratios = model.predict_hazard_ratios(data.covariates())?;
println!("Risk scores: {:?}", risk_scores);
println!("Hazard ratios: {:?}", hazard_ratios);
use cox_hazards::CoxModel;
// Ridge regression (L2 regularization)
let mut ridge_model = CoxModel::new()
.with_l2_penalty(0.1);
// Lasso regression (L1 regularization)
let mut lasso_model = CoxModel::new()
.with_l1_penalty(0.1);
// Elastic net (combination of L1 and L2)
let mut elastic_model = CoxModel::new()
.with_elastic_net(0.5, 0.2); // 50% L1, 50% L2, total penalty = 0.2
// Fit models
ridge_model.fit(&data)?;
lasso_model.fit(&data)?;
elastic_model.fit(&data)?;
use cox_hazards::{CoxModel, OptimizerType};
// Use Adam optimizer for large datasets or noisy gradients
let mut adam_model = CoxModel::new()
.with_optimizer(OptimizerType::Adam)
.with_learning_rate(0.1)
.with_adam_params(0.9, 0.999) // beta1, beta2
.with_l2_penalty(0.01);
adam_model.fit(&data)?;
// Use RMSprop optimizer for stable convergence
let mut rmsprop_model = CoxModel::new()
.with_optimizer(OptimizerType::RMSprop)
.with_learning_rate(0.1)
.with_adam_params(0.9, 0.9) // beta1 (unused), beta2 (decay rate)
.with_elastic_net(0.5, 0.1);
rmsprop_model.fit(&data)?;
// Both optimizers work well with regularization
let mut regularized_adam = CoxModel::new()
.with_optimizer(OptimizerType::Adam)
.with_elastic_net(0.5, 0.1)
.with_learning_rate(0.05)
.with_max_iterations(1000);
use cox_hazards::metrics::ModelMetrics;
// Compute comprehensive metrics
let risk_scores = model.predict(data.covariates())?;
let metrics = ModelMetrics::compute(&data, risk_scores.view(), data.n_features())?;
println!("C-index: {:.4}", metrics.c_index);
println!("Harrell's C-index: {:.4}", metrics.harrell_c_index);
println!("Log-likelihood: {:.4}", metrics.log_likelihood);
println!("AIC: {:.4}", metrics.aic);
println!("BIC: {:.4}", metrics.bic);
// Model with feature names and custom parameters
let feature_names = vec!["Age".to_string(), "Treatment".to_string()];
let mut advanced_model = CoxModel::new()
.with_feature_names(feature_names)
.with_elastic_net(0.3, 0.1)
.with_max_iterations(1000)
.with_tolerance(1e-6);
advanced_model.fit(&data)?;
// Get model summary
let summary = advanced_model.summary()?;
summary.print();
// Feature importance
let importance = advanced_model.feature_importance()?;
println!("Feature importance: {:?}", importance);
// Survival probability predictions
use ndarray::Array1;
let time_points = Array1::from(vec![1.0, 2.0, 3.0, 5.0]);
let survival_probs = advanced_model.predict_survival(
data.covariates(),
time_points.view()
)?;
SurvivalData: Container for survival times, event indicators, and covariatesCoxModel: Main Cox regression model with configurable regularizationModelMetrics: Comprehensive evaluation metrics for survival modelsnew(times, events, covariates): Create survival datasetstandardize_covariates(): Standardize feature matrixsubset(indices): Create subset of the datanew(): Create new model instancewith_l1_penalty(penalty): Set Lasso regularizationwith_l2_penalty(penalty): Set Ridge regularizationwith_elastic_net(alpha, penalty): Set elastic net parameterswith_optimizer(optimizer_type): Choose optimization algorithmwith_learning_rate(rate): Set Adam learning ratewith_adam_params(beta1, beta2): Configure Adam/RMSprop parametersfit(data): Train the modelpredict(covariates): Get risk scorespredict_hazard_ratios(covariates): Get hazard ratiospredict_survival(covariates, times): Get survival probabilitiesconcordance_index(): Standard C-indexharrell_c_index(): Harrell's C-index with tie handlinglog_partial_likelihood(): Model log-likelihoodModelMetrics::compute(): All metrics at onceThe examples/ directory contains comprehensive examples:
basic_usage.rs: Introduction to all major featurescross_validation.rs: Cross-validation and hyperparameter tuningrmsprop_example.rs: RMSprop optimizer usage and comparison with AdamRun examples with:
cargo run --example basic_usage
cargo run --example cross_validation
cargo run --example rmsprop_example
This implementation follows the standard Cox proportional hazards model:
Hazard Function:
h(t|x) = h₀(t) × exp(β'x)
Partial Likelihood:
L(β) = ∏ᵢ [exp(β'xᵢ) / Σⱼ∈R(tᵢ) exp(β'xⱼ)]^δᵢ
Elastic Net Penalty:
P(β) = λ₁||β||₁ + λ₂||β||₂²
Where:
h₀(t) is the baseline hazardβ are the regression coefficientsx are the covariatesδ are the event indicatorsR(t) is the risk set at time tλ₁, λ₂ are the regularization parametersThe library is optimized for performance with:
ndarrayrayonRun benchmarks with:
cargo bench
Comprehensive test coverage including:
proptestRun tests with:
cargo test
default: Includes parallel processingparallel: Enable parallel computations with Rayonno_std environments (without std feature)Contributions are welcome! Please:
If you use this library in academic work, please cite:
@software{cox_hazards_rust,
title = {cox-hazards: Cox Proportional Hazards Regression in Rust},
author = {Ethan Wu},
year = {2024},
url = {https://github.com/ethqnol/cox-hazards},
}
This project is licensed under the MIT License - see the LICENSE file for details.
survival package and Python's lifelinesndarray for efficient numerical computingargmin framework