Ejemplo n.º 1
0
 def fit(self, X, y, column_names):
     # format data
     self.column_names = column_names
     full_df = self._format_to_pycox(X, y, self.column_names)
     val_df = full_df.sample(frac=0.2)
     train_df = full_df.drop(val_df.index)
     train_x, train_y = self._standardize_df(train_df, "train")
     val_x, val_y = self._standardize_df(val_df, "val")
     # configure model
     self.in_features = train_x.shape[1]
     self.out_features = self.labtrans.out_features
     net = tt.practical.MLPVanilla(
         in_features=self.in_features,
         num_nodes=self.num_nodes,
         out_features=self.out_features,
         batch_norm=self.batch_norm,
         dropout=self.dropout,
         activation=self.activation,
         output_bias=self.output_bias,
         w_init_=lambda w: torch.nn.init.xavier_normal_(w))
     self.model = DeepHitSingle(net, tt.optim.Adam(lr=self.lr, weight_decay=self.weight_decay), \
                               alpha=self.alpha, sigma=self.sigma, duration_index=self.labtrans.cuts)
     n_train = train_x.shape[0]
     while n_train % self.batch_size == 1:  # this will cause issues in batch norm
         self.batch_size += 1
     self.model.fit(train_x,
                    train_y,
                    self.batch_size,
                    self.epochs,
                    self.callbacks,
                    verbose=True,
                    val_data=(val_x, val_y),
                    val_batch_size=self.batch_size,
                    num_workers=self.num_workers)
Ejemplo n.º 2
0
    def _model_factory(self,
                       n_trees=None,
                       n_input_features=None,
                       n_neurons=None):
        if self.algorithm == 'CPH':
            return CoxPHFitter()
        elif self.algorithm == 'RSF':
            return RandomSurvivalForestModel(num_trees=n_trees)
        elif self.algorithm in self._pycox_methods:
            net_args = {
                'in_features': n_input_features,
                'num_nodes': n_neurons,
                'batch_norm': True,
                'dropout': 0.1,
            }

            if self.algorithm == 'DeepSurv':
                net = tt.practical.MLPVanilla(out_features=1,
                                              output_bias=False,
                                              **net_args)
                model = CoxPH(net, tt.optim.Adam)

                return model
            if self.algorithm == 'CoxTime':
                net = MLPVanillaCoxTime(**net_args)
                model = CoxTime(net, tt.optim.Adam)

                return model
            if self.algorithm in self._discrete_time_methods:
                num_durations = 30
                print(f'   {num_durations} equidistant intervals')
            if self.algorithm == 'DeepHit':
                labtrans = DeepHitSingle.label_transform(num_durations)
                net = self._get_discrete_time_net(labtrans, net_args)
                model = DeepHitSingle(net,
                                      tt.optim.Adam,
                                      alpha=0.2,
                                      sigma=0.1,
                                      duration_index=labtrans.cuts)

                return model
            if self.algorithm == 'MTLR':
                labtrans = MTLR.label_transform(num_durations)
                net = self._get_discrete_time_net(labtrans, net_args)
                model = MTLR(net, tt.optim.Adam, duration_index=labtrans.cuts)

                return model
            if self.algorithm == 'Nnet-survival':
                labtrans = LogisticHazard.label_transform(num_durations)
                net = self._get_discrete_time_net(labtrans, net_args)
                model = LogisticHazard(net,
                                       tt.optim.Adam(0.01),
                                       duration_index=labtrans.cuts)

                return model
        else:
            raise Exception('Unrecognized model.')
Ejemplo n.º 3
0
def test_deep_hit_single_runs(numpy, num_durations):
    data = make_dataset(True)
    input, target = data
    labtrans = DeepHitSingle.label_transform(num_durations)
    target = labtrans.fit_transform(*target)
    data = tt.tuplefy(input, target)
    if not numpy:
        data = data.to_tensor()
    net = tt.practical.MLPVanilla(input.shape[1], [4], labtrans.out_features)
    model = DeepHitSingle(net)
    fit_model(data, model)
    assert_survs(input, model)
    model.duration_index = labtrans.cuts
    assert_survs(input, model)
    cdi = model.interpolate(3, 'const_pdf')
    assert_survs(input, cdi)
