Yijie7 commited on
Commit
0a8ccf5
1 Parent(s): af549e4

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +223 -0
  2. saved_model/model1.pkl +3 -0
app.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import joblib
2
+ import pandas as pd
3
+ import streamlit as st
4
+ from streamlit_shap import st_shap
5
+ import shap
6
+ import numpy as np
7
+
8
+ # Load Model
9
+ model1 = joblib.load('saved_model/model1.pkl')
10
+ predictor = model1
11
+ st.title('Prediction of postoperative delirium')
12
+ st.write('#### For geriatric patients undergoing cardiac surgery')
13
+
14
+ asa_options = {
15
+ "Ⅰ": -1.38814621350096,
16
+ "Ⅱ": 0.511717257330668,
17
+ "Ⅲ": -0.395963387679586,
18
+ "Ⅳ": -1.4681889211745,
19
+ "Ⅴ": -1.4681889211745
20
+ }
21
+ hypertension_options = {
22
+ "No": 3.68035036162672,
23
+ "Ⅰ": -0.544235316554776,
24
+ "Ⅱ": -0.844034612101507,
25
+ "Ⅲ": -0.943664453050348
26
+ }
27
+ dm_options = {
28
+ "No": 0.122040527036218,
29
+ "Non-insulin dependent": -0.638909566289975,
30
+ "Insulin dependent": -1.7072632945609
31
+ }
32
+ illness_options = {
33
+ "Yes": 1,
34
+ "No": 0
35
+ }
36
+ os_options = {
37
+ "": 2.70805020110221,
38
+ "Dermatological surgery": 2.22692108269007,
39
+ "Limb surgery": 0.752566153571913,
40
+ "Arthroplasty": 0.532164318353033,
41
+ "Spinal surgery": 1.6127011607198,
42
+ "Head and neck surgery": 2.52541407124607,
43
+ "Upper abdomen surgery": -0.649878597660549,
44
+ "Lower abdomen surgery": -0.464370149938076,
45
+ "Abdomen surgery": -2.20389571615324,
46
+ "Thoracic surgery": 0.416954872664665,
47
+ "cranial surgery": 0.0899556968720493,
48
+ "Thoracoabdominal surgery": 0.0899556968720493,
49
+ "Vascular surgery": 0.281010933634758
50
+ }
51
+ es_options = {
52
+ "No": 0.0175056050012399,
53
+ "yes": -1.97901454494049
54
+ }
55
+ eot_options = {
56
+ "": 2.944439,
57
+ "1h": 0.768487407184522,
58
+ "1h-1.5h": 0.523271451886264,
59
+ "1.5-2h": -0.170387892577323,
60
+ "2h-3h": -0.345346138774783,
61
+ ">=3h": -0.749296055496119
62
+ }
63
+ up_options = {
64
+ "": 3.59497984361465,
65
+ "No": 0.0374632790768398,
66
+ "+/-": -0.465955759499621,
67
+ "1+": -1.18050684872272,
68
+ "2+": -1.18050684872272,
69
+ "3+": -1.4681889211745
70
+ }
71
+
72
+ sccl_zh = '血清胱抑素C测定'
73
+ asa_zh = 'ASA分级'
74
+ hypertension_zh = '高血压_分级'
75
+ dm_zh = '糖尿病_控制方式'
76
+ os_zh = '手术风险评估_手术部位'
77
+ es_zh = '急诊'
78
+ eot_zh = '手术时长_分钟'
79
+ up_zh = '尿蛋白定性'
80
+ coovorbcdw_zh = 'RBC分布宽度CV'
81
+ inr_zh = '国际标准化比值'
82
+
83
+ sccl_en = 'Serum cystatin C level (mg/L)'
84
+ asa_en = 'ASA classification'
85
+ hypertension_en = 'Hypertension'
86
+ dm_en = 'Diabetes mellitus'
87
+ os_en = 'Operation site'
88
+ es_en = 'Emergency surgery'
89
+ eot_en = 'Estimated operation time'
90
+ up_en = 'Urine protein'
91
+ coovorbcdw_en = 'RDW-CV (%)'
92
+ inr_en = 'International normalized ratio'
93
+
94
+ # Form
95
+ with st.form(key='form_parameters'):
96
+ col1, col2 = st.columns(2) # Create two columns
97
+
98
+ # First column
99
+ with col1:
100
+ sccl = st.number_input('Serum cystatin C level (mg/L)')
101
+ asa = st.selectbox('ASA classification', list(asa_options.keys()))
102
+ asa_woe = asa_options.get(asa, 0)
103
+ hypertension = st.selectbox('Hypertension', list(hypertension_options.keys()))
104
+ hypertension_woe = hypertension_options.get(hypertension, 0)
105
+ dm = st.selectbox('Diabetes mellitus', list(dm_options.keys()))
106
+ dm_woe = dm_options.get(dm, 0)
107
+ os = st.selectbox('Operation site', list(os_options.keys()))
108
+ os_woe = os_options.get(os, 0)
109
+ es = st.selectbox('Emergency surgery', list(es_options.keys()))
110
+ es_woe = es_options.get(es, 0)
111
+
112
+ sccl_woe = 0
113
+ if sccl == '':
114
+ sccl_woe = 2.99885240089024
115
+ sccl = np.nan
116
+ elif float(sccl) < 0.87:
117
+ sccl_woe = 0.645372775418255
118
+ elif (float(sccl) >= 0.87) and (float(sccl) < 0.95):
119
+ sccl_woe = 0.369025188040581
120
+ elif (float(sccl) >= 0.95) and (float(sccl) < 1.03):
121
+ sccl_woe = -0.10610555179212
122
+ elif (float(sccl) >= 1.03) and (float(sccl) < 1.13):
123
+ sccl_woe = 0.0898098195273885
124
+ elif float(sccl) >= 1.13:
125
+ sccl_woe = -0.925496780781878
126
+ sccl = float(sccl)
127
+
128
+
129
+ # Second column
130
+ with col2:
131
+ eot = st.selectbox('Estimated operation time', list(eot_options.keys()))
132
+ eot_woe = eot_options.get(eot, 0)
133
+ up = st.selectbox('Urine protein', list(up_options.keys()))
134
+ up_woe = up_options.get(up, 0)
135
+ coovorbcdw = st.number_input('RDW-CV (%)')
136
+ inr = st.number_input('International normalized ratio')
137
+
138
+ coovorbcdw_woe = 0
139
+ if coovorbcdw == '':
140
+ coovorbcdw_woe = 3.34041249059303
141
+ coovorbcdw = np.nan
142
+ elif float(coovorbcdw) < 12.7:
143
+ coovorbcdw_woe = 0.398231895412054
144
+ elif (float(coovorbcdw) >= 12.7) and (float(coovorbcdw) < 13.3):
145
+ coovorbcdw_woe = 0.048813472291148
146
+ elif (float(coovorbcdw) >= 13.3) and (float(coovorbcdw) < 13.7):
147
+ coovorbcdw_woe = -0.104034700025362
148
+ elif (float(coovorbcdw) >= 13.7) and (float(coovorbcdw) < 14.6):
149
+ coovorbcdw_woe = -0.0861214293356946
150
+ elif float(coovorbcdw) >= 14.6:
151
+ coovorbcdw_woe = -0.646032944021757
152
+ coovorbcdw = float(coovorbcdw)
153
+
154
+ inr_woe = 0
155
+ if inr == '':
156
+ inr_woe = 3.38627173144548
157
+ inr = np.nan
158
+ elif float(inr) < 0.92:
159
+ inr_woe = -0.000131790754127941
160
+ elif (float(inr) >= 0.92) and (float(inr) < 0.95):
161
+ inr_woe = 0.383156538484155
162
+ elif (float(inr) >= 0.95) and (float(inr) < 0.98):
163
+ inr_woe = 0.282044225138759
164
+ elif (float(inr) >= 0.98) and (float(inr) < 1.03):
165
+ inr_woe = -0.104889279197154
166
+ elif float(inr) >= 1.03:
167
+ inr_woe = -0.769604383885953
168
+ inr = float(inr)
169
+
170
+ st.markdown('---')
171
+ submitted = st.form_submit_button('Predict')
172
+
173
+ # 构建预测样本(原始数据)
174
+ data1 = {
175
+ hypertension_zh: hypertension,
176
+ up_zh: up,
177
+ dm_zh: dm,
178
+ os_zh: os,
179
+ asa_zh: asa,
180
+ eot_zh: eot,
181
+ sccl_zh: sccl,
182
+ coovorbcdw_zh: coovorbcdw,
183
+ inr_zh: inr,
184
+ es_zh: es
185
+ }
186
+ X_train_1 = pd.DataFrame(data1, index=[0])
187
+
188
+ data2 = {
189
+ hypertension_zh: hypertension_woe,
190
+ up_zh: up_woe,
191
+ dm_zh: dm_woe,
192
+ os_zh: os_woe,
193
+ asa_zh: asa_woe,
194
+ eot_zh: eot_woe,
195
+ sccl_zh: sccl_woe,
196
+ coovorbcdw_zh: coovorbcdw_woe,
197
+ inr_zh: inr_woe,
198
+ es_zh: es_woe
199
+ }
200
+ X_train = pd.DataFrame(data2, index=[0])
201
+
202
+ if submitted:
203
+ # Predict
204
+ y_prob_train = model1.predict_proba(X_train)
205
+
206
+ value = y_prob_train[0][0]
207
+ with st.container():
208
+ st.write('### The possibility of xx is \n'+ str(value))
209
+ st.write('*Threshold is xx*')
210
+ st.markdown('---')
211
+ with st.container():
212
+ st.write('## SHAP force plot for this patient')
213
+
214
+ explainer = shap.TreeExplainer(model1)
215
+ shap_values = explainer.shap_values(X_train) # 这里的X_train替换成输进来的值,要woe版的数据,不是原始版数据,有个对应文件用来映射数值与woe
216
+ print(shap_values.shape)
217
+ X1_ = X_train_1.fillna(0) # 这里替换成输进来的值的原始数据
218
+ # 替换英文名
219
+ X1_.columns = [hypertension_en, up_en, dm_en, os_en, asa_en, eot_en, sccl_en, coovorbcdw_en, inr_en, es_en]
220
+
221
+ # Visualize SHAP values
222
+ # Visualize SHAP values
223
+ st_shap(shap.force_plot(explainer.expected_value, shap_values[0], X1_.iloc[0]), height=400, width=1000)
saved_model/model1.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ddc52af2cc3e719e73b40648f9022163329649d9d32131ac2c6ec299a78f802a
3
+ size 72508