def predict_pmf(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Predict the probability mass function (PMF) for `input`. Arguments: input {tuple, np.ndarray, or torch.tensor} -- Input to net. Keyword Arguments: batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) eval_ {bool} -- If 'True', use 'eval' mode on net. (default: {True}) grads {bool} -- If gradients should be computed (default: {False}) to_cpu {bool} -- For larger data sets we need to move the results to cpu (default: {False}) num_workers {int} -- Number of workers in created dataloader (default: {0}) Returns: [np.ndarray or tensor] -- Predictions """ preds = self.predict(input, batch_size, False, eval_, False, to_cpu, num_workers) pmf = pad_col(preds).softmax(1)[:, :-1] return array_or_tensor(pmf, numpy, input)
def _hazard_const_haz(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Computes the continuous-time constant hazard interpolation. Essentially we what the discrete survival estimates to match the continuous time at the knots. So essentially we want $$S(tau_j) = prod_{k=1}^j [1 - h_k] = prod_{k=1}{j} exp[-eta_k].$$ where $h_k$ is the discrete hazard estimates and $eta_k$ continuous time hazards multiplied with the length of the duration interval as they are defined for the PC-Hazard method. Thus we get $$eta_k = - log[1 - h_k]$$ which can be divided by the length of the time interval to get the continuous time hazards. """ haz_orig = self.model.predict_hazard(input, batch_size, False, eval_, to_cpu, num_workers) haz = (1 - haz_orig).add( self.epsilon).log().mul(-1).relu()[:, 1:].contiguous() n = haz.shape[0] haz = haz.view(-1, 1).repeat(1, self.sub).view(n, -1).div(self.sub) haz = utils.pad_col(haz, where='start') haz[:, 0] = haz_orig[:, 0] return utils.array_or_tensor(haz, numpy, input)
def predict_surv(self, input, max_duration=None, batch_size=8224, numpy=None, verbose=False, baseline_hazards_=None, eval_=True, num_workers=0): """Predict survival function for `input`. S(x, t) = exp(-H(x, t)) Require compueted baseline hazards. Arguments: input {np.array, tensor or tuple} -- Input x passed to net. Keyword Arguments: max_duration {float} -- Don't compute estimates for duration higher (default: {None}) batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) baseline_hazards_ {pd.Series} -- Baseline hazards. If `None` used `model.baseline_hazards_` (default: {None}) eval_ {bool} -- If 'True', use 'eval' mode on net. (default: {True}) num_workers {int} -- Number of workers in created dataloader (default: {0}) Returns: pd.DataFrame -- Survival estimates. One columns for each individual. """ surv = self.predict_surv_df(input, max_duration, batch_size, verbose, baseline_hazards_, eval_, num_workers) surv = torch.from_numpy(surv.values.transpose()) return array_or_tensor(surv, numpy, input)
def predict_hazard(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Predict the hazard function for `input`. Arguments: input {tuple, np.ndarra, or torch.tensor} -- Input to net. Keyword Arguments: batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) eval_ {bool} -- If 'True', use 'eval' mode on net. (default: {True}) to_cpu {bool} -- For larger data sets we need to move the results to cpu (default: {False}) num_workers {int} -- Number of workers in created dataloader (default: {0}) Returns: [np.ndarray or tensor] -- Predicted hazards """ preds = self.predict(input, batch_size, False, eval_, False, to_cpu, num_workers) n = preds.shape[0] hazard = F.softplus(preds).view(-1, 1).repeat(1, self.sub).view( n, -1).div(self.sub) hazard = pad_col(hazard, where='start') return array_or_tensor(hazard, numpy, input)
def predict_surv(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): pmf = self.predict_pmf(input, batch_size, False, eval_, to_cpu, num_workers) surv = 1 - pmf.cumsum(1) return array_or_tensor(surv, numpy, input)
def predict_surv(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): hazard = self.predict_hazard(input, batch_size, False, eval_, to_cpu, num_workers) surv = hazard.cumsum(1).mul(-1).exp() return array_or_tensor(surv, numpy, input)
def predict_pmf(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): preds = self.predict(input, batch_size, False, eval_, False, to_cpu, num_workers) preds = utils.cumsum_reverse(preds, dim=1) pmf = utils.pad_col(preds).softmax(1)[:, :-1] return utils.array_or_tensor(pmf, numpy, input)
def _surv_const_haz(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): haz = self._hazard_const_haz(input, batch_size, False, eval_, to_cpu, num_workers) surv_0 = 1 - haz[:, :1] surv = utils.pad_col(haz[:, 1:], where='start').cumsum(1).mul(-1).exp().mul(surv_0) return utils.array_or_tensor(surv, numpy, input)
def predict_pmf(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): if not self.scheme in ['const_pdf', 'lin_surv']: raise NotImplementedError pmf = self.model.predict_pmf(input, batch_size, False, eval_, to_cpu, num_workers) n, m = pmf.shape pmf_cdi = pmf[:, 1:].contiguous().view(-1, 1).repeat(1, self.sub).div( self.sub).view(n, -1) pmf_cdi = utils.pad_col(pmf_cdi, where='start') pmf_cdi[:, 0] = pmf[:, 0] return utils.array_or_tensor(pmf_cdi, numpy, input)
def _surv_const_pdf(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Basic method for constant PDF interpolation that use `self.model.predict_surv`. Arguments: input {tuple, np.ndarray, or torch.tensor} -- Input to net. Keyword Arguments: batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) eval_ {bool} -- If 'True', use 'eval' mode on net. (default: {True}) to_cpu {bool} -- For larger data sets we need to move the results to cpu (default: {False}) num_workers {int} -- Number of workers in created dataloader (default: {0}) Returns: [np.ndarray or tensor] -- Predictions """ s = self.model.predict_surv(input, batch_size, False, eval_, to_cpu, num_workers) n, m = s.shape device = s.device diff = (s[:, 1:] - s[:, :-1]).contiguous().view(-1, 1).repeat( 1, self.sub).view(n, -1) rho = torch.linspace(0, 1, self.sub + 1, device=device)[:-1].contiguous().repeat(n, m - 1) s_prev = s[:, :-1].contiguous().view(-1, 1).repeat(1, self.sub).view(n, -1) surv = torch.zeros(n, int((m - 1) * self.sub + 1)) surv[:, :-1] = diff * rho + s_prev surv[:, -1] = s[:, -1] return utils.array_or_tensor(surv, numpy, input)
def predict_cif(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Predict the cumulative incidence function (cif) for `input`. Arguments: input {tuple, np.ndarray, or torch.tensor} -- Input to net. Keyword Arguments: batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) eval_ {bool} -- If 'True', use 'eval' mode on net. (default: {True}) to_cpu {bool} -- For larger data sets we need to move the results to cpu (default: {False}) num_workers {int} -- Number of workers in created dataloader (default: {0}) Returns: [np.ndarray or tensor] -- Predictions """ pmf = self.predict_pmf(input, batch_size, False, eval_, to_cpu, num_workers) cif = pmf.cumsum(1) return array_or_tensor(cif, numpy, input)
def predict_surv(self, input, batch_size=8224, numpy=None, eval_=True, to_cpu=False, num_workers=0): """Predict the survival function for `input`, i.e., survive all of the event types. See `prediction_surv_df` to return a DataFrame instead. Arguments: input {tuple, np.ndarra, or torch.tensor} -- Input to net. Keyword Arguments: batch_size {int} -- Batch size (default: {8224}) numpy {bool} -- 'False' gives tensor, 'True' gives numpy, and None give same as input (default: {None}) eval_ {bool} -- If 'True', use 'eval' modede on net. (default: {True}) to_cpu {bool} -- For larger data sets we need to move the results to cpu (default: {False}) num_workers {int} -- Number of workes in created dataloader (default: {0}) Returns: [TupleTree, np.ndarray or tensor] -- Predictions """ cif = self.predict_cif(input, batch_size, False, eval_, to_cpu, num_workers) surv = 1. - cif.sum(0) return array_or_tensor(surv, numpy, input)