Ejemplo n.º 4
0
    def __init__(self, nodes_per_layer, layers, dropout, weight_decay, batch_size, \
                 num_durations, alpha, sigma, lr=0.0001, seed=47):
        # set seed
        np.random.seed(seed)
        _ = torch.manual_seed(seed)

        self.standardalizer = None
        self.standardize_data = True

        self._duration_col = "duration"
        self._event_col = "event"

        self.in_features = None
        self.batch_norm = True
        self.output_bias = False
        self.activation = torch.nn.ReLU
        self.epochs = 512
        self.num_workers = 2
        self.callbacks = [tt.callbacks.EarlyStopping()]

        # parameters tuned
        self.alpha = alpha
        self.sigma = 10**sigma
        self.num_nodes = [int(nodes_per_layer) for _ in range(int(layers))]
        self.dropout = dropout
        self.weight_decay = weight_decay
        self.lr = lr
        self.batch_size = int(batch_size)

        self.num_durations = int(num_durations)
        self.labtrans = DeepHitSingle.label_transform(self.num_durations)
Ejemplo n.º 5
0
def prepare_data(df_train, df_test,name):
    """ Define the input and output sets formated to use for neural network model 
    # Arguments
        df_train: training set with all input variables, survival time and censoring status
        df_test: test set with all input variables, survival time and censoring status
        name: name of the model (CoxCC, CoxTime or DeepHit)
    # Returns
        x_train: input variables for the training set
        y_train: output variables for the training set
        x_test: input variables for the test set
        duration_test: survival time for the test set
        event_test: censoring indicator for the test set
        labtrans: output variables transformed for specific models (DeepHit ad CoxTime)
    """
    col_list = list(df_train.columns)
    cols_standardize = [e for e in col_list if e not in ['yy', 'status']]
    standardize = [([col], StandardScaler()) for col in cols_standardize]
    x_mapper = DataFrameMapper(standardize)
    x_train = x_mapper.fit_transform(df_train).astype('float32')
    x_test = x_mapper.transform(df_test).astype('float32')
    get_target = lambda df: (df['yy'].values, df['status'].values)
    
    if name=="DeepHit" :
        num_durations = 10
        labtrans = DeepHitSingle.label_transform(num_durations)
        y_train = labtrans.fit_transform(*get_target(df_train))
    elif name=="CoxTime":
        labtrans = CoxTime.label_transform()
        y_train = labtrans.fit_transform(*get_target(df_train))
    else :
        labtrans = ""
        y_train = get_target(df_train)
    duration_test, event_test = get_target(df_test)
    
    return x_train, y_train, x_test, duration_test, event_test,labtrans
def transform_data(df_train,df_test,df_val, mod, scale, cols_standardize, log_columns, num_durations=100):
    
    tf_train = df_train.copy()
    tf_test = df_test.copy()
    tf_val = df_val.copy()
    if scale == "minmax":
        standardize = [([col], MinMaxScaler()) for col in cols_standardize]
    elif scale == "standard":
        standardize = [([col], StandardScaler()) for col in cols_standardize]
    elif scale == "robust":
        standardize = [([col], RobustScaler()) for col in cols_standardize]
    elif scale == "power":
        standardize = [([col], PowerTransformer()) for col in cols_standardize]

    if len(log_columns) != 0:
        log_scaler = lambda x: np.log(np.abs(x)+1e-7)
        
        for c in log_columns:
            tf_train.loc[:,c] = log_scaler(tf_train.loc[:,c])
            tf_val.loc[:,c] = log_scaler(tf_val.loc[:,c])
            tf_test.loc[:,c] = log_scaler(tf_test.loc[:,c])
   
    x_mapper = DataFrameMapper(standardize)
    
    x_train = x_mapper.fit_transform(tf_train).astype('float32')
    x_val = x_mapper.transform(tf_val).astype('float32')
    x_test = x_mapper.transform(tf_test).astype('float32')
    
    pca = PCA(n_components=10,whiten=True)
    x_train = pca.fit_transform(x_train)
    x_val = pca.transform(x_val)
    x_test = pca.transform(x_test)
    
    if mod == "LogisticHazard":
        labtrans = LogisticHazard.label_transform(num_durations)
    elif mod == "MTLR":
        labtrans = MTLR.label_transform(num_durations)
    elif mod == "DeepHitSingle":
        labtrans = DeepHitSingle.label_transform(num_durations) 
    
    get_target = lambda tf: (tf['duration'].values.astype("float32"), tf['event'].values)
    y_train = labtrans.fit_transform(*get_target(tf_train))
    y_val = labtrans.transform(*get_target(tf_val))
    
    train = (x_train, y_train)
    val = (x_val, y_val)
    
    # We don't need to transform the test labels
    durations_test, events_test = get_target(tf_test)
    
    return x_mapper, labtrans, train, val, x_test, durations_test, events_test, pca
