Saturday, November 23, 2024
HomeData ScienceCOVID-19 Mortality Triage with Streamlit, Pycaret, and Shap | by Cole Hagen...

COVID-19 Mortality Triage with Streamlit, Pycaret, and Shap | by Cole Hagen | Oct, 2022


Constructing a Scientific Choice Help System with Highly effective Python Instruments

Picture from Patrick Assale @ Unsplash

Background

I used to be not too long ago tasked with a challenge the place the objective was to examine how one can create a device that might assist clinicians determine mortality dangers in sufferers with COVID-19 coming into the intensive care unit. This device, also called a ‘scientific choice help system,’ is required to empower clinicians with data-driven well being info, reminiscent of earlier COVID-19 affected person outcomes or present affected person mortality threat, to make well-informed care choices.

As any true tinkerer would do, I assumed one of the simplest ways to envision one thing was to create it myself. And, as a python fanatic, I figured there can be loads of instruments accessible to make it attainable. Subsequently, this tutorial outlines how I created a COVID-19 scientific choice help system with highly effective python libraries and offers the assets so that you can recreate or reimagine the challenge your self.

Sneak Peak on the Closing Product: https://covidtriage.streamlitapp.com/

Define

I considered this challenge by means of the lens of a machine-learning drawback. Subsequently, the challenge was outlined as follows:

  1. Get knowledge (sufferers from the intensive care unit who had COVID-19)
  2. Prepare and check a machine studying mannequin (deceased vs. survived)
  3. Deploy a machine studying mannequin to a consumer interface

Putting in Libraries

Important libraries central to this challenge embody Pandas, Pycaret, Shap, and Streamlit. All of that are used to deal with particular wants.

  • Pandas: knowledge manipulation and evaluation
  • Pycaret: constructing low-code machine studying pipelines
  • Shap: evaluation and visualization of characteristic affect on mannequin predictions
  • Streamlit: python pushed app growth
  • Plotly: high-quality, interactive charts

To put in these libraries, open a command line immediate or terminal and enter the next.

pip set up pandas
pip set up pycaret
pip set up shap
pip set up streamlit
pip set up plotly

Further libraries on this tutorial are elements of Streamlit and have been used to enhance the consumer interface/ expertise.

pip set up streamlit_option_menu
pip set up streamlit_shap
pip set up streamlit_echarts

One of many main hurdles of this challenge was buying knowledge for mannequin coaching. Since no open supply databases have been accessible from people with COVID-19 in intensive care, I assumed the perfect route can be creating my very own. To take action, I discovered a paper addressing an identical drawback. The paper under outlines a number of key options that influenced predictions of mortality in COVID-19 sufferers. I then loosely reverse engineered these options to generate a proxy dataset.

import random as rand
import pandas as pd
import numpy as np
samples = 1000
age_m = 58.0
age_std = 9.0
bun_m = 16.0
bun_std = 6.5
creatine_m = 1.1
creatine = 0.3
inr_m = 1.2
inr_std = 0.1
survived = pd.DataFrame()
survived['Age'] = np.random.regular(loc=age_m,scale=age_std,measurement=samples)
survived['Gender'] = np.random.binomial(1, 0.367, measurement=samples)
survived['Blood Urea Nitrogen'] = np.random.regular(loc=bun_m,scale=bun_std,measurement=samples)
survived['Cardiovascular History'] = np.random.binomial(1, 0.291, measurement=samples)
survived['Neurological History'] = np.random.binomial(1, 0.16, measurement=samples)
survived['Int Norm Ratio'] = np.random.regular(loc=inr_m,scale=inr_std,measurement=samples)
age_m = 72.5
age_std = 8.25
bun_m = 30.0
bun_std = 9.0
creatine_m = 1.5
creatine = 0.4
inr_m = 1.3
inr_std = 0.1
deceased = pd.DataFrame()
deceased['Age'] = np.random.regular(loc=age_m,scale=age_std,measurement=samples)
deceased['Gender'] = np.random.binomial(1, 0.646, measurement=samples)
deceased['Blood Urea Nitrogen'] = np.random.regular(loc=bun_m,scale=bun_std,measurement=samples)
deceased['Cardiovascular History'] = np.random.binomial(1, 0.709, measurement=samples)
deceased['Neurological History'] = np.random.binomial(1, 0.840, measurement=samples)
deceased['Int Norm Ratio'] = np.random.regular(loc=inr_m,scale=inr_std,measurement=samples)

Then, mixed, shuffled, and saved the dataframe to characterize my mannequin coaching dataset.

practice = pd.concat([survived, deceased])
practice = practice.pattern(frac=1).reset_index(drop=True)
practice.to_csv('COVID_TRAIN.csv')

Subsequent, I used Pycaret’s supervised classification capabilities to setup, practice, and consider a mannequin figuring out deceased versus survived.

As soon as the mannequin was appropriate for my wants, I started creating the consumer interface. The three primary elements I felt essential for clinicians have been:

  • Ease of use
  • Interpretable mannequin predictions
  • Function exploration of present and previous sufferers

Streamlit provides the potential to make use of strictly python-syntax to construct lovely internet functions. Thus, the consumer interface is constructed solely with Streamlit and associated elements.

Setup

Set up libraries and set Streamlit web page configurations.

