Title: | Models for Survival Analysis |
---|---|
Description: | Implementations of classical and machine learning models for survival analysis, including deep neural networks via 'keras' and 'tensorflow'. Each model includes a separated fit and predict interface with consistent prediction types for predicting risk, survival probabilities, or survival distributions with 'distr6' <https://CRAN.R-project.org/package=distr6>. Models are either implemented from 'Python' via 'reticulate' <https://CRAN.R-project.org/package=reticulate>, from code in GitHub packages, or novel implementations using 'Rcpp' <https://CRAN.R-project.org/package=Rcpp>. Novel machine learning survival models wil be included in the package in near-future updates. Neural networks are implemented from the 'Python' package 'pycox' <https://github.com/havakv/pycox> and are detailed by Kvamme et al. (2019) <https://jmlr.org/papers/v20/18-424.html>. The 'Akritas' estimator is defined in Akritas (1994) <doi:10.1214/aos/1176325630>. 'DNNSurv' is defined in Zhao and Feng (2020) <arXiv:1908.02337>. |
Authors: | Raphael Sonabend [aut, cre] , John Zobolas [aut] |
Maintainer: | Raphael Sonabend <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.1.19 |
Built: | 2024-10-29 05:03:28 UTC |
Source: | https://github.com/RaphaelS1/survivalmodels |
survivalmodels implements classical and machine learning models for survival analysis that either do not already exist in R or for more efficient implementations.
Maintainer: Raphael Sonabend [email protected] (ORCID)
Authors:
John Zobolas [email protected] (ORCID)
Useful links:
Report bugs at https://github.com/RaphaelS1/survivalmodels/issues
The Akritas survival estimator is a conditional nearest-neighbours approach to the more common Kaplan-Meier estimator. Common usage includes IPCW Survival models and measures, which do not assume that censoring is independent of the covariates.
akritas( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, ... )
akritas( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
... |
|
This implementation uses a fit/predict interface to allow estimation on unseen data after fitting on training data. This is achieved by fitting the empirical CDF on the training data and applying this to the new data.
An object inheriting from class akritas
.
Akritas, M. G. (1994). Nearest Neighbor Estimation of a Bivariate Distribution Under Random Censoring. Ann. Statist., 22(3), 1299–1327. doi:10.1214/aos/1176325630
if (requireNamespaces(c("distr6", "survival"))) { library(survival) akritas(Surv(time, status) ~ ., data = rats[1:10, ]) }
if (requireNamespaces(c("distr6", "survival"))) { library(survival) akritas(Surv(time, status) ~ ., data = rats[1:10, ]) }
Utility function to build a Keras MLP.
build_keras_net( n_in, n_out, nodes = c(32L, 32L), layer_pars = list(), activation = "linear", act_pars = list(), dropout = 0.1, batch_norm = TRUE, batch_pars = list() )
build_keras_net( n_in, n_out, nodes = c(32L, 32L), layer_pars = list(), activation = "linear", act_pars = list(), dropout = 0.1, batch_norm = TRUE, batch_pars = list() )
n_in |
|
n_out |
|
nodes |
|
layer_pars |
|
activation |
|
act_pars |
|
dropout |
|
batch_norm |
|
batch_pars |
|
This function is a helper for R users with less Python experience. Currently it is limited to simple MLPs and with identical layers. More advanced networks will require manual creation with keras.
if (requireNamespaces("keras")) { build_keras_net(4L, 2L) build_keras_net(n_in = 4L, n_out = 2L, nodes = c(32L, 64L, 32L), activation = "elu", dropout = 0.4) }
if (requireNamespaces("keras")) { build_keras_net(4L, 2L) build_keras_net(n_in = 4L, n_out = 2L, nodes = c(32L, 64L, 32L), activation = "elu", dropout = 0.4) }
Utility function to build an MLP with a choice of activation function and weight initialization with optional dropout and batch normalization.
build_pytorch_net( n_in, n_out, nodes = c(32, 32), activation = "relu", act_pars = list(), dropout = 0.1, bias = TRUE, batch_norm = TRUE, batch_pars = list(eps = 1e-05, momentum = 0.1, affine = TRUE), init = "uniform", init_pars = list() )
build_pytorch_net( n_in, n_out, nodes = c(32, 32), activation = "relu", act_pars = list(), dropout = 0.1, bias = TRUE, batch_norm = TRUE, batch_pars = list(eps = 1e-05, momentum = 0.1, affine = TRUE), init = "uniform", init_pars = list() )
n_in |
|
n_out |
|
nodes |
|
activation |
|
act_pars |
|
dropout |
|
bias |
|
batch_norm |
|
batch_pars |
|
init |
|
init_pars |
|
This function is a helper for R users with less Python experience. Currently it is limited to simple MLPs. More advanced networks will require manual creation with reticulate.
if (requireNamespaces("reticulate")) { build_pytorch_net(4L, 2L, nodes = c(32, 64, 32), activation = "selu") # pass parameters to activation and initializer functions build_pytorch_net(4L, 2L, activation = "elu", act_pars = list(alpha = 0.1), init = "kaiming_uniform", init_pars = list(mode = "fan_out")) }
if (requireNamespaces("reticulate")) { build_pytorch_net(4L, 2L, nodes = c(32, 64, 32), activation = "selu") # pass parameters to activation and initializer functions build_pytorch_net(4L, 2L, activation = "elu", act_pars = list(alpha = 0.1), init = "kaiming_uniform", init_pars = list(mode = "fan_out")) }
A thin wrapper around survival::concordance which essentially
just sets reverse = TRUE
.
cindex(risk, truth, ...)
cindex(risk, truth, ...)
risk |
( |
truth |
( |
... |
( |
if (!requireNamespace("survival", quietly = TRUE)) { set.seed(10) data <- simsurvdata(20) fit <- deepsurv(data = data[1:10, ]) p <- predict(fit, type = "risk", newdata = data[11:20, ]) concordance(risk = p, truth = data[11:20, "time"]) }
if (!requireNamespace("survival", quietly = TRUE)) { set.seed(10) data <- simsurvdata(20) fit <- deepsurv(data = data[1:10, ]) p <- predict(fit, type = "risk", newdata = data[11:20, ]) concordance(risk = p, truth = data[11:20, "time"]) }
Cox-Time fits a neural network based on the Cox PH with possibly time-dependent effects.
coxtime( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, standardize_time = FALSE, log_duration = FALSE, with_mean = TRUE, with_std = TRUE, activation = "relu", num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, shrink = 0, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
coxtime( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, standardize_time = FALSE, log_duration = FALSE, with_mean = TRUE, with_std = TRUE, activation = "relu", num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, shrink = 0, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
frac |
|
standardize_time |
|
log_duration |
|
with_mean |
|
with_std |
|
activation |
|
num_nodes , batch_norm , dropout
|
|
device |
|
shrink |
|
early_stopping , best_weights , min_delta , patience
|
|
batch_size |
|
epochs |
|
verbose |
|
num_workers |
|
shuffle |
|
... |
|
Implemented from the pycox
Python package via reticulate.
Calls pycox.models.Coxtime
.
An object inheriting from class coxtime
.
An object of class survivalmodel
.
Kvamme, H., Borgan, Ø., & Scheel, I. (2019). Time-to-event prediction with neural networks and Cox regression. Journal of Machine Learning Research, 20(129), 1–30.
## Not run: if (requireNamespaces("reticulate")) { # all defaults coxtime(data = simsurvdata(50)) # common parameters coxtime(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) } ## End(Not run)
## Not run: if (requireNamespaces("reticulate")) { # all defaults coxtime(data = simsurvdata(50)) # common parameters coxtime(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) } ## End(Not run)
DeepHit fits a neural network based on the PMF of a discrete Cox model. This is the single (non-competing) event implementation.
deephit( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, mod_alpha = 0.2, sigma = 0.1, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
deephit( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, mod_alpha = 0.2, sigma = 0.1, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
frac |
|
cuts |
|
cutpoints |
|
scheme |
|
cut_min |
|
activation |
|
custom_net |
|
num_nodes , batch_norm , dropout
|
|
device |
|
mod_alpha |
|
sigma |
|
early_stopping , best_weights , min_delta , patience
|
|
batch_size |
|
epochs |
|
verbose |
|
num_workers |
|
shuffle |
|
... |
|
Implemented from the pycox
Python package via reticulate.
Calls pycox.models.DeepHitSingle
.
An object inheriting from class deephit
.
An object of class survivalmodel
.
Changhee Lee, William R Zame, Jinsung Yoon, and Mihaela van der Schaar. Deephit: A deep learning approach to survival analysis with competing risks. In Thirty-Second AAAI Conference on Artificial Intelligence, 2018. http://medianetlab.ee.ucla.edu/papers/AAAI_2018_DeepHit
if (requireNamespaces("reticulate")) { # all defaults deephit(data = simsurvdata(50)) # common parameters deephit(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
if (requireNamespaces("reticulate")) { # all defaults deephit(data = simsurvdata(50)) # common parameters deephit(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
DeepSurv neural fits a neural network based on the partial likelihood from a Cox PH.
deepsurv( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, activation = "relu", num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
deepsurv( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, activation = "relu", num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
frac |
|
activation |
|
num_nodes , batch_norm , dropout
|
|
device |
|
early_stopping , best_weights , min_delta , patience
|
|
batch_size |
|
epochs |
|
verbose |
|
num_workers |
|
shuffle |
|
... |
|
Implemented from the pycox
Python package via reticulate.
Calls pycox.models.CoxPH
.
An object inheriting from class deepsurv
.
An object of class survivalmodel
.
Katzman, J. L., Shaham, U., Cloninger, A., Bates, J., Jiang, T., & Kluger, Y. (2018). DeepSurv: personalized treatment recommender system using a Cox proportional hazards deep neural network. BMC Medical Research Methodology, 18(1), 24. https://doi.org/10.1186/s12874-018-0482-1
if (requireNamespaces("reticulate")) { # all defaults deepsurv(data = simsurvdata(50)) # common parameters deepsurv(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
if (requireNamespaces("reticulate")) { # all defaults deepsurv(data = simsurvdata(50)) # common parameters deepsurv(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
DNNSurv neural fits a neural network based on pseudo-conditional survival probabilities.
dnnsurv( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, cutpoints = NULL, cuts = 5L, custom_model = NULL, loss_weights = NULL, weighted_metrics = NULL, optimizer = "adam", early_stopping = FALSE, min_delta = 0, patience = 0L, verbose = 0L, baseline = NULL, restore_best_weights = FALSE, batch_size = 32L, epochs = 10L, validation_split = 0, shuffle = TRUE, sample_weight = NULL, initial_epoch = 0L, steps_per_epoch = NULL, validation_steps = NULL, ... )
dnnsurv( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, cutpoints = NULL, cuts = 5L, custom_model = NULL, loss_weights = NULL, weighted_metrics = NULL, optimizer = "adam", early_stopping = FALSE, min_delta = 0, patience = 0L, verbose = 0L, baseline = NULL, restore_best_weights = FALSE, batch_size = 32L, epochs = 10L, validation_split = 0, shuffle = TRUE, sample_weight = NULL, initial_epoch = 0L, steps_per_epoch = NULL, validation_steps = NULL, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
cutpoints |
|
cuts |
|
custom_model |
|
loss_weights , weighted_metrics
|
|
optimizer |
|
early_stopping |
|
min_delta , patience , baseline , restore_best_weights
|
|
verbose |
|
batch_size , epochs , validation_split , shuffle , sample_weight , initial_epoch , steps_per_epoch , validation_steps
|
See keras::fit.keras.engine.training.Model. # nolint |
... |
|
Code for generating the conditional probabilities and pre-processing data is taken from https://github.com/lilizhaoUM/DNNSurv.
An object of class survivalmodel
.
Zhao, L., & Feng, D. (2020). DNNSurv: Deep Neural Networks for Survival Analysis Using Pseudo Values. https://arxiv.org/abs/1908.02337
if (requireNamespaces(c("keras", "pseudo"))) # all defaults dnnsurv(data = simsurvdata(10)) # setting common parameters dnnsurv(time_variable = "time", status_variable = "status", data = simsurvdata(10), early_stopping = TRUE, epochs = 100L, validation_split = 0.3) # custom model library(keras) cuts <- 10 df <- simsurvdata(50) # shape = features + cuts input <- layer_input(shape = c(3L + cuts), name = 'input') output <- input %>% layer_dense(units = 4L, use_bias = TRUE) %>% layer_dense(units = 1L, use_bias = TRUE ) %>% layer_activation(activation="sigmoid") model <- keras_model(input, output) class(model) dnnsurv(custom_model = model, time_variable = "time", status_variable = "status", data = df, cuts = cuts)
if (requireNamespaces(c("keras", "pseudo"))) # all defaults dnnsurv(data = simsurvdata(10)) # setting common parameters dnnsurv(time_variable = "time", status_variable = "status", data = simsurvdata(10), early_stopping = TRUE, epochs = 100L, validation_split = 0.3) # custom model library(keras) cuts <- 10 df <- simsurvdata(50) # shape = features + cuts input <- layer_input(shape = c(3L + cuts), name = 'input') output <- input %>% layer_dense(units = 4L, use_bias = TRUE) %>% layer_dense(units = 1L, use_bias = TRUE ) %>% layer_activation(activation="sigmoid") model <- keras_model(input, output) class(model) dnnsurv(custom_model = model, time_variable = "time", status_variable = "status", data = df, cuts = cuts)
Utility function to construct optimiser from keras, primarily for internal use.
get_keras_optimizer( optimizer = "adam", lr = 0.001, beta_1 = 0.9, beta_2 = 0.999, epsilon = 1e-07, decay = NULL, clipnorm = NULL, clipvalue = NULL, momentum = 0, nesterov = FALSE, rho = 0.95, global_clipnorm = NULL, use_ema = FALSE, ema_momentum = 0.99, ema_overwrite_frequency = NULL, jit_compile = TRUE, initial_accumultator_value = 0.1, amsgrad = FALSE, lr_power = -0.5, l1_regularization_strength = 0, l2_regularization_strength = 0, l2_shrinkage_regularization_strength = 0, beta = 0, centered = FALSE )
get_keras_optimizer( optimizer = "adam", lr = 0.001, beta_1 = 0.9, beta_2 = 0.999, epsilon = 1e-07, decay = NULL, clipnorm = NULL, clipvalue = NULL, momentum = 0, nesterov = FALSE, rho = 0.95, global_clipnorm = NULL, use_ema = FALSE, ema_momentum = 0.99, ema_overwrite_frequency = NULL, jit_compile = TRUE, initial_accumultator_value = 0.1, amsgrad = FALSE, lr_power = -0.5, l1_regularization_strength = 0, l2_regularization_strength = 0, l2_shrinkage_regularization_strength = 0, beta = 0, centered = FALSE )
optimizer |
|
lr |
|
beta_1 , beta_2
|
|
epsilon |
|
decay , clipnorm , clipvalue , global_clipnorm
|
|
momentum |
|
nesterov |
|
rho |
|
use_ema , jit_compile
|
|
ema_momentum , ema_overwrite_frequency
|
|
initial_accumultator_value |
|
amsgrad |
|
lr_power , l1_regularization_strength , l2_regularization_strength , l2_shrinkage_regularization_strength , beta
|
|
centered |
|
Implemented optimizers are
"adadelta"
keras::optimizer_adadelta
"adagrad"
keras::optimizer_adagrad
"adam"
keras::optimizer_adam
"adamax"
keras::optimizer_adamax
"ftrl"
keras::optimizer_ftrl
"nadam"
keras::optimizer_nadam
"rmsprop"
keras::optimizer_rmsprop
"sgd"
keras::optimizer_sgd
if (requireNamespaces("keras")) { get_keras_optimizer() get_keras_optimizer(optimizer = "adamax", decay = 0.1, lr = 0.01) }
if (requireNamespaces("keras")) { get_keras_optimizer() get_keras_optimizer(optimizer = "adamax", decay = 0.1, lr = 0.01) }
Helper function to return a class or constructed object for
pytorch activation function from torch.nn.modules.activation
.
get_pycox_activation( activation = "relu", construct = TRUE, alpha = 1, dim = NULL, lambd = 0.5, min_val = -1, max_val = 1, negative_slope = 0.01, num_parameters = 1L, init = 0.25, lower = 1/8, upper = 1/3, beta = 1, threshold = 20, value = 20 )
get_pycox_activation( activation = "relu", construct = TRUE, alpha = 1, dim = NULL, lambd = 0.5, min_val = -1, max_val = 1, negative_slope = 0.01, num_parameters = 1L, init = 0.25, lower = 1/8, upper = 1/3, beta = 1, threshold = 20, value = 20 )
activation |
|
construct |
|
alpha |
|
dim |
|
lambd |
|
min_val , max_val
|
|
negative_slope |
|
num_parameters |
|
init |
|
lower , upper
|
|
beta |
|
threshold |
|
value |
|
Implemented methods (with help pages) are
"celu"
reticulate::py_help(torch$nn$modules$activation$CELU)
"elu"
reticulate::py_help(torch$nn$modules$activation$ELU)
"gelu"
reticulate::py_help(torch$nn$modules$activation$GELU)
"glu"
reticulate::py_help(torch$nn$modules$activation$GLU)
"hardshrink"
reticulate::py_help(torch$nn$modules$activation$Hardshrink)
"hardsigmoid"
reticulate::py_help(torch$nn$modules$activation$Hardsigmoid)
"hardswish"
reticulate::py_help(torch$nn$modules$activation$Hardswish)
"hardtanh"
reticulate::py_help(torch$nn$modules$activation$Hardtanh)
"relu6"
reticulate::py_help(torch$nn$modules$activation$ReLU6)
"leakyrelu"
reticulate::py_help(torch$nn$modules$activation$LeakyReLU)
"logsigmoid"
reticulate::py_help(torch$nn$modules$activation$LogSigmoid)
"logsoftmax"
reticulate::py_help(torch$nn$modules$activation$LogSoftmax)
"prelu"
reticulate::py_help(torch$nn$modules$activation$PReLU)
"rrelu"
reticulate::py_help(torch$nn$modules$activation$RReLU)
"relu"
reticulate::py_help(torch$nn$modules$activation$ReLU)
"selu"
reticulate::py_help(torch$nn$modules$activation$SELU)
"sigmoid"
reticulate::py_help(torch$nn$modules$activation$Sigmoid)
"softmax"
reticulate::py_help(torch$nn$modules$activation$Softmax)
"softmax2d"
reticulate::py_help(torch$nn$modules$activation$Softmax2d)
"softmin"
reticulate::py_help(torch$nn$modules$activation$Softmin)
"softplus"
reticulate::py_help(torch$nn$modules$activation$Softplus)
"softshrink"
reticulate::py_help(torch$nn$modules$activation$Softshrink)
"softsign"
reticulate::py_help(torch$nn$modules$activation$Softsign)
"tanh"
reticulate::py_help(torch$nn$modules$activation$Tanh)
"tanhshrink"
reticulate::py_help(torch$nn$modules$activation$Tanhshrink)
"threshold"
reticulate::py_help(torch$nn$modules$activation$Threshold)
if (requireNamespaces("reticulate")) { #' # returns constructed objects get_pycox_activation(activation = "relu", construct = TRUE) # returns class get_pycox_activation(activation = "selu", construct = FALSE) }
if (requireNamespaces("reticulate")) { #' # returns constructed objects get_pycox_activation(activation = "relu", construct = TRUE) # returns class get_pycox_activation(activation = "selu", construct = FALSE) }
Helper function to return torchtuples callbacks from torchtuples.callbacks
.
get_pycox_callbacks( early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L )
get_pycox_callbacks( early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L )
early_stopping |
|
best_weights |
|
min_delta |
|
patience |
|
if (requireNamespaces("reticulate")) { get_pycox_callbacks(early_stopping = TRUE) get_pycox_callbacks(best_weights = TRUE) }
if (requireNamespaces("reticulate")) { get_pycox_callbacks(early_stopping = TRUE) get_pycox_callbacks(best_weights = TRUE) }
Helper function to return a character string with a populated pytorch weight
initializer method from torch.nn.init
. Used in build_pytorch_net to define a weighting
function.
get_pycox_init( init = "uniform", a = 0, b = 1, mean = 0, std = 1, val, gain = 1, mode = c("fan_in", "fan_out"), non_linearity = c("leaky_relu", "relu") )
get_pycox_init( init = "uniform", a = 0, b = 1, mean = 0, std = 1, val, gain = 1, mode = c("fan_in", "fan_out"), non_linearity = c("leaky_relu", "relu") )
init |
|
a |
|
b |
|
mean , std
|
|
val |
|
gain |
|
mode |
|
non_linearity |
|
Implemented methods (with help pages) are
"uniform"
reticulate::py_help(torch$nn$init$uniform_)
"normal"
reticulate::py_help(torch$nn$init$normal_)
"constant"
reticulate::py_help(torch$nn$init$constant_)
"xavier_uniform"
reticulate::py_help(torch$nn$init$xavier_uniform_)
"xavier_normal"
reticulate::py_help(torch$nn$init$xavier_normal_)
"kaiming_uniform"
reticulate::py_help(torch$nn$init$kaiming_uniform_)
"kaiming_normal"
reticulate::py_help(torch$nn$init$kaiming_normal_)
"orthogonal"
reticulate::py_help(torch$nn$init$orthogonal_)
if (requireNamespaces("reticulate")) { get_pycox_init(init = "uniform") get_pycox_init(init = "kaiming_uniform", a = 0, mode = "fan_out") }
if (requireNamespaces("reticulate")) { get_pycox_init(init = "uniform") get_pycox_init(init = "kaiming_uniform", a = 0, mode = "fan_out") }
Helper function to return a constructed pytorch optimizer from torch.optim
.
get_pycox_optim( optimizer = "adam", net, rho = 0.9, eps = 1e-08, lr = 1, weight_decay = 0, learning_rate = 0.01, lr_decay = 0, betas = c(0.9, 0.999), amsgrad = FALSE, lambd = 1e-04, alpha = 0.75, t0 = 1e+06, momentum = 0, centered = TRUE, etas = c(0.5, 1.2), step_sizes = c(1e-06, 50), dampening = 0, nesterov = FALSE )
get_pycox_optim( optimizer = "adam", net, rho = 0.9, eps = 1e-08, lr = 1, weight_decay = 0, learning_rate = 0.01, lr_decay = 0, betas = c(0.9, 0.999), amsgrad = FALSE, lambd = 1e-04, alpha = 0.75, t0 = 1e+06, momentum = 0, centered = TRUE, etas = c(0.5, 1.2), step_sizes = c(1e-06, 50), dampening = 0, nesterov = FALSE )
optimizer |
|
net |
|
rho , lr , lr_decay
|
|
eps |
|
weight_decay |
|
learning_rate |
|
betas |
|
amsgrad |
|
lambd , t0
|
|
alpha |
|
momentum |
|
centered |
|
etas , step_sizes
|
|
dampening |
|
nesterov |
|
Implemented methods (with help pages) are
"adadelta"
reticulate::py_help(torch$optim$Adadelta)
"adagrad"
reticulate::py_help(torch$optim$Adagrad)
"adam"
reticulate::py_help(torch$optim$Adam)
"adamax"
reticulate::py_help(torch$optim$Adamax)
"adamw"
reticulate::py_help(torch$optim$AdamW)
"asgd"
reticulate::py_help(torch$optim$ASGD)
"rmsprop"
reticulate::py_help(torch$optim$RMSprop)
"rprop"
reticulate::py_help(torch$optim$Rprop)
"sgd"
reticulate::py_help(torch$optim$SGD)
"sparse_adam"
reticulate::py_help(torch$optim$SparseAdam)
Stripped back version of keras::install_keras. Note the
default for pip
is changed to TRUE
.
install_keras( method = "auto", conda = "auto", pip = TRUE, install_tensorflow = FALSE, ... )
install_keras( method = "auto", conda = "auto", pip = TRUE, install_tensorflow = FALSE, ... )
method , conda , pip
|
|
install_tensorflow |
If |
... |
Passed to reticulate::py_install. |
Installs the python 'pycox' package via reticulate.
Note the default for pip
is changed to TRUE
.
install_pycox( method = "auto", conda = "auto", pip = TRUE, install_torch = FALSE, ... )
install_pycox( method = "auto", conda = "auto", pip = TRUE, install_torch = FALSE, ... )
method , conda , pip
|
|
install_torch |
If |
... |
Passed to reticulate::py_install. |
Installs the python 'torch' package via reticulate. Note the
default for pip
is changed to TRUE
.
install_torch(method = "auto", conda = "auto", pip = TRUE)
install_torch(method = "auto", conda = "auto", pip = TRUE)
method , conda , pip
|
Logistic-Hazard fits a discrete neural network based on a cross-entropy loss and predictions of a discrete hazard function, also known as Nnet-Survival.
loghaz( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
loghaz( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
frac |
|
cuts |
|
cutpoints |
|
scheme |
|
cut_min |
|
activation |
|
custom_net |
|
num_nodes , batch_norm , dropout
|
|
device |
|
early_stopping , best_weights , min_delta , patience
|
|
batch_size |
|
epochs |
|
verbose |
|
num_workers |
|
shuffle |
|
... |
|
Implemented from the pycox
Python package via reticulate.
Calls pycox.models.LogisticHazard
.
An object inheriting from class loghaz
.
An object of class survivalmodel
.
Gensheimer, M. F., & Narasimhan, B. (2018). A Simple Discrete-Time Survival Model for Neural Networks, 1–17. https://doi.org/arXiv:1805.00917v3
Kvamme, H., & Borgan, Ø. (2019). Continuous and discrete-time survival prediction with neural networks. https://doi.org/arXiv:1910.06724.
if (requireNamespaces("reticulate")) { # all defaults loghaz(data = simsurvdata(50)) # common parameters loghaz(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
if (requireNamespaces("reticulate")) { # all defaults loghaz(data = simsurvdata(50)) # common parameters loghaz(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
Fit/predict implementation of survival::survreg()
, which can return
absolutely continuous distribution predictions using distr6.
parametric( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, eps = 1e-15, ... )
parametric( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, eps = 1e-15, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
eps |
|
... |
|
An object inheriting from class parametric
.
if (requireNamespaces(c("distr6", "survival"))) { library(survival) parametric(Surv(time, status) ~ ., data = simsurvdata(10)) }
if (requireNamespaces(c("distr6", "survival"))) { library(survival) parametric(Surv(time, status) ~ ., data = simsurvdata(10)) }
Logistic-Hazard fits a discrete neural network based on a cross-entropy loss and predictions of a discrete hazard function, also known as Nnet-Survival.
pchazard( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, reduction = c("mean", "none", "sum"), dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
pchazard( formula = NULL, data = NULL, reverse = FALSE, time_variable = "time", status_variable = "status", x = NULL, y = NULL, frac = 0, cuts = 10, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0, activation = "relu", custom_net = NULL, num_nodes = c(32L, 32L), batch_norm = TRUE, reduction = c("mean", "none", "sum"), dropout = NULL, device = NULL, early_stopping = FALSE, best_weights = FALSE, min_delta = 0, patience = 10L, batch_size = 256L, epochs = 1L, verbose = FALSE, num_workers = 0L, shuffle = TRUE, ... )
formula |
|
data |
|
reverse |
|
time_variable |
|
status_variable |
|
x |
|
y |
|
frac |
|
cuts |
|
cutpoints |
|
scheme |
|
cut_min |
|
activation |
|
custom_net |
|
num_nodes , batch_norm , dropout
|
|
reduction |
|
device |
|
early_stopping , best_weights , min_delta , patience
|
|
batch_size |
|
epochs |
|
verbose |
|
num_workers |
|
shuffle |
|
... |
|
Implemented from the pycox
Python package via reticulate.
Calls pycox.models.PCHazard
.
An object inheriting from class pchazard
.
An object of class survivalmodel
.
Kvamme, H., & Borgan, Ø. (2019). Continuous and discrete-time survival prediction with neural networks. https://doi.org/arXiv:1910.06724.
if (requireNamespaces("reticulate")) { # all defaults pchazard(data = simsurvdata(50)) # common parameters pchazard(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
if (requireNamespaces("reticulate")) { # all defaults pchazard(data = simsurvdata(50)) # common parameters pchazard(data = simsurvdata(50), frac = 0.3, activation = "relu", num_nodes = c(4L, 8L, 4L, 2L), dropout = 0.1, early_stopping = TRUE, epochs = 100L, batch_size = 32L) }
Predicted values from a fitted Akritas estimator.
## S3 method for class 'akritas' predict( object, newdata, times = NULL, lambda = 0.5, type = c("survival", "risk", "all"), distr6 = FALSE, ntime = 150, round_time = 2, ... )
## S3 method for class 'akritas' predict( object, newdata, times = NULL, lambda = 0.5, type = c("survival", "risk", "all"), distr6 = FALSE, ntime = 150, round_time = 2, ... )
object |
( |
newdata |
|
times |
|
lambda |
( |
type |
( |
distr6 |
( |
ntime |
|
round_time |
|
... |
|
This implementation uses a fit/predict interface to allow estimation on unseen data after fitting on training data. This is achieved by fitting the empirical CDF on the training data and applying this to the new data.
A numeric
if type = "risk"
, a distr6::Matdist()
(if distr6 = TRUE
)
and type = "survival"
; a matrix
if (distr6 = FALSE
) and type = "survival"
where
entries are survival probabilities with rows of observations and columns are time-points;
or a list combining above if type = "all"
.
Akritas, M. G. (1994). Nearest Neighbor Estimation of a Bivariate Distribution Under Random Censoring. Ann. Statist., 22(3), 1299–1327. doi:10.1214/aos/1176325630
if (requireNamespaces(c("distr6", "survival"))) { library(survival) train <- 1:10 test <- 11:20 fit <- akritas(Surv(time, status) ~ ., data = rats[train, ]) predict(fit, newdata = rats[test, ]) # when lambda = 1, identical to Kaplan-Meier fit <- akritas(Surv(time, status) ~ ., data = rats[1:100, ]) predict_akritas <- predict(fit, newdata = rats[1:100, ], lambda = 1)[1, ] predict_km <- survfit(Surv(time, status) ~ 1, data = rats[1:100, ])$surv all(predict_akritas == predict_km) # Use distr6 = TRUE to return a distribution predict_distr <- predict(fit, newdata = rats[test, ], distr6 = TRUE) predict_distr$survival(100) # Return a relative risk ranking with type = "risk" predict(fit, newdata = rats[test, ], type = "risk") # Or survival probabilities and a rank predict(fit, newdata = rats[test, ], type = "all", distr6 = TRUE) }
if (requireNamespaces(c("distr6", "survival"))) { library(survival) train <- 1:10 test <- 11:20 fit <- akritas(Surv(time, status) ~ ., data = rats[train, ]) predict(fit, newdata = rats[test, ]) # when lambda = 1, identical to Kaplan-Meier fit <- akritas(Surv(time, status) ~ ., data = rats[1:100, ]) predict_akritas <- predict(fit, newdata = rats[1:100, ], lambda = 1)[1, ] predict_km <- survfit(Surv(time, status) ~ 1, data = rats[1:100, ])$surv all(predict_akritas == predict_km) # Use distr6 = TRUE to return a distribution predict_distr <- predict(fit, newdata = rats[test, ], distr6 = TRUE) predict_distr$survival(100) # Return a relative risk ranking with type = "risk" predict(fit, newdata = rats[test, ], type = "risk") # Or survival probabilities and a rank predict(fit, newdata = rats[test, ], type = "all", distr6 = TRUE) }
Predicted values from a fitted object of class dnnsurv.
## S3 method for class 'dnnsurv' predict( object, newdata, batch_size = 32L, verbose = 0L, steps = NULL, callbacks = NULL, type = c("survival", "risk", "all"), distr6 = FALSE, ... )
## S3 method for class 'dnnsurv' predict( object, newdata, batch_size = 32L, verbose = 0L, steps = NULL, callbacks = NULL, type = c("survival", "risk", "all"), distr6 = FALSE, ... )
object |
|
newdata |
|
batch_size |
|
verbose |
|
steps |
|
callbacks |
|
type |
( |
distr6 |
|
... |
|
A numeric
if type = "risk"
, a distr6::Matdist()
(if distr6 = TRUE
)
and type = "survival"
; a matrix
if (distr6 = FALSE
) and type = "survival"
where
entries are survival probabilities with rows of observations and columns are time-points;
or a list combining above if type = "all"
.
if (requireNamespaces(c("keras", "pseudo"))) fit <- dnnsurv(data = simsurvdata(10)) # predict survival matrix and relative risks predict(fit, simsurvdata(10), type = "all") # return as distribution if (requireNamespaces("distr6")) { predict(fit, simsurvdata(10), distr6 = TRUE) }
if (requireNamespaces(c("keras", "pseudo"))) fit <- dnnsurv(data = simsurvdata(10)) # predict survival matrix and relative risks predict(fit, simsurvdata(10), type = "all") # return as distribution if (requireNamespaces("distr6")) { predict(fit, simsurvdata(10), distr6 = TRUE) }
Predicted values from a fitted Parametric survival model.
## S3 method for class 'parametric' predict( object, newdata, form = c("aft", "ph", "tobit", "po"), times = NULL, type = c("survival", "risk", "all"), distr6 = FALSE, ntime = 150, round_time = 2, ... )
## S3 method for class 'parametric' predict( object, newdata, form = c("aft", "ph", "tobit", "po"), times = NULL, type = c("survival", "risk", "all"), distr6 = FALSE, ntime = 150, round_time = 2, ... )
object |
( |
newdata |
|
form |
|
times |
|
type |
( |
distr6 |
( |
ntime |
|
round_time |
|
... |
|
The form
parameter determines how the distribution is created.
Options are:
Accelerated failure time ("aft"
)
Proportional Hazards ("ph"
)
Tobit ("tobit"
)
Proportional odds ("po"
)
where are the estimated baseline hazard and survival functions
(in this case with a given parametric form),
is the predicted linear
predictor calculated using the formula
where
are the variables in the test data set and
are the coefficients from the fitted parametric survival model (
object
).
is the cdf of a N(0, 1) distribution, and
is the
fitted scale parameter.
A numeric
if type = "risk"
, a distr6::Distribution()
(if distr6 = TRUE
) and type = "survival"
; a matrix
if
(distr6 = FALSE
) and type = "survival"
where entries are survival
probabilities with rows of observations and columns are time-points;
or a list combining above if type = "all"
.
if (requireNamespaces(c("distr6", "survival"))) { library(survival) set.seed(42) train <- simsurvdata(10) test <- simsurvdata(5) fit <- parametric(Surv(time, status) ~ ., data = train) # Return a discrete distribution survival matrix predict_distr <- predict(fit, newdata = test) predict_distr # Return a relative risk ranking with type = "risk" predict(fit, newdata = test, type = "risk") # Or survival probabilities and a rank predict(fit, newdata = test, type = "all", distr6 = TRUE) }
if (requireNamespaces(c("distr6", "survival"))) { library(survival) set.seed(42) train <- simsurvdata(10) test <- simsurvdata(5) fit <- parametric(Surv(time, status) ~ ., data = train) # Return a discrete distribution survival matrix predict_distr <- predict(fit, newdata = test) predict_distr # Return a relative risk ranking with type = "risk" predict(fit, newdata = test, type = "risk") # Or survival probabilities and a rank predict(fit, newdata = test, type = "all", distr6 = TRUE) }
Predicted values from a fitted pycox ANN.
## S3 method for class 'pycox' predict( object, newdata, batch_size = 256L, num_workers = 0L, interpolate = FALSE, inter_scheme = c("const_hazard", "const_pdf"), sub = 10L, type = c("survival", "risk", "all"), distr6 = FALSE, ... )
## S3 method for class 'pycox' predict( object, newdata, batch_size = 256L, num_workers = 0L, interpolate = FALSE, inter_scheme = c("const_hazard", "const_pdf"), sub = 10L, type = c("survival", "risk", "all"), distr6 = FALSE, ... )
object |
|
newdata |
|
batch_size |
|
num_workers |
|
interpolate |
|
inter_scheme |
|
sub |
|
type |
( |
distr6 |
|
... |
|
A numeric
if type = "risk"
, a distr6::Matdist()
(if distr6 = TRUE
)
and type = "survival"
; a matrix
if (distr6 = FALSE
) and type = "survival"
where
entries are survival probabilities with rows of observations and columns are time-points;
or a list combining above if type = "all"
.
## Not run: if (requireNamespaces("reticulate")) { fit <- coxtime(data = simsurvdata(50)) # predict survival matrix and relative risks predict(fit, simsurvdata(10), type = "all") # return as distribution if (requireNamespaces("distr6")) { predict(fit, simsurvdata(10), distr6 = TRUE) } } ## End(Not run)
## Not run: if (requireNamespaces("reticulate")) { fit <- coxtime(data = simsurvdata(50)) # predict survival matrix and relative risks predict(fit, simsurvdata(10), type = "all") # return as distribution if (requireNamespaces("distr6")) { predict(fit, simsurvdata(10), distr6 = TRUE) } } ## End(Not run)
Utility function to prepare data for training in a Pycox model. Generally used internally only.
pycox_prepare_train_data( x_train, y_train, frac = 0, standardize_time = FALSE, log_duration = FALSE, with_mean = TRUE, with_std = TRUE, discretise = FALSE, cuts = 10L, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0L, model = c("coxtime", "deepsurv", "deephit", "loghaz", "pchazard") )
pycox_prepare_train_data( x_train, y_train, frac = 0, standardize_time = FALSE, log_duration = FALSE, with_mean = TRUE, with_std = TRUE, discretise = FALSE, cuts = 10L, cutpoints = NULL, scheme = c("equidistant", "quantiles"), cut_min = 0L, model = c("coxtime", "deepsurv", "deephit", "loghaz", "pchazard") )
x_train |
|
y_train |
|
frac |
|
standardize_time |
|
log_duration |
|
with_mean |
|
with_std |
|
discretise |
|
cuts |
|
cutpoints |
|
scheme |
|
cut_min |
|
model |
|
Helper function for internal use. Vectorises the requireNamespace function and
returns TRUE
if all packages, x
, are available and FALSE
otherwise.
requireNamespaces(x)
requireNamespaces(x)
x |
|
To ensure consistent results, a seed has to be set in R using set.seed as usual but also in numpy and torch via reticulate. Therefore this function simplifies the process into one funciton.
set_seed(seed_R, seed_np = seed_R, seed_torch = seed_R)
set_seed(seed_R, seed_np = seed_R, seed_torch = seed_R)
seed_R |
( |
seed_np |
( |
seed_torch |
( |
Function for simulating survival data.
simsurvdata(n = 100, trt = 2, age = 2, sex = 1.5, cens = 0.3)
simsurvdata(n = 100, trt = 2, age = 2, sex = 1.5, cens = 0.3)
n |
|
trt , age , sex
|
|
cens |
|
Currently limited to three covariates, Weibull survival times, and Type I censoring. This will be expanded to a flexible simulation function in future updates. For now the function is primarily limited to helping function examples.
simsurvdata()
simsurvdata()
Many methods can be used to reduce a discrete survival distribution prediction (i.e. matrix) to a relative risk / ranking prediction. Here we define the predicted relative risk as the sum of the predicted cumulative hazard function - which can be loosely interpreted as the expected number of deaths for patients with similar characteristics.
surv_to_risk(x)
surv_to_risk(x)
x |
( |
Sonabend, R., Bender, A., & Vollmer, S. (2021). Evaluation of survival distribution predictions with discrimination measures. http://arxiv.org/abs/2112.04828.