Ejemplo n.º 7
0
            # print(args)

            df_train = data_split[str(fold)]['train']
            df_val = data_split[str(fold)]['valid']
            df_test = data_split[str(fold)]['test']
            if len(cols_categorical) > 0:
                x_train = x_fit_transform(df_train)
                x_val = x_transform(df_val)
                x_test = x_transform(df_test)
            else:
                x_train = x_mapper.fit_transform(df_train).astype('float32')
                x_val = x_mapper.transform(df_val).astype('float32')
                x_test = x_mapper.transform(df_test).astype('float32')

            num_durations = args.num_duration
            labtrans = DeepHitSingle.label_transform(num_durations)
            get_target = lambda df: (df['duration'].values, df['event'].values)
            y_train = labtrans.fit_transform(*get_target(df_train))
            y_val = labtrans.transform(*get_target(df_val))

            train = (x_train, y_train)
            val = (x_val, y_val)
            # We don't need to transform the test labels
            durations_test, events_test = get_target(df_test)
            # Model preparation =============================================================
            in_features = x_train[0].shape[1] if len(
                cols_categorical) else x_train.shape[1]
            num_nodes = [args.num_nodes] * args.num_layers
            out_features = labtrans.out_features
            batch_norm = args.use_BN
            dropout = args.dropout
Ejemplo n.º 8
0
def objective(x_train,
              neurons,
              drop,
              activation,
              lr_opt,
              optimizer,
              n_layers,
              name,
              labtrans=""):
    """ Define the structure of the neural network for a Cox-MLP (CC), CoxTime and  DeepHit
    # Arguments
        x_train: input data as formated by the function "prepare_data"
        neurons: number of neurons per hidden layer in the neural network
        drop: dropout rate applied after each hidden layer
        activation: activation function applied after each hidden layer
        lr_opt: learning rate chosen for optimization
        optimizer: optimization algorithm 
        n_layers: number of hidden layers 
        name: name of the model
        labtrans: transformed input variables, including the time variable
    # Returns
        model: pycox model (based on pytorch) with the architecture defined previously
        callbacks: callbacks function
    
    """
    in_features = x_train.shape[1]
    if labtrans != "":
        out_features = labtrans.out_features
    else:
        out_features = 1
    nb_neurons = [neurons] * n_layers

    if optimizer == "rmsprop":
        optim = tt.optim.RMSprop()
        callbacks = [tt.callbacks.Callback()]

    elif optimizer == "adam":
        optim = tt.optim.Adam()
        callbacks = [tt.callbacks.Callback()]

    elif optimizer == "adam_amsgrad":
        optim = tt.optim.Adam(amsgrad=True)
        callbacks = [tt.callbacks.Callback()]

    elif optimizer == "sgdwr":
        optim = tt.optim.SGD(momentum=0.9)
        callbacks = [tt.callbacks.LRCosineAnnealing()]

    if activation == 'relu':
        act = torch.nn.ReLU
    elif activation == 'elu':
        act = torch.nn.ELU
    elif activation == 'tanh':
        act = torch.nn.Tanh

    if name == "Cox-CC":
        net = tt.practical.MLPVanilla(in_features,
                                      nb_neurons,
                                      out_features,
                                      batch_norm=True,
                                      dropout=drop,
                                      activation=act,
                                      output_bias=False)
        model = CoxCC(net, optim)

    elif name == "CoxTime":
        net = MLPVanillaCoxTime(in_features,
                                nb_neurons,
                                batch_norm=True,
                                dropout=drop,
                                activation=act)
        model = CoxTime(net, optim, labtrans=labtrans)

    elif name == "DeepHit":
        net = tt.practical.MLPVanilla(in_features,
                                      nb_neurons,
                                      out_features,
                                      batch_norm=True,
                                      dropout=drop,
                                      activation=act,
                                      output_bias=False)
        model = DeepHitSingle(net,
                              optim,
                              alpha=0.2,
                              sigma=0.1,
                              duration_index=labtrans.cuts)

    model.optimizer.set_lr(lr_opt)

    return model, callbacks