import streamlit as st
import pandas as pd
from streamlit_option_menu import option_menu
from pycaret.classification import *
import plotly.specific as px
import shap
from streamlit_shap import st_shap
from streamlit_echarts import st_echarts
#set settings for streamlit web page
st.set_page_config(format="vast",
page_title="COVID Triage",
page_icon="chart_with_upwards_trend")
#disguise streamlit menu bar
hide_streamlit_style = """
<type>
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
</type>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)

Mannequin

Initialize coaching knowledge and mannequin.

#use pandas to learn covid knowledge for mannequin coaching and creation
practice = pd.read_csv('COVID_TRAIN.csv')
#use pycaret to preprocess and practice a choice tree supervised ML mannequin
exp = setup(practice, goal = 'class', silent=True, verbose=False)
dt = create_model('dt')

Menu Bar

Create a menu bar to modify between login and COVID triage.

#choice menu from streamlit element streamlit_option_menu
with st.sidebar:
chosen = option_menu(None, ["Log In", "COVID Triage"],
icons=['house', "list-task"],
menu_icon="solid", default_index=0, orientation="vertical")

Login Web page

Create logic for easy non-functioning login web page.

if chosen == 'Log In':
st.title('Covid 19 Mortality Danger Scientific Choice Help System')
if 'user_name' not in st.session_state:
st.session_state.user_name = 'Person Identify'
user_name = st.text_input("Person Identify", worth = st.session_state.user_name)
st.session_state.user_name = user_name
password = st.text_input("Password", kind="password")
st.session_state.password = password
if st.session_state.password:
sc = "Welcome " + st.session_state.user_name + " please proceed to COVID Triage"
st.success(sc)

COVID-19 Triage Web page — Person Inputs

Create widgets to take consumer enter similar to options within the coaching knowledge.

#covid triage web page
#characteristic inputs correspond to coaching knowledge
if chosen == 'COVID Triage':
col1, col2, col3= st.columns(3)
with col1:
identify = st.text_input("Affected person ID")
with col2:
gender = st.selectbox("Gender", (0, 1), assist = "0 = Feminine, 1 = Male")
with col3:
age = st.number_input("Age", step = 1)
ccol1, ccol2, ccol3, ccol4= st.columns(4)
with ccol1:
bun = st.slider("Blood Urea Nitrogen", min_value=0, max_value=60)
with ccol2:
inr = st.slider("Worldwide Normalized Ratio", min_value=0.88, max_value=1.66)
with ccol3:
honeuro = st.selectbox("Historical past of Neurological Dysfunction", (0, 1), assist = "0 = No historical past of neurological problems, 1 = Historical past of neurological problems")
with ccol4:
hocard = st.selectbox("Historical past of Cardiovascular Dysfunction", (0, 1), assist = "0 = No historical past of cardiovascular problems, 1 = Historical past of cardiovascular problems")

check = pd.DataFrame({"Age": [age], "Gender":[int(gender)],"Blood Urea Nitrogen":[bun], "Cardiovascular Historical past":[int(hocard)], "Neurological Historical past":[int(honeuro)], "Int Norm Ratio":[inr]})

COVID-19 Triage Web page —Mannequin Prediction and Confidence

Setup the show and logic for prediction and confidence values.

preds = predict_model(dt, check)
st.sidebar.textual content('Danger Prediction and Confidence')
preds['Mortality Risk'] = preds['Label'].substitute([0,1], ['Low Mortality Risk', 'High Mortality Risk'])
if preds['Label'].iloc[0] == 0:
#show if label = 0 (low mortality threat)
st.sidebar.data(preds['Mortality Risk'].iloc[0])
liquidfill_option = {
"collection": [{"type": "liquidFill", "data": [preds['Score'].iloc[0]]}]
}
if preds['Label'].iloc[0] == 1:
#show if label = 1 (excessive mortality threat)
st.sidebar.error(preds['Mortality Risk'].iloc[0])
liquidfill_option = {
"collection": [{"type": "liquidFill", "data": [preds['Score'].iloc[0]], 'coloration': ['#ff0000']}]
}
with st.sidebar:
#liquid fill chart with confidence worth and coloration similar to mortality threat (excessive = purple, low = blue)
st_echarts(liquidfill_option)
#shapley additive rationalization of characteristic weights on mannequin prediction
explainer = shap.KernelExplainer(mannequin = dt.predict_proba, knowledge = get_config('X_train'), hyperlink = "identification")
shap_value_single = explainer.shap_values(X = check)
st_shap(shap.force_plot(base_value = explainer.expected_value[0],
shap_values = shap_value_single[0], options=check
))

COVID-19 Triage Web page — Affected person Graphs

Setup logic to show present affected person relationships with earlier sufferers and options.

st.textual content("Earlier COVID-19 ICU Sufferers")
df = practice.copy()
for cols in df.drop(['Unnamed: 0', 'class'], axis=1).columns:
df['Mortality Outcome'] = practice['class'].substitute([1,0], ['Deceased', 'Survived'])
fig = px.histogram(df, x = cols, coloration = 'Mortality Consequence',
color_discrete_map = {'Deceased':'purple','Survived':'blue'})
fig.add_vline(x=check[cols].iloc[0], line_dash="dot",
annotation_text="Present Affected person",
annotation_position="prime left",
annotation_font_size=10,
annotation_font_color="grey"
)
st.plotly_chart(fig, config= dict(
displayModeBar = False))

Placing It All Collectively

The consumer interface was able to be deployed. The ultimate steps included saving the necessities, including all recordsdata to GitHub, and deploying to the Streamlit sharing service. To entry the ultimate product, go to the hyperlink under or construct it your self in your native machine from my covidtriageStreamlit repository.

https://covidtriage.streamlitapp.com/

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments