-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
133 lines (113 loc) · 4.96 KB
/
Copy pathapp.py
File metadata and controls
133 lines (113 loc) · 4.96 KB
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
import streamlit as st
import pandas as pd
import joblib
# Load saved model, scaler, and expected columns
# Caching resources to improve performance
@st.cache_resource
def load_resources():
try:
model = joblib.load("KNN_heart.pkl")
scaler = joblib.load("scaler.pkl")
expected_columns = joblib.load("columns.pkl")
# Load heart.csv to compute original stats for pre-scaling
# This matches the logic in api.py and the original notebook
df_raw = pd.read_csv("heart.csv")
pre_scale_cols = ['RestingBP', 'Cholesterol', 'MaxHR', 'Oldpeak']
pre_scale_stats = {}
for col in pre_scale_cols:
pre_scale_stats[col] = {
'mean': df_raw[col].mean(),
'std': df_raw[col].std()
}
return model, scaler, expected_columns, pre_scale_stats
except Exception as e:
return None, None, None, None
model, scaler, expected_columns, pre_scale_stats = load_resources()
if model is None:
st.error("Error loading model or data files. Please ensure 'KNN_heart.pkl', 'scaler.pkl', 'columns.pkl', and 'heart.csv' are in the directory.")
st.stop()
# Sidebar content
with st.sidebar:
st.image("https://cdn-icons-png.flaticon.com/512/2503/2503509.png", width=100)
st.title("About")
st.info(
"""
This application uses a Machine Learning model (KNN) to predict the risk of heart disease based on various health parameters.
**Accuracy**: ~87% (Estimated)
**Developed by**: Ankit
"""
)
st.markdown("---")
st.write("### Instructions")
st.write("1. Fill in all the details in the main form.")
st.write("2. Click the 'Predict Risk' button.")
st.write("3. Review the result.")
# Main content
st.title("❤️ Heart Stroke Prediction System")
st.markdown("### Please provide the patient's details below")
# Create a form to group inputs
with st.form("prediction_form"):
col1, col2 = st.columns(2, gap="medium")
with col1:
st.subheader("Personal Info")
age = st.slider("Age", 18, 100, 40, help="Age of the patient")
sex = st.selectbox("Sex", ["M", "F"], format_func=lambda x: "Male" if x == "M" else "Female")
resting_bp = st.number_input("Resting Blood Pressure (mm Hg)", 80, 200, 120)
cholesterol = st.number_input("Cholesterol (mg/dL)", 100, 600, 200)
fasting_bs = st.selectbox("Fasting Blood Sugar > 120 mg/dL", [0, 1], format_func=lambda x: "Yes" if x == 1 else "No")
with col2:
st.subheader("Medical History")
chest_pain = st.selectbox("Chest Pain Type", ["ATA", "NAP", "TA", "ASY"],
help="ATA: Atypical Angina, NAP: Non-Anginal Pain, TA: Typical Angina, ASY: Asymptomatic")
resting_ecg = st.selectbox("Resting ECG", ["Normal", "ST", "LVH"])
max_hr = st.slider("Max Heart Rate", 60, 220, 150)
exercise_angina = st.selectbox("Exercise-Induced Angina", ["Y", "N"], format_func=lambda x: "Yes" if x == "Y" else "No")
oldpeak = st.slider("Oldpeak (ST Depression)", 0.0, 6.0, 1.0)
st_slope = st.selectbox("ST Slope", ["Up", "Flat", "Down"])
st.markdown("---")
submitted = st.form_submit_button("Predict Heart Disease Risk")
# Logic for prediction
if submitted:
# Create a raw input dictionary
raw_input = {
'Age': age,
'RestingBP': resting_bp,
'Cholesterol': cholesterol,
'FastingBS': fasting_bs,
'MaxHR': max_hr,
'Oldpeak': oldpeak,
'Sex_' + sex: 1,
'ChestPainType_' + chest_pain: 1,
'RestingECG_' + resting_ecg: 1,
'ExerciseAngina_' + exercise_angina: 1,
'ST_Slope_' + st_slope: 1
}
# Feature Engineering (High_Cholesterol)
raw_input['High_Cholesterol'] = 1 if cholesterol > 240 else 0
# Pre-Scaling (Manual Standardization for specific columns)
for col in pre_scale_stats:
if col in raw_input:
mean = pre_scale_stats[col]['mean']
std = pre_scale_stats[col]['std']
# Update metric in raw_input
raw_input[col] = (raw_input[col] - mean) / std
# Create input dataframe
input_df = pd.DataFrame([raw_input])
# Fill in missing columns with 0s and reorder
for col in expected_columns:
if col not in input_df.columns:
input_df[col] = 0
input_df = input_df[expected_columns]
# Scale the input (Final Pass)
scaled_input = scaler.transform(input_df)
# Make prediction
prediction = model.predict(scaled_input)[0]
# Show result with animation
st.markdown("### Prediction Result")
if prediction == 1:
st.error("⚠️ **High Risk Detected**")
st.warning("The model predicts a high probability of heart disease. Please consult a cardiologist immediately.")
else:
st.balloons()
st.success("✅ **Low Risk Detected**")
st.info("The model predicts a low probability of heart disease. Keep maintaining a healthy lifestyle!")