def benchmark_metabric():

    time_grid = np.linspace(0, 300, 30, dtype=np.int)
    get_target = lambda data: (data['t'], data['y'])
    # define base network
    in_features = 9
    epochs = 512
    net = MetabricMainNetworkTorch(in_features=in_features,
                                   out_features=4,
                                   last_layer_units=1,
                                   bias=True)
    num_durations = 10
    labtrans = DeepHitSingle.label_transform(num_durations)
    deephit_net = MetabricMainNetworkTorch(in_features=in_features,
                                           out_features=4,
                                           last_layer_units=num_durations,
                                           bias=True)
    all_results = []

    # load data
    for cv in tqdm.tqdm(range(5)):
        train_data_path = "data/input_metabric/metabric_preprocessed_cv_{}_train.pkl".format(
            cv)
        val_data_path = "data/input_metabric/metabric_preprocessed_cv_{}_test.pkl".format(
            cv)
        with open(train_data_path, 'rb') as f:
            train_data = pickle.load(f)
        with open(val_data_path, 'rb') as f:
            val_data = pickle.load(f)
        y_train = get_target(train_data)

        # CoxPH, CoxCC
        for method in ['CoxPH', 'CoxCC']:
            f = getattr(pycox.models, method)
            model = f(net, tt.optim.Adam)
            df_metrics = eval(model,
                              train_data,
                              y_train,
                              val_data,
                              time_grid,
                              epochs=epochs,
                              lr=0.01)
            df_metrics['cv'] = cv
            df_metrics['method'] = method
            all_results.append(df_metrics)

        # DeepHit method
        y_train = labtrans.fit_transform(*y_train)
        model = DeepHitSingle(deephit_net,
                              tt.optim.Adam,
                              alpha=0.2,
                              sigma=0.1,
                              duration_index=labtrans.cuts)
        df_metrics = eval(model,
                          train_data,
                          y_train,
                          val_data,
                          time_grid,
                          epochs=epochs,
                          lr=0.01)
        df_metrics['cv'] = cv
        df_metrics['method'] = 'DeepHit'
        all_results.append(df_metrics)
    return pd.concat(all_results, axis=0)
def benchmark_kkbox():

    time_grid = np.array([
        1, 29, 57, 85, 113, 142, 170, 198, 226, 255, 283, 311, 339, 368, 396,
        424, 452, 481, 509, 537, 565, 594, 622, 650, 678, 707, 735, 763, 791,
        820
    ])
    get_target = lambda data: (data['t'], data['y'])
    # define base network
    in_features = 40
    epochs = 70
    net = KKBOXMainNetworkTorch(in_features=in_features,
                                out_features=[64, 32, 16],
                                last_layer_units=1,
                                bias=True,
                                w_init_=None)
    num_durations = 10
    labtrans = DeepHitSingle.label_transform(num_durations)
    deephit_net = KKBOXMainNetworkTorch(in_features=in_features,
                                        out_features=[64, 32, 16],
                                        last_layer_units=num_durations,
                                        bias=True,
                                        w_init_=None)
    all_results = []

    # load data
    train_data_path = "data/input_kkbox/kkbox_preprocessed_train.pkl"
    val_data_path = "data/input_kkbox/kkbox_preprocessed_test.pkl"
    with open(train_data_path, 'rb') as f:
        train_data = pickle.load(f)
    with open(val_data_path, 'rb') as f:
        val_data = pickle.load(f)
    y_train = get_target(train_data)

    # CoxPH, CoxCC
    for method in ['CoxPH', 'CoxCC']:
        f = getattr(pycox.models, method)
        model = f(net, tt.optim.Adam)
        df_metrics = eval(model,
                          train_data,
                          y_train,
                          val_data,
                          time_grid,
                          epochs=epochs,
                          lr=0.001)
        df_metrics['cv'] = 'test'
        df_metrics['method'] = method
        print(df_metrics)
        all_results.append(df_metrics)

    # DeepHit method
    y_train = labtrans.fit_transform(*y_train)
    model = DeepHitSingle(deephit_net,
                          tt.optim.Adam,
                          alpha=0.001,
                          sigma=0.1,
                          duration_index=labtrans.cuts)
    df_metrics = eval(model,
                      train_data,
                      y_train,
                      val_data,
                      time_grid,
                      epochs=epochs,
                      lr=0.001)
    df_metrics['cv'] = 'test'
    df_metrics['method'] = 'DeepHit'
    all_results.append(df_metrics)
    return pd.concat(all_results, axis=0)
