[8d2107]: / decision_model.py

Download this file

109 lines (97 with data), 3.8 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
from sklearn.base import TransformerMixin, ClassifierMixin
from value_extractor_transformer import EFTransformer, QRSTransformer, LBBBTransformer, SinusRhythmTransformer, NYHATransformer
class ClinicalDecisionModel(TransformerMixin, ClassifierMixin):
"""
Replicate prediction of clinical descion tree
in 'Circulation-2012-Tracy-1784-800.pdf' Appendix 3
Does not need to be fit and transforms data on its own
"""
LVEF = 'lvef'
QRS = 'qrs'
LBBB = 'lbbb'
SINUS_RHYTHM = 'sr'
NYHA = 'nyha'
def __init__(self):
self.transformers = dict()
self.transformers[self.LVEF]= EFTransformer('max',3)
self.transformers[self.QRS]= QRSTransformer('mean', 3)
self.transformers[self.LBBB]= LBBBTransformer()
self.transformers[self.SINUS_RHYTHM]= SinusRhythmTransformer()
self.transformers[self.NYHA]= NYHATransformer()
def fit(self, X = None, y = None):
for trans_key in self.transformers:
self.transformers[trans_key].fit(X, y)
return self
def transform(self, X):
return [self.__find_values(empi) for empi in X]
def __find_values(self, empi):
values = dict()
for trans_key in self.transformers:
values[trans_key] = self.transformers[trans_key].get_feature(empi)
return values
def predict(self, X):
X_transformed = self.transform(X)
predicted_colors = map(self.predict_color, X_transformed)
y_hat = map(self.prediction_from_color, predicted_colors)
return y_hat
def predict_color(self, values):
"""
Summary of logic (all have ef > 35):
NYHA I:
Orange - ef < 30, qrs > 150, lbbb
Red - ef > 30 or qrs < 150 or no lbbb
NYHA II:
Green - qrs > 150, lbbb, sinus rhythm
Yellow - qrs < 150, lbbb, sinus rhythm
Orange - qrs > 150, no lbbb
Red - no lbbb and qrs < 150 or lbbb and no SR
NYHA III:
Green - qrs > 150, lbbb, sinus rhythm
Yellow - qrs > 150, no lbbb, sinus rhythm
Orange - qrs < 150, no lbbb, sinus rhythm
Red - qrs < 120 or no sinus rhythm
NYHA IV:
Red - for all cases
"""
nyha_class = values[self.NYHA].index(1) + 1
ef = values[self.LVEF][0]
qrs = values[self.QRS][0]
lbbb = bool(values[self.LBBB][0])
sr = bool(values[self.SINUS_RHYTHM][0])
if ef > 35: #EF higher than 35 disqualified
return 'red'
#print "NYHA:", nyha_class, "EF:", ef, "QRS:", qrs, "LBBB:", lbbb, "SR:", sr
if nyha_class == 1:
if ef < 30 and qrs >= 150 and lbbb:
return 'orange'
else:
return 'red'
elif nyha_class == 2:
if lbbb:
if sr:
if qrs > 150:
return 'green'
else:
return 'yellow'
else:
return 'red'
else:
if qrs > 150:
return 'orange'
else:
return 'red'
elif nyha_class == 3:
if sr and qrs > 120:
if qrs > 150 and lbbb:
return 'green'
elif qrs <= 150 and not lbbb:
return 'orange'
else:
return 'yellow'
else:
return 'red'
else: #this is None and class 4
return 'red'
def prediction_from_color(self, color):
mapping = {'red' : 0, 'orange' : 0, 'yellow': 1, 'green' : 1}
return mapping[color]