File size: 5,458 Bytes
fba85dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import streamlit.components.v1 as components
import numpy as np
import pickle 
import pandas as pd

pd.set_option('display.max_columns', 500)
def impute_missing_values(df_,dict_impute):
    return df_.fillna(dict_impute)


to_rescale_ = ['MS_d',
 'delta_msid_d',
 'pr_pre_tavi',
 'surface_systole',
 'MS_s',
 'calc_risque_n']



to_encode_ = ['syncope_Oui',
 'marque_ACURATE',
 'marque_COREVALVE',
 'marque_EDWARDS',
 'bloc_branche_pre_bbd']

st.title("Pacemaker Implantation (IPM) risk prediction")
st.subheader(f':green[Per procedural] Tavi implantation model')
         
cols =  to_rescale_+to_encode_






with st.form(key='cols_form'):
    c1,cuseless= st.columns(2)
    c2,c3 = st.columns(2)
    c4,c5,c6 = st.columns(3)
    c7,c8,c9  = st.columns(3)
    c10,c11  = st.columns(2)


    with c1:
        syncope_Oui = st.selectbox("Syncope",key="syncope",options=["Yes", "No"])
    with c2:
        pr_pre_tavi = st.number_input('Pre-TAVI PR time (ms)',value=186)
    with c3:
        bloc_branche_pre_bbd = st.selectbox("Right bundle branch block",key="prebbd",options=["Yes", "No"])
    
    with c4:
        ncc_calcif_n = st.selectbox("NCC calcification grade",key='nccalcn',options=[0,1,2,3])
    with c5:
        rcc_calcif_n = st.selectbox("RCC calcification grade",key='rccalcn',options=[0,1,2,3])
    with c6:
        isc_calcif_n = st.selectbox("IS calcification",key='isccalcn',options=["Yes", "No"])
    
    with c7:
        surface_systole = st.number_input('Systolic aortic annular surface (mm²)',value=483)
        
    with c8:
        MS_s = st.number_input('Systolic membranous septal length(mm)',value=8)
    with c9:
        MS_d = st.number_input('Diastolic membranous septal length (mm)',value=8.9)
    with c10:
        marque_valve = st.selectbox("TAVI valve type",key="pmbrand",options=["Corevalve", "Edwards","Acurate","Portico"])
    with c11:
        IDepth = st.number_input('Implantation depth (mm)',value=5.3)   
    
        
        
    submitButton = st.form_submit_button(label = 'Predict')


#load model, set cache to prevent reloading
@st.cache_resource()
def load_model():
    with open(r"models/ensemble_models_per.pkl", "rb") as input_file:
        models = pickle.load(input_file)
    return models


#@st.cache_resource()
def load_scaler():
    with open(r"models/ensemble_scaler_per.pkl", "rb") as input_file:
        scalers = pickle.load(input_file)
    return scalers


@st.cache_resource()
def load_impute():
    with open(r"models/ensemble_dict_impute_per.pkl", "rb") as input_file:
        dicts_impute = pickle.load(input_file)
    return dicts_impute

with st.spinner("Loading Model...."):
    models = load_model()
    dicts_impute = load_impute()
    scalers = load_scaler()

    


#st.write("Predicting Class...") 
with st.spinner("Prediction..."):
    
    # preprocessing
    diff_MS = MS_d - MS_s
    syncope_Oui = 1 if syncope_Oui == "Yes" else 0
    isc_calcif_n = 1 if isc_calcif_n == "Yes" else 0
    bloc_branche_pre_bbd = 1 if bloc_branche_pre_bbd == "Yes" else 0
    calc_risque_n = ncc_calcif_n + rcc_calcif_n + isc_calcif_n

    delta_msid_d = MS_d - IDepth
    
    marque_COREVALVE = 1 if marque_valve == "Corevalve" else 0
    marque_ACURATE = 1 if marque_valve == "Acurate" else 0
    marque_EDWARDS = 1 if marque_valve == "Edwards" else 0

    bool_warning = False 
    if MS_d<1.5 or MS_d>15.30:
        bool_warning = True
    if MS_s<2.0 or MS_s> 14.61:
        bool_warning = True
    if pr_pre_tavi<90 or pr_pre_tavi>344: 
        bool_warning = True
    if surface_systole<300 or surface_systole>724:
        bool_warning = True
    if IDepth<0 or IDepth>16.1:
        bool_warning = True
    if bool_warning:
        st.write(":warning: Warning Results might not be reliable because:")
    if MS_d<1.5 or MS_d>15.30:
        st.write("Our study population had a dMS (mm) between 1.5 and 15.30 (mm)")
    if MS_s<2.0 or MS_s> 14.61:
        st.write("Our study population had a sMS (mm) between 2 and 14.61 (mm) ")
    if pr_pre_tavi<90 or pr_pre_tavi>344: 
        st.write("Our study population had a pre-TAVI PR surface between 90 and 344 (ms)")
    if surface_systole<300 or surface_systole>724:
        st.write("Our study population had a systolic aortic annular surface between 300 and 724 (mm²) ")
    if IDepth<0 or IDepth>16.1:
        st.write("Our study population had an implantation depth between 0 and 16.1 (mm) ")
        
    
    
    pred_arr = np.array([[MS_d,delta_msid_d,pr_pre_tavi,surface_systole,MS_s,calc_risque_n,
                          syncope_Oui,marque_ACURATE,marque_COREVALVE,marque_EDWARDS,bloc_branche_pre_bbd]])
        
        
    
    pred_df = pd.DataFrame(pred_arr,columns=cols)
    print(pred_df.head())
    pred_dfs = [impute_missing_values(pred_df,dict_impute) for dict_impute in dicts_impute]
    dfs_scaled_ = [scaler.transform(df_[to_rescale_]) for df_,scaler in zip(pred_dfs,scalers)]
    dfs_scaled = [pd.DataFrame(columns=to_rescale_,data=df_scaled_) for df_scaled_ in dfs_scaled_]
    dfs_cat = [pd.concat([df_scaled,pred_df[to_encode_]],axis=1) for df_scaled in dfs_scaled]
    pred= round( np.array([model.predict_proba(pred_df_)[0][1] for pred_df_,model in zip(dfs_cat,models)]).mean()*100,2)
    
    if pred>90:
        st.write("PMI risk probability >90 %")
    elif pred<10:
        st.write("PMI risk probability <10 %")
    else:
        st.write("PMI risk probability :",pred,' %')