Ejemplo n.º 11
0
print('[Dataset: %s, experiment: %d]' % (dataset, experiment_idx))
print()

X_train, y_train, X_test, y_test, feature_names, \
        compute_features_and_transformer, transform_features = \
    load_dataset(dataset, experiment_idx)

print('Testing...', flush=True)
X_train_std, transformer = \
        compute_features_and_transformer(X_train)
X_test_std = transform_features(X_test, transformer)
X_train_std = X_train_std.astype('float32')
X_test_std = X_test_std.astype('float32')
y_train = y_train.astype('float32')
y_test = y_test.astype('float32')
labtrans = DeepHitSingle.label_transform(num_durations)
y_train_discrete = labtrans.fit_transform(*y_train.T)

torch.manual_seed(method_random_seed)
torch.cuda.manual_seed_all(method_random_seed)
np.random.seed(method_random_seed)

batch_norm = True
dropout = 0.0
output_bias = True

net = tt.practical.MLPVanilla(X_train_std.shape[1],
                              [n_nodes for layer_idx in range(n_layers)],
                              labtrans.out_features,
                              batch_norm,
                              dropout,
Ejemplo n.º 12
0
X_train_std = X_train_std.astype('float32')
X_test_std = X_test_std.astype('float32')
y_train = y_train.astype('float32')
y_test = y_test.astype('float32')

torch.manual_seed(init_random_seed)
torch.cuda.manual_seed(init_random_seed)
np.random.seed(init_random_seed)

# for DeepHit, train on full dataset
batch_norm = True
dropout = 0.0
output_bias = True

optimizer = tt.optim.Adam(lr=lr)
labtrans = DeepHitSingle.label_transform(init_num_durations)
y_train_discrete = labtrans.fit_transform(*y_train.T)
net = tt.practical.MLPVanilla(X_train_std.shape[1],
                              [n_nodes for layer_idx in range(n_layers)],
                              labtrans.out_features,
                              batch_norm,
                              dropout,
                              output_bias=output_bias)

surv_model = DeepHitSingle(net,
                           optimizer,
                           alpha=init_alpha,
                           sigma=init_sigma,
                           duration_index=labtrans.cuts)

model_filename = \
Ejemplo n.º 13
0
                        fold_X_val, transformer)
                    fold_X_train_std = fold_X_train_std.astype('float32')
                    fold_X_val_std = fold_X_val_std.astype('float32')

                    # pre-train on full training data
                    tic = time.time()
                    torch.manual_seed(init_random_seed)
                    np.random.seed(init_random_seed)

                    # for DeepHit, train on full dataset
                    batch_norm = True
                    dropout = 0.0
                    output_bias = True

                    optimizer = tt.optim.Adam(lr=lr)
                    labtrans = DeepHitSingle.label_transform(
                        init_num_durations)
                    y_train_discrete = labtrans.fit_transform(*y_train.T)
                    net = tt.practical.MLPVanilla(
                        X_train_std.shape[1],
                        [n_nodes for layer_idx in range(n_layers)],
                        labtrans.out_features,
                        batch_norm,
                        dropout,
                        output_bias=output_bias)

                    surv_model = DeepHitSingle(net,
                                               optimizer,
                                               alpha=init_alpha,
                                               sigma=init_sigma,
                                               duration_index=labtrans.cuts)
