CoolFace
Apppublic

onconpc/onconpc-visualization

sourceHugging Faceupdated 7mo agoView on Hugging Face
2likes
train_evaluate_onconpc.py168 linesDownload Raw Back to codes
1from absl import app2from absl import flags3import pandas as pd4import pickle5import utils_training6import utils7import os8import numpy as np9 10"""11Author: Intae Moon12In this script, we train and evaluate the performance of the XGBoost model on the OncoTree-based cancer types.13One can choose to use k-fold cross validation or train on the entire dataset and test on the held out set.14"""15 16flags.DEFINE_string('config', None, 'Cancer centers to incorporate for feature processing (genie, profile_dfci, or both)')17flags.DEFINE_integer('k_fold', 10, 'Number of folds in k-fold cross-validation')18flags.DEFINE_boolean('use_held_out_set', False, 'Whether to use a held-out set')19flags.DEFINE_boolean('filter_out_non_informatives', False, 'Whether to filter out non-informative features and samples')20flags.DEFINE_string('save_model_name', None, 'Name of the model to save')21flags.DEFINE_string('index_profile_samples_by', 'SAMPLE_ACCESSION_NBR', 'Index profile samples by DFCI_MRN or SAMPLE_ACCESSION_NBR')22# DATA_PATH = '../data/internal_training_data/'23DATA_PATH = '../data/'24 25def main(argv=None):26	# Custom check for flags that you still require to be non-default27	FLAGS = flags.FLAGS28	# Training configs:29	config = FLAGS.config30	k_fold = FLAGS.k_fold31	use_held_out_set = FLAGS.use_held_out_set32	save_model_name = FLAGS.save_model_name33	index_profile_samples_by = FLAGS.index_profile_samples_by34	filter_out_non_informatives = FLAGS.filter_out_non_informatives35	if config not in ['genie', 'profile_dfci', 'both']:36		raise ValueError("config must be one of genie, profile_dfci, or both")37	if config == 'genie' and use_held_out_set == True:38		raise ValueError("Cannot use held out set when training on genie data only")39	# load xgb parameters40	hyperparam_xgb = pd.read_csv(os.path.join(DATA_PATH, 'xgb_hyperparams'), sep = '\t')  #xgb_params_to_run # params_w_results_Mar_1st41	hyperparam_xgb.drop(columns = 'Unnamed: 0', inplace = True)42	# Get the best performing hyperparameters from the previous experiments43	# this can be extended to try multiple hyperparameters44	params_xgb = hyperparam_xgb.iloc[0:1]45 46	# ====================================================================================================47	# Loading data and labels, and processing them for training48	# ====================================================================================================49	# Load trainable data and labels50	# Tab separated feature data for CKPs51	feature_data_name = os.path.join(DATA_PATH, 'features_genie_') # Replace with your feature file path52	# Tab separated label data for CKPs53	label_data_name = os.path.join(DATA_PATH, 'labels_genie_')  # Replace with your label file path54	if config in ['profile_dfci', 'both']:55		# Tab separated feature data for CUPs56		feature_data_name_cup = os.path.join(DATA_PATH, 'features_combined_cup_onco_tree_based_dev')57		features_cup_df = pd.read_csv(feature_data_name_cup, sep = '\t')58		features_cup_df.set_index('Unnamed: 0', inplace = True)59	features_ckp_df = pd.read_csv(feature_data_name, sep = '\t')60	features_ckp_df.set_index(features_ckp_df.columns[0], inplace = True)61	labels_ckp_df = pd.read_csv(label_data_name, sep = '\t')62	labels_ckp_df.set_index(labels_ckp_df.columns[0], inplace = True)63 64	if config in ['profile_dfci', 'both']:65		if index_profile_samples_by == 'DFCI_MRN':66			# Load ../data/internal_training_data/onconpc_sample_id_to_dfci_mrn.pkl67			with open(os.path.join(DATA_PATH, 'onconpc_sample_id_to_dfci_mrn.pkl'), "rb") as fp:   # Unpickling68				onconpc_sample_id_to_dfci_mrn = pickle.load(fp)69			# index CKP data by DFCI_MRN70			features_ckp_df.index = utils_training.get_new_indices(features_ckp_df.index, onconpc_sample_id_to_dfci_mrn)71			labels_ckp_df.index = utils_training.get_new_indices(labels_ckp_df.index, onconpc_sample_id_to_dfci_mrn)72			features_cup_df.index = utils_training.get_new_indices(features_cup_df.index, onconpc_sample_id_to_dfci_mrn)73			# Set index name74			features_ckp_df.index.name = 'DFCI_MRN_FOR_PROFILE'75			labels_ckp_df.index.name = 'DFCI_MRN_FOR_PROFILE'76			features_cup_df.index.name = 'DFCI_MRN_FOR_PROFILE'77		elif index_profile_samples_by == 'SAMPLE_ACCESSION_NBR':78			# Load ../data/internal_training_data/onconpc_sample_id_to_sample_accession_nbr.pkl79			with open(os.path.join(DATA_PATH, 'onconpc_sample_id_to_sample_accession_nbr.pkl'), "rb") as fp:   # Unpickling80				onconpc_sample_id_to_sample_accession_nbr = pickle.load(fp)81			# index CKP data by SAMPLE_ACCESSION_NBR82			features_ckp_df.index = utils_training.get_new_indices(features_ckp_df.index, onconpc_sample_id_to_sample_accession_nbr)83			labels_ckp_df.index = utils_training.get_new_indices(labels_ckp_df.index, onconpc_sample_id_to_sample_accession_nbr)84			features_cup_df.index = utils_training.get_new_indices(features_cup_df.index, onconpc_sample_id_to_sample_accession_nbr)85			# Set index name86			features_ckp_df.index.name = 'SAMPLE_ACCESSION_NBR_FOR_PROFILE'87			labels_ckp_df.index.name = 'SAMPLE_ACCESSION_NBR_FOR_PROFILE'88			features_cup_df.index.name = 'SAMPLE_ACCESSION_NBR_FOR_PROFILE'89 90		if use_held_out_set:91			heldout_ckps_preds_df = pd.read_csv(os.path.join(DATA_PATH, 'heldout_ckps_preds_onco_tree_based_dev'), sep = '\t')92			heldout_ckps_preds_df.set_index(heldout_ckps_preds_df.columns[0], inplace = True)93			held_out_indices = utils_training.get_new_indices([idx[:-3] for idx in heldout_ckps_preds_df.index],94														onconpc_sample_id_to_sample_accession_nbr)95			# Exclude held out samples from training96			indices_to_choose = set(features_ckp_df.index) - set(held_out_indices)97			features_ckp_df = features_ckp_df.loc[indices_to_choose]98			labels_ckp_df = labels_ckp_df.loc[indices_to_choose]99	feature_group_to_features_dict = utils.partition_feature_names_by_group(list(features_ckp_df.columns))100	if filter_out_non_informatives:101		if config in ['profile_dfci', 'both']:102			(features_ckp_final_df,103		labels_ckp_final_df,104		features_cup_final_df) = utils_training.filter_out_low_freq_feats_and_samples(features_ckp_df,105																						labels_ckp_df,106																						features_cup_df, 107																						feature_group_to_features_dict)108		else:109			(features_ckp_final_df,110		labels_ckp_final_df,111		_) = utils_training.filter_out_low_freq_feats_and_samples(features_ckp_df,112															labels_ckp_df,113															features_ckp_df, # placeholder for cup_df114															feature_group_to_features_dict)115	else:116		features_ckp_final_df = features_ckp_df117		labels_ckp_final_df = labels_ckp_df118		if config in ['profile_dfci', 'both']:119			features_cup_final_df = features_cup_df120 121	# ====================================================================================================122	# Model Training and Evaluation123	# ====================================================================================================124	# Cancer types to consider125	cancer_types = list(np.unique(labels_ckp_final_df.cancer_type.values))126	# Check duplicate indices127	if len(features_ckp_final_df) == len(set(features_ckp_final_df.index)):128		print('\n')129		print('No duplicate indices')130	else:131		print('\n')132		print('Duplicate indices detected (most likely due to DFCI_MRN indexing)')133	if k_fold > 0:134		(k_fold_to_performance_report_dict,135	pred_probs_on_val_total_df) = utils_training.perform_k_fold(features_ckp_final_df,136																labels_ckp_final_df,137																cancer_types,138																params_xgb,139																k_fold=k_fold,140																save_model_name=save_model_name)141		# Store k_fold_to_performance_report_dict and pred_probs_on_val_total_df142		with open(os.path.join(DATA_PATH, f'k_fold_to_performance_report_dict_{save_model_name}.pkl'), 'wb') as f:143			pickle.dump(k_fold_to_performance_report_dict, f)144		pred_probs_on_val_total_df.to_csv(os.path.join(DATA_PATH, f'pred_probs_on_val_total_df_{save_model_name}.csv'))145	else:146		X_train = features_ckp_final_df.copy()147		y_train = labels_ckp_final_df.loc[X_train.index]['cancer_label']148		# Standardize Age based on train data149		age_mean = X_train['Age'].mean()150		age_std = X_train['Age'].std()151		X_train['Age'] = (X_train['Age'] - age_mean) / age_std152		xg_clf = utils_training.fit_and_evaluate_model(X_train.values,153												 y_train.values,154												 None,155												 None,156												 params_xgb,157												 cancer_types)158		# Evaluate the model performance based on different maximum prediction probability cut-offs.159		if save_model_name is not None:160			if not os.path.exists('../models'):161				os.makedirs('../models/models')162			xg_clf.save_model(f'../models/xgboost_{save_model_name}_trained_on_all_ckps.json')163	return 164 165if __name__ == '__main__':166	flags.mark_flags_as_required(['k_fold', 'config', 'use_held_out_set', 'save_model_name'])167	app.run(main)168