-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmodel_evaluation.py
176 lines (144 loc) · 8.26 KB
/
model_evaluation.py
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# Copyright (C) 2022 Antonio Rodriguez
#
# This file is part of synthetic_data_generation_framework.
#
# synthetic_data_generation_framework is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# synthetic_data_generation_framework is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with synthetic_data_generation_framework. If not, see <http://www.gnu.org/licenses/>.
import numpy as np
import pandas as pd
from sklearn import metrics
from sklearn.metrics import plot_roc_curve, f1_score
from sklearn import base
import matplotlib.pyplot as plt
from typing import List, Tuple, Dict
def acc_auc_roc_SVM(model : base.BaseEstimator, X : pd.DataFrame, y : pd.DataFrame):
"""Computes accuracy (acc), Area Under the Curve (AUC), Reciever Operating
Characteristics (ROC) and F1-score for a given SVM Classifier and a given
dataset. This function is thought to be used in a validation or test set".
Args:
-----
models: sklearn SVM instance.
X : features of the dataset
y : target variable of the dataset.
Returns:
--------
acc: accuracy on the validation set.
roc_auc: AUC on the validation set.
f1_sc: F1-score on the validation set.
"""
# Prediction
y_pred = model.predict(X)
# Accuracy
acc = metrics.accuracy_score(y, y_pred)
# AUC
y_score = model.decision_function(X)
fpr, tpr, thresholds = metrics.roc_curve(y, y_score, pos_label=1)
roc_auc = metrics.auc(fpr, tpr)
# F1 Score
f1_sc = f1_score(y, y_pred)
return acc, roc_auc, f1_sc
def acc_auc_roc_general(model : base.BaseEstimator, X : pd.DataFrame, y : pd.DataFrame):
"""Computes accuracy (acc), Area Under the Curve (AUC), Reciever Operating
Characteristics (ROC) and F1-score for a sklearn Classifier and a given
dataset. This function is thought to be used in a validation or test set".
Args:
-----
models: sklearn classifier instance.
X : features of the dataset
y : target variable of the dataset.
Returns:
--------
acc: accuracy on the validation set.
auc: AUC on the validation set.
f1_sc: F1-score on the validation set.
"""
# Prediction
y_pred = model.predict(X)
# Accuracy
acc = metrics.accuracy_score(y, y_pred)
# ROC
disp = plot_roc_curve(model, X, y)
# AUC
auc = disp.roc_auc
# F1 Score
f1_sc = f1_score(y, y_pred)
return acc, auc, f1_sc
def get_eval_dictionaries(sdg_combinations: List, sizes_keys: List, class_metrics : List, iterations : int) -> Tuple [Dict, Dict, Dict]:
"""This function generates and returns three different dictionaries to evaluate
the Synthetic Data Generation (SDG) in three ways:
1) Statistical metrics of SDG: Pairwise Correlation Difference (PCD),
Kullback-Leibler Divergence (KLD), Maximun Mean Discrepancy (MMD) and
Case/Control ratio.
2) Classification Performance employing four different Machine Learning
(ML) models: SVM, RF, XGB and KNN. Notice that any changes on the
framework must be changed in this code for a proper work of it.
3) Hyperparameters optimization. These are ML models-dependent. As
abovementioned, changes on tuned parameters or in the models
themselves, must be translated into changes in this code.
Args:
-----
sdg_combinations: list containing the employed SDG combinations.
sizes_keys: identificators of the different amount of synthetic samples generated.
class_metrics: list containing the metrics used to evaluated the ML models
iterations: number of synthetic data generations iterations to be evaluated
Returns:
--------
sdg_metrics: dictionary of structure {SDG combinations :
{different generated sizes:
{statistical metrics : np.arrray(iterations)}}}
class_metrics: dictionary of structure {ML model:
{SDG combinations :
{different generated sizes:
{classification metrics : np.array(iterations)}}}
hyperparameters: dictionary of structure {ML model:
{SDG combinations :
{different generated sizes:
{best model hyperparameters : list(iterations)}}}.
"""
# Dictionary to store metrics for all synthetic data generation combinations
sdg_metrics = {}
# Dictionary structure: {SDG combinations : {different generated sizes: {statistical metrics : np.arrray(iterations)}}}
for comb in sdg_combinations :
sdg_metrics[comb] = {'quarter': {}, 'half': {},
'unit':{}, 'double': {}, 'quadruple' : {}}
for sizes in sizes_keys :
sdg_metrics[comb][sizes] = {'PCD': np.zeros(iterations), 'MMD': np.zeros(iterations),
'KLD':np.zeros(iterations), 'ratio': np.zeros(iterations)}
# In order to compare results obtained with SDG to the reference, train is added as a key in the dictionary
train = "No synthetic"
sdg_combinations.insert(0, train)
# Dictionary II to store classification metrics for all synthetic data generation combinations and all ML classifiers
class_metrics = {'SVM' : {}, 'RF' : {}, 'XGB' : {}, 'KNN': {}}
# Dictionary structure: {ML model: {SDG combinations : {different generated sizes: {classification metrics : np.array(iterations)}}}
for key in class_metrics :
for comb in sdg_combinations :
class_metrics[key][comb] = {'quarter': {}, 'half': {},
'unit':{}, 'double': {}, 'quadruple' : {}}
for sizes in sizes_keys :
class_metrics[key][comb][sizes] = {'acc': np.zeros(iterations), 'auc': np.zeros(iterations),
'f1':np.zeros(iterations)}
# Dictionary III to store optimized models after GridSearch Hiperparametrization
hyperparameters = {'SVM' : {}, 'RF' : {}, 'XGB' : {}, 'KNN': {}}
# Dictionary structure: {ML model: {SDG combinations : {different generated sizes: {best model hyperparameters : list(iterations)}}}
# Notice that hyperparameters are ML model-specific
for key in hyperparameters :
for comb in sdg_combinations :
hyperparameters[key][comb] = {'quarter': {}, 'half': {},
'unit':{}, 'double': {}, 'quadruple' : {}}
for comb in sdg_combinations :
for sizes in sizes_keys :
hyperparameters['SVM'][comb][sizes] = {'kernel': [None]*iterations, 'C': [None]*iterations, 'gamma' : [None]*iterations}
hyperparameters['RF'][comb][sizes] = {'estimators': [None]*iterations, 'max_feat': [None]*iterations}
hyperparameters['XGB'][comb][sizes] = {'estimators': [None]*iterations, 'lr': [None]*iterations}
hyperparameters['KNN'][comb][sizes] = {'neigh': [None]*iterations, 'C': [None]*iterations, 'weights' : [None]*iterations}
return sdg_metrics, class_metrics, hyperparameters