Ejemplo n.º 14
0
def _train_dht(x, t, e, folds, params):
    """Helper Function to train a deep-hit model (van der schaar et. al).

  Args:
    x:
      a numpy array of input features (Training Data).
    t:
      a numpy vector of event times (Training Data).
    e:
      a numpy vector of event indicators (1 if event occured, 0 otherwise)
      (Training Data).
    folds:
       vector of the training cv folds.

  Returns:
    Trained pycox.DeepHitSingle model.

  """
    if params is None:
        num_nodes = [100, 100]
        lr = 1e-3
        bs = 128
    else:
        num_nodes = params['num_nodes']
        lr = params['lr']
        bs = params['bs']

    x = x.astype('float32')
    t = t.astype('float32')
    e = e.astype('int32')

    #   num_durations = int(0.5*max(t))
    #   print ("num_durations:", num_durations)

    num_durations = int(max(t))
    #num_durations = int(30)

    print("num_durations:", num_durations)

    labtrans = DeepHitSingle.label_transform(num_durations, scheme='quantiles')
    #labtrans = DeepHitSingle.label_transform(num_durations,)

    #print (labtrans)

    in_features = x.shape[1]
    batch_norm = False
    dropout = 0.0
    output_bias = False

    fold_model = {}

    for f in set(folds):

        xf = x[folds != f]
        tf = t[folds != f]
        ef = e[folds != f]

        validx = sorted(
            np.random.choice(len(xf),
                             size=(int(0.15 * len(xf))),
                             replace=False))

        vidx = np.array([False] * len(xf))
        vidx[validx] = True

        y_train = labtrans.fit_transform(tf[~vidx], ef[~vidx])
        y_val = labtrans.transform(tf[vidx], ef[vidx])
        out_features = labtrans.out_features

        net = ttup.practical.MLPVanilla(in_features, num_nodes, out_features,
                                        batch_norm, dropout)

        model = DeepHitSingle(net,
                              ttup.optim.Adam,
                              alpha=0.5,
                              sigma=1,
                              duration_index=labtrans.cuts)

        y_train = y_train[0].astype('int64'), y_train[1].astype('float32')
        y_val = y_val[0].astype('int64'), y_val[1].astype('float32')

        val = xf[vidx], y_val
        train = xf[~vidx], y_train

        batch_size = bs
        model.optimizer.set_lr(lr)
        epochs = 10
        callbacks = [ttup.callbacks.EarlyStopping()]

        model.fit(
            xf[~vidx],
            y_train,
            batch_size,
            epochs,
            callbacks,
            True,
            val_data=val,
        )

        fold_model[f] = model

    return fold_model
Ejemplo n.º 15
0
def main():
    parser = setup_parser()
    args = parser.parse_args()

    if args.which_gpu != 'none':
        os.environ["CUDA_VISIBLE_DEVICES"] = args.which_gpu

    # save setting
    if not os.path.exists(os.path.join(args.save_path, args.model_name)):
        os.mkdir(os.path.join(args.save_path, args.model_name))

    # label transform
    labtrans = DeepHitSingle.label_transform(args.durations)

    # data reading seeting
    singnal_data_path = args.signal_dataset_path
    table_path = args.table_path
    time_col = 'SurvivalDays'
    event_col = 'Mortality'

    # dataset
    data_pathes, times, events = read_dataset(singnal_data_path, table_path,
                                              time_col, event_col,
                                              args.sample_ratio)

    data_pathes_train, data_pathes_test, times_train, times_test, events_train, events_test = train_test_split(
        data_pathes, times, events, test_size=0.3, random_state=369)
    data_pathes_train, data_pathes_val, times_train, times_val, events_train, events_val = train_test_split(
        data_pathes_train,
        times_train,
        events_train,
        test_size=0.2,
        random_state=369)

    labels_train = label_transfer(times_train, events_train)
    target_train = labtrans.fit_transform(*labels_train)
    dataset_train = VsDatasetBatch(data_pathes_train, *target_train)
    dl_train = tt.data.DataLoaderBatch(dataset_train,
                                       args.train_batch_size,
                                       shuffle=True)

    labels_val = label_transfer(times_val, events_val)
    target_val = labtrans.transform(*labels_val)
    dataset_val = VsDatasetBatch(data_pathes_val, *target_val)
    dl_val = tt.data.DataLoaderBatch(dataset_val,
                                     args.train_batch_size,
                                     shuffle=True)

    labels_test = label_transfer(times_test, events_test)
    dataset_test_x = VsTestInput(data_pathes_test)
    dl_test_x = DataLoader(dataset_test_x, args.test_batch_size, shuffle=False)

    net = resnet18(args)
    model = DeepHitSingle(net,
                          tt.optim.Adam(lr=args.lr,
                                        betas=(0.9, 0.999),
                                        eps=1e-08,
                                        weight_decay=5e-4,
                                        amsgrad=False),
                          duration_index=labtrans.cuts)
    # callbacks = [tt.cb.EarlyStopping(patience=15)]
    callbacks = [
        tt.cb.BestWeights(file_path=os.path.join(
            args.save_path, args.model_name, args.model_name + '_bestWeight'),
                          rm_file=False)
    ]
    verbose = True
    model_log = model.fit_dataloader(dl_train,
                                     args.epochs,
                                     callbacks,
                                     verbose,
                                     val_dataloader=dl_val)

    save_args(os.path.join(args.save_path, args.model_name), args)
    model_log.to_pandas().to_csv(os.path.join(args.save_path, args.model_name,
                                              'loss.csv'),
                                 index=False)
    model.save_net(
        path=os.path.join(args.save_path, args.model_name, args.model_name +
                          '_final'))
    surv = model.predict_surv_df(dl_test_x)
    surv.to_csv(os.path.join(args.save_path, args.model_name,
                             'test_sur_df.csv'),
                index=False)
    ev = EvalSurv(surv, *labels_test, 'km')
    print(ev.concordance_td())
    save_cindex(os.path.join(args.save_path, args.model_name),
                ev.concordance_td())
    print('done')
