| import streamlit as st |
| import pandas as pd |
| import numpy as np |
| import matplotlib.pyplot as plt |
| import seaborn as sns |
| from sklearn.preprocessing import StandardScaler |
| from sklearn.model_selection import train_test_split |
| import keras |
| from keras.models import Sequential |
| from keras.layers import Dense |
| from sklearn.metrics import confusion_matrix, classification_report |
| import plotly.express as px |
| import plotly.graph_objects as go |
|
|
| def load_and_prep_data(): |
| |
| HDNames = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', 'thalach', |
| 'exang', 'oldpeak', 'slope', 'ca', 'hal', 'HeartDisease'] |
| |
| |
| data = pd.read_excel('Ch3.ClevelandData.xlsx', names=HDNames) |
| |
| |
| data_new = data.replace("?", np.nan) |
| data_new = data_new.dropna() |
| |
| return data_new |
|
|
| def scale_and_split_data(data_new): |
| feature_names = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg', |
| 'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'hal'] |
| |
| features = pd.DataFrame(data_new.iloc[:, 0:13], columns=feature_names) |
| target = pd.DataFrame(data_new.iloc[:,13], columns=["HeartDisease"]) |
| |
| scaler = StandardScaler() |
| FeatureScaled = scaler.fit_transform(features) |
| FeatureScaled = pd.DataFrame(FeatureScaled, columns=feature_names) |
| |
| X_train, X_test, y_train, y_test = train_test_split( |
| FeatureScaled, target, test_size=0.30, random_state=5 |
| ) |
| |
| return X_train, X_test, y_train, y_test, FeatureScaled, scaler, features |
|
|
| def create_model(): |
| model = Sequential() |
| model.add(Dense(30, input_dim=13, activation="tanh")) |
| model.add(Dense(20, activation="tanh")) |
| model.add(Dense(1, activation="sigmoid")) |
| |
| model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy']) |
| return model |
|
|
| def plot_correlation_heatmap(FeatureScaled): |
| corrMatrix = FeatureScaled.corr() |
| fig = px.imshow(corrMatrix, |
| labels=dict(color="Correlation"), |
| title="Feature Correlation Heatmap") |
| return fig |
|
|
| def plot_feature_distributions(FeatureScaled): |
| fig = go.Figure() |
| for column in FeatureScaled.columns: |
| fig.add_trace(go.Box(y=FeatureScaled[column], name=column)) |
| fig.update_layout(title="Feature Distributions", |
| showlegend=False, |
| height=600) |
| return fig |
|
|
| def make_prediction(model, scaler, features, input_data): |
| |
| scaled_input = scaler.transform([input_data]) |
| |
| prediction = model.predict(scaled_input) |
| return prediction[0][0] |
|
|
| def main(): |
| st.set_page_config(page_title="Heart Disease Classification", layout="wide") |
| |
| st.title("Heart Disease Classification") |
| st.markdown(""" |
| This application predicts the likelihood of heart disease based on various medical parameters. |
| The model uses neural networks to make predictions with an accuracy of approximately 82%. |
| """) |
| |
| |
| with st.spinner("Loading and preparing data..."): |
| data_new = load_and_prep_data() |
| X_train, X_test, y_train, y_test, FeatureScaled, scaler, features = scale_and_split_data(data_new) |
| |
| |
| with st.expander("Model Training"): |
| if st.button("Train Model"): |
| with st.spinner("Training model..."): |
| model = create_model() |
| history = model.fit(X_train, y_train, epochs=1000, verbose=0) |
| score = model.evaluate(X_test, y_test, verbose=0) |
| st.success(f"Model trained! Accuracy: {score[1]:.2f}") |
| st.session_state['model'] = model |
| st.session_state['scaler'] = scaler |
| |
| |
| st.header("Data Visualization") |
| viz_option = st.selectbox( |
| "Choose visualization", |
| ["Correlation Heatmap", "Feature Distributions"] |
| ) |
| |
| if viz_option == "Correlation Heatmap": |
| st.plotly_chart(plot_correlation_heatmap(FeatureScaled), use_container_width=True) |
| else: |
| st.plotly_chart(plot_feature_distributions(FeatureScaled), use_container_width=True) |
| |
| |
| st.header("Make Prediction") |
| |
| col1, col2, col3 = st.columns(3) |
| |
| with col1: |
| age = st.number_input("Age", min_value=20, max_value=100, value=50) |
| sex = st.selectbox("Sex", [0, 1], format_func=lambda x: "Female" if x == 0 else "Male") |
| cp = st.selectbox("Chest Pain Type", [1, 2, 3, 4]) |
| trestbps = st.number_input("Resting Blood Pressure (mmHg)", 90, 200, 120) |
| chol = st.number_input("Cholesterol (mg/dl)", 100, 600, 250) |
| |
| with col2: |
| fbs = st.selectbox("Fasting Blood Sugar > 120 mg/dl", [0, 1], format_func=lambda x: "No" if x == 0 else "Yes") |
| restecg = st.selectbox("Resting ECG Results", [0, 1, 2]) |
| thalach = st.number_input("Maximum Heart Rate", 70, 220, 150) |
| exang = st.selectbox("Exercise Induced Angina", [0, 1], format_func=lambda x: "No" if x == 0 else "Yes") |
| |
| with col3: |
| oldpeak = st.number_input("ST Depression", 0.0, 10.0, 1.0) |
| slope = st.selectbox("ST Slope", [1, 2, 3]) |
| ca = st.selectbox("Number of Major Vessels", [0, 1, 2, 3]) |
| hal = st.selectbox("Thalassemia", [3, 6, 7]) |
| |
| if st.button("Predict"): |
| if 'model' not in st.session_state: |
| st.error("Please train the model first!") |
| else: |
| input_data = [age, sex, cp, trestbps, chol, fbs, restecg, thalach, |
| exang, oldpeak, slope, ca, hal] |
| prediction = make_prediction(st.session_state['model'], |
| st.session_state['scaler'], |
| features, |
| input_data) |
| |
| risk_level = "High Risk" if prediction > 0.5 else "Low Risk" |
| risk_color = "red" if prediction > 0.5 else "green" |
| |
| st.markdown(f""" |
| <h2 style='text-align: center; color: {risk_color};'> |
| {risk_level} |
| </h2> |
| <p style='text-align: center;'> |
| Probability of heart disease: {prediction:.2%} |
| </p> |
| """, unsafe_allow_html=True) |
|
|
| if __name__ == "__main__": |
| main() |