forked from Yu-Group/sMPS2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path03_evaluate_prediction_methods.py
More file actions
124 lines (105 loc) · 5.94 KB
/
Copy path03_evaluate_prediction_methods.py
File metadata and controls
124 lines (105 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import argparse
from os.path import join as oj
import os
import pandas as pd
import numpy as np
import copy
import pickle as pkl
import importlib
import sys
sys.path.append("..")
from functions.pipeline import run_binary_classification_pipeline
if __name__ == '__main__':
# load inputs
parser = argparse.ArgumentParser()
parser.add_argument('--config', type=str, default="models")
parser.add_argument('--include_clin', action='store_true', default=False)
parser.add_argument('--keep_models', type=str, default=None)
parser.add_argument('--topk', type=int, default=17)
parser.add_argument('--topk_mode', type=str, default="naive")
parser.add_argument('--split_seed', type=int, default=0)
parser.add_argument('--results_path', type=str, default="results")
parser.add_argument('--scale_X', action='store_true', default=False)
parser.add_argument('--ignore_cache', action='store_true', default=False)
args = parser.parse_args()
assert args.topk_mode in ["naive", "ensemble", "ensemble_small", "ensemble_linear", "ensemble_nonlinear", "pcs", "pcs_small"]
assert args.topk is not None
# define helper variables
CLIN_COLS = ["age", "aa", "fhx", "dre_abnl", "bx_prior_neg", "psa", "prostate_volume"]
DROP_CLIN_COLS = ["prostate_volume"]
CONFIG = importlib.import_module(f'model_config.{args.config}')
cv_param_grid_all = CONFIG.CV_PARAM_GRID
models_all = CONFIG.MODELS
fi_models_all = CONFIG.FI_MODELS
if args.include_clin:
res_subdir = "train_with_clinical"
else:
res_subdir = "train_without_clinical"
if args.scale_X:
data_suffix = "_scaled"
else:
data_suffix = ""
# get ranked list of important features
out_dir = oj(args.results_path, res_subdir, str(args.split_seed))
naive_vimps = pkl.load(open(oj(out_dir, f"naive_vimps{data_suffix}.pkl"), "rb"))
# load in data
data_dir = oj(args.results_path, "train_with_clinical", str(args.split_seed))
X_train = pd.read_csv(oj(data_dir, f"X_train{data_suffix}.csv"))
y_train = pd.read_csv(oj(data_dir, "y_train.csv"))
X_test = pd.read_csv(oj(data_dir, f"X_test{data_suffix}.csv"))
y_test = pd.read_csv(oj(data_dir, "y_test.csv"))
# evaluate models with and without clinical data
for key in ["eval_with_clinical", "eval_without_clinical"]:
out_dir = oj(args.results_path, key, res_subdir, str(args.topk), str(args.split_seed))
os.makedirs(out_dir, exist_ok=True)
test_errs_all = {}
test_preds_all = {}
test_prob_preds_all = {}
full_tuned_pipelines_all = {}
# get models to fit
if args.keep_models is None:
keep_models = naive_vimps.keys()
else:
keep_models = args.keep_models.split(",")
# retrieve cache
if not args.ignore_cache and os.path.exists(oj(out_dir, f"tuned_pipelines_{args.topk_mode}{data_suffix}.pkl")):
test_errs_all = pkl.load(open(oj(out_dir, f"valid_errs_{args.topk_mode}{data_suffix}.pkl"), "rb"))
keep_models = [model_name for model_name in keep_models if model_name not in test_errs_all.keys()]
if len(keep_models) == 0:
print('Evaluation has been cached previously!')
continue
test_preds_all = pkl.load(open(oj(out_dir, f"valid_preds_{args.topk_mode}{data_suffix}.pkl"), "rb"))
test_prob_preds_all = pkl.load(open(oj(out_dir, f"valid_prob_preds_{args.topk_mode}{data_suffix}.pkl"), "rb"))
full_tuned_pipelines_all = pkl.load(open(oj(out_dir, f"tuned_pipelines_{args.topk_mode}{data_suffix}.pkl"), "rb"))
for pipe_name in keep_models:
if args.topk_mode in ["ensemble", "ensemble_small", "ensemble_linear", "ensemble_nonlinear"]:
ranked_vimps = pkl.load(open(oj(args.results_path, res_subdir, f"{args.topk_mode}_vimps{data_suffix}.pkl"), "rb"))
ranked_vimps = ranked_vimps.loc[ranked_vimps["rep"] == args.split_seed]
top_genes = list(ranked_vimps["varname"][:args.topk])
elif args.topk_mode in ["pcs", "pcs_small"]:
ranked_vimps = pkl.load(open(oj(os.path.dirname(args.results_path), res_subdir, f"{args.topk_mode}_vimps{data_suffix}.pkl"), "rb"))
ranked_vimps = ranked_vimps.loc[ranked_vimps["rep"] == args.split_seed]
top_genes = list(ranked_vimps["varname"][:args.topk])
else:
top_genes = list(naive_vimps[pipe_name]["varname"][:args.topk])
if key == "eval_with_clinical":
keep_features = top_genes + [x for x in CLIN_COLS if x not in DROP_CLIN_COLS]
else:
keep_features = top_genes
test_errs, test_preds, test_prob_preds, full_tuned_pipelines, _, _ = \
run_binary_classification_pipeline(
X_train.loc[:, keep_features], y_train, X_test.loc[:, keep_features], y_test,
models_all=models_all, cv_param_grid_all=cv_param_grid_all,
fi_models_all=fi_models_all, keep_models=[pipe_name]
)
test_errs_all[pipe_name] = copy.deepcopy(test_errs[pipe_name])
test_preds_all[pipe_name] = copy.deepcopy(test_preds[pipe_name])
test_prob_preds_all[pipe_name] = copy.deepcopy(test_prob_preds[pipe_name])
full_tuned_pipelines_all[pipe_name] = copy.deepcopy(full_tuned_pipelines[pipe_name])
# save results
pkl.dump(test_errs_all, open(oj(out_dir, f"valid_errs_{args.topk_mode}{data_suffix}.pkl"), "wb"))
pkl.dump(test_preds_all, open(oj(out_dir, f"valid_preds_{args.topk_mode}{data_suffix}.pkl"), "wb"))
pkl.dump(test_prob_preds_all, open(oj(out_dir, f"valid_prob_preds_{args.topk_mode}{data_suffix}.pkl"), "wb"))
pkl.dump(full_tuned_pipelines_all, open(oj(out_dir, f"tuned_pipelines_{args.topk_mode}{data_suffix}.pkl"), "wb"))
print('Completed evaluation!')
# %%