Ejemplo n.º 16
0
                    fold_X_val_std = transform_features(
                        fold_X_val, transformer)
                    fold_X_train_std = fold_X_train_std.astype('float32')
                    fold_X_val_std = fold_X_val_std.astype('float32')

                    tic = time.time()
                    torch.manual_seed(method_random_seed)
                    torch.cuda.manual_seed_all(method_random_seed)
                    np.random.seed(method_random_seed)

                    batch_norm = True
                    dropout = 0.
                    output_bias = True

                    optimizer = tt.optim.Adam(lr=lr)
                    labtrans = DeepHitSingle.label_transform(num_durations)
                    fold_y_train_discrete \
                        = labtrans.fit_transform(*fold_y_train.T)
                    fold_y_val_discrete \
                        = labtrans.transform(*fold_y_val.T)
                    net = tt.practical.MLPVanilla(
                        fold_X_train_std.shape[1],
                        [n_nodes for layer_idx in range(n_layers)],
                        labtrans.out_features,
                        batch_norm,
                        dropout,
                        output_bias=output_bias)

                    surv_model = DeepHitSingle(net,
                                               optimizer,
                                               alpha=alpha,
Ejemplo n.º 17
0
df_train.head()

cols_standardize = ['x0', 'x1', 'x2', 'x3', 'x8']
cols_leave = ['x4', 'x5', 'x6', 'x7']

standardize = [([col], StandardScaler()) for col in cols_standardize]
leave = [(col, None) for col in cols_leave]

x_mapper = DataFrameMapper(standardize + leave)

x_train = x_mapper.fit_transform(df_train).astype('float32')
x_val = x_mapper.transform(df_val).astype('float32')
x_test = x_mapper.transform(df_test).astype('float32')

num_durations = 10
labtrans = DeepHitSingle.label_transform(num_durations)
get_target = lambda df: (df['duration'].values, df['event'].values)
y_train = labtrans.fit_transform(*get_target(df_train))
y_val = labtrans.transform(*get_target(df_val))

train = (x_train, y_train)
val = (x_val, y_val)

# We don't need to transform the test labels
durations_test, events_test = get_target(df_test)

type(labtrans)

# Making Neural Network with torch:
in_features = x_train.shape[1]
num_nodes = [32, 32]
Ejemplo n.º 18
0
class DeepHit_pycox():
    def __init__(self, nodes_per_layer, layers, dropout, weight_decay, batch_size, \
                 num_durations, alpha, sigma, lr=0.0001, seed=47):
        # set seed
        np.random.seed(seed)
        _ = torch.manual_seed(seed)

        self.standardalizer = None
        self.standardize_data = True

        self._duration_col = "duration"
        self._event_col = "event"

        self.in_features = None
        self.batch_norm = True
        self.output_bias = False
        self.activation = torch.nn.ReLU
        self.epochs = 512
        self.num_workers = 2
        self.callbacks = [tt.callbacks.EarlyStopping()]

        # parameters tuned
        self.alpha = alpha
        self.sigma = 10**sigma
        self.num_nodes = [int(nodes_per_layer) for _ in range(int(layers))]
        self.dropout = dropout
        self.weight_decay = weight_decay
        self.lr = lr
        self.batch_size = int(batch_size)

        self.num_durations = int(num_durations)
        self.labtrans = DeepHitSingle.label_transform(self.num_durations)

    def set_standardize(self, standardize_bool):
        self.standardize_data = standardize_bool

    def _format_to_pycox(self, X, Y, F):
        # from numpy to pandas df
        df = pd.DataFrame(data=X, columns=F)
        if Y is not None:
            df[self._duration_col] = Y[:, 0]
            df[self._event_col] = Y[:, 1]
        return df

    def _standardize_df(self, df, flag):
        # if flag = test, the df passed in does not contain Y labels
        if self.standardize_data:
            # standardize x
            df_x = df if flag == 'test' else df.drop(
                columns=[self._duration_col, self._event_col])
            if flag == "train":
                cols_leave = []
                cols_standardize = []
                for column in df_x.columns:
                    if set(pd.unique(df[column])) == set([0, 1]):
                        cols_leave.append(column)
                    else:
                        cols_standardize.append(column)
                standardize = [([col], StandardScaler())
                               for col in cols_standardize]
                leave = [(col, None) for col in cols_leave]
                self.standardalizer = DataFrameMapper(standardize + leave)

                x = self.standardalizer.fit_transform(df_x).astype('float32')
                # standardize y
                y = self.labtrans.fit_transform(df[self._duration_col].values.astype('float32'), \
                                                df[self._event_col].values.astype('float32'))
            elif flag == "val":
                x = self.standardalizer.transform(df_x).astype('float32')
                y = self.labtrans.transform(df[self._duration_col].values.astype('float32'), \
                                            df[self._event_col].values.astype('float32'))

            elif flag == "test":
                x = self.standardalizer.transform(df_x).astype('float32')
                y = None

            else:
                raise NotImplementedError

            return x, y
        else:
            raise NotImplementedError

    def fit(self, X, y, column_names):
        # format data
        self.column_names = column_names
        full_df = self._format_to_pycox(X, y, self.column_names)
        val_df = full_df.sample(frac=0.2)
        train_df = full_df.drop(val_df.index)
        train_x, train_y = self._standardize_df(train_df, "train")
        val_x, val_y = self._standardize_df(val_df, "val")
        # configure model
        self.in_features = train_x.shape[1]
        self.out_features = self.labtrans.out_features
        net = tt.practical.MLPVanilla(
            in_features=self.in_features,
            num_nodes=self.num_nodes,
            out_features=self.out_features,
            batch_norm=self.batch_norm,
            dropout=self.dropout,
            activation=self.activation,
            output_bias=self.output_bias,
            w_init_=lambda w: torch.nn.init.xavier_normal_(w))
        self.model = DeepHitSingle(net, tt.optim.Adam(lr=self.lr, weight_decay=self.weight_decay), \
                                  alpha=self.alpha, sigma=self.sigma, duration_index=self.labtrans.cuts)
        n_train = train_x.shape[0]
        while n_train % self.batch_size == 1:  # this will cause issues in batch norm
            self.batch_size += 1
        self.model.fit(train_x,
                       train_y,
                       self.batch_size,
                       self.epochs,
                       self.callbacks,
                       verbose=True,
                       val_data=(val_x, val_y),
                       val_batch_size=self.batch_size,
                       num_workers=self.num_workers)

    def predict(self, test_x, time_list):
        # format data
        test_df = self._format_to_pycox(test_x, None, self.column_names)
        test_x, _ = self._standardize_df(test_df, "test")

        proba_matrix_ = self.model.interpolate().predict_surv_df(test_x)
        time_list_ = list(proba_matrix_.index)
        proba_matrix = np.transpose(proba_matrix_.values)
        pred_medians = []
        median_time = max(time_list_)
        # if the predicted proba never goes below 0.5, predict the largest seen value
        for test_idx, survival_proba in enumerate(proba_matrix):
            # the survival_proba is in descending order
            for col, proba in enumerate(survival_proba):
                if proba > 0.5:
                    continue
                if proba == 0.5 or col == 0:
                    median_time = time_list_[col]
                else:
                    median_time = (time_list_[col - 1] + time_list_[col]) / 2
                break
            pred_medians.append(median_time)

        return np.array(pred_medians), proba_matrix_