|
import streamlit as st |
|
import json |
|
import requests |
|
import pandas as pd |
|
import numpy as np |
|
import pickle |
|
from PIL import Image |
|
|
|
image = Image.open('logo.png') |
|
|
|
st.image(image) |
|
|
|
|
|
|
|
st.title("Калькулятор прогнозирования значения фракции выброса левого желудочка") |
|
st.header("Кафедра пропедевтической терапии с курсом кардиологи") |
|
|
|
|
|
|
|
nyha = 2 |
|
vozrast = 65 |
|
ckf = 71.5 |
|
pim = 2 |
|
fp = 2 |
|
cd = 3 |
|
nt = 394.05 |
|
st2 = 30.8 |
|
|
|
|
|
|
|
|
|
f1 = st.selectbox( |
|
'Функциональный класс по NYHA', |
|
('1', '2', '3', '4')) |
|
nyha_check = st.checkbox('NYHA', value=True) |
|
|
|
f2 = st.text_input('Возраст лет') |
|
vozrast_check = st.checkbox('Возраст', value=True) |
|
|
|
f3 = st.text_input('Скорость клубочковой фильтрации по формуле CKD-EPI (мл/мин/1,73м2)') |
|
ckf_check = st.checkbox('СКФ CKD-EPI', value=True) |
|
|
|
f4 = st.selectbox( |
|
'Перенесенный инфаркт миокарда', |
|
('Да', 'Нет')) |
|
pim_check = st.checkbox('ПИМ', value=True) |
|
|
|
f5 = st.selectbox( |
|
'Фибрилляция/Трепетание предсердий', |
|
('Да', 'Нет')) |
|
fp_check = st.checkbox('ФП', value=True) |
|
|
|
f6 = st.selectbox( |
|
'Сахарный диабет ', |
|
('Да', 'НТГ', 'Нет')) |
|
cd_check = st.checkbox('СД', value=True) |
|
|
|
f7 =st.text_input('Концентрация NT-proBNP (пг/мл)') |
|
nt_check = st.checkbox('NT_proBNP', value=True) |
|
|
|
f8 = st.text_input('Концентрация ST2 (нг/мл)') |
|
st2_check = st.checkbox('ST2', value=True) |
|
|
|
|
|
|
|
filename_model = 'class_model_logreg.pickle' |
|
filename_scaler = 'class_scaler.pickle' |
|
filename_ohe = 'class_one_hot_enc.pickle' |
|
filename_cat = 'class_model_catboost.pickle' |
|
|
|
|
|
loaded_model = pickle.load(open(filename_model, 'rb')) |
|
loaded_scaler = pickle.load(open(filename_scaler, 'rb')) |
|
loaded_ohe = pickle.load(open(filename_ohe, 'rb')) |
|
loaded_cat = pickle.load(open(filename_cat, 'rb')) |
|
|
|
|
|
|
|
def get_interval_by_class(a): |
|
pref = 'Прогнозируемое значение фракции выброса левого желудочка ' |
|
if a == 1: |
|
return pref + 'больше 50%' |
|
elif a == 2: |
|
return pref + 'лежит в интервале от 40 до 49%' |
|
else: |
|
return pref + 'меньше 40%' |
|
|
|
|
|
if st.button('OK'): |
|
|
|
if nyha_check: |
|
if f1 == '': |
|
st.write('Вы не ввели NYHA, будет использовано медианное значение') |
|
f1 = nyha |
|
else: |
|
f1 = 0 |
|
|
|
if vozrast_check: |
|
if f2 == '': |
|
st.write('Вы не ввели возраст, будет использовано медианное значение') |
|
f2 = vozrast |
|
else: |
|
f2 = 0 |
|
|
|
if ckf_check: |
|
if f3 == '': |
|
st.write('Вы не ввели СКФ, будет использовано медианное значение') |
|
f3 = ckf |
|
else: |
|
f3 = 0 |
|
|
|
if pim_check: |
|
if f4 == '': |
|
st.write('Вы не ввели ПИМ, будет использовано медианное значение') |
|
f4 = pim |
|
else: |
|
f4 = 0 |
|
|
|
if fp_check: |
|
if f5 == '': |
|
st.write('Вы не ввели ФП, будет использовано медианное значение') |
|
f5 = fp |
|
else: |
|
f5 = 0 |
|
|
|
if cd_check: |
|
if f6 == '': |
|
st.write('Вы не ввели СД, будет использовано медианное значение') |
|
f6 = cd |
|
else: |
|
f6 = 0 |
|
|
|
if nt_check: |
|
if f7 == '': |
|
st.write('Вы не ввели NT_proBNP, будет использовано медианное значение') |
|
f7 = nt |
|
else: |
|
f7 = 0 |
|
|
|
if st2_check: |
|
if f8 == '': |
|
st.write('Вы не ввели ST2, будет использовано медианное значение') |
|
f8 = st2 |
|
else: |
|
f8 = 0 |
|
|
|
|
|
|
|
|
|
if f4 == 'Да': |
|
f4 = '1' |
|
else: |
|
f4 = '2' |
|
|
|
if f5 == 'Да': |
|
f5 = '1' |
|
elif f5 == 'НТГ': |
|
f5 = '2' |
|
else: |
|
f5 = '3' |
|
|
|
if f6 == 'Да': |
|
f6 = '1' |
|
else: |
|
f6 = '2' |
|
|
|
line = np.array([[str(f1), float(f2), float(f3), str(f4), str(f5), str(f6), float(f7), float(f8)]]) |
|
|
|
picked_cols = ['NYHA', 'возраст', 'СКФ CKD-EPI', 'ПИМ', 'ФП', 'СД', 'NT_proBNP', 'ST2'] |
|
categorical_cols = ['NYHA', 'ПИМ', 'ФП', 'СД'] |
|
num_cols = ['возраст', 'СКФ CKD-EPI', 'NT_proBNP', 'ST2'] |
|
|
|
X = pd.DataFrame(line, columns=picked_cols) |
|
|
|
X_transform = pd.DataFrame(loaded_ohe.transform(X[categorical_cols]).toarray()).set_index(X.index) |
|
X_transform.columns = loaded_ohe.get_feature_names_out() |
|
|
|
X_encode = pd.concat([X_transform, X[num_cols]], axis=1) |
|
|
|
line_norm = loaded_scaler.transform(X_encode) |
|
|
|
|
|
|
|
|
|
|
|
res = loaded_cat.predict(line_norm)[0] |
|
st.header(get_interval_by_class(int(res))) |
|
|