Musabbirkm commited on
Commit
8d85da5
·
verified ·
1 Parent(s): df4101d

Upload 8 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/banner.png filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ import pandas as pd
4
+
5
+
6
+ # Page config must be first command
7
+ st.set_page_config(
8
+ page_title="❤️ Heart Disease Prediction System",
9
+ page_icon="❤️",
10
+ layout="wide",
11
+ initial_sidebar_state="expanded"
12
+ )
13
+
14
+
15
+ # Load the pre-trained model
16
+ @st.cache_resource
17
+ def load_model():
18
+ try:
19
+ production_model = joblib.load('models/uci_heart_disease_model.pkl')
20
+ return production_model['model'], production_model['metadata']['threshold']
21
+ except Exception as e:
22
+ st.error(f"Error loading model: {e}")
23
+ st.stop()
24
+
25
+
26
+ model, optimal_threshold = load_model()
27
+
28
+
29
+ # Function to process input and make predictions
30
+ def predict_heart_disease(user_input):
31
+ try:
32
+ # Feature engineering
33
+ user_input['hr_age_ratio'] = user_input['thalach'] / (user_input['age'] + 1e-5)
34
+ user_input['bp_oldpeak'] = user_input['trestbps'] * (user_input['oldpeak'] + 1)
35
+ user_input['risk_score'] = (user_input['age'] / 50 + user_input['chol'] / 200 + user_input['trestbps'] / 140)
36
+
37
+ # Make prediction
38
+ probabilities = model.predict_proba(user_input)[:, 1]
39
+ predictions = (probabilities >= optimal_threshold).astype(int)
40
+
41
+ # Create results DataFrame
42
+ results = pd.DataFrame({
43
+ 'Prediction': predictions,
44
+ 'Diagnosis': ['Heart Disease' if p == 1 else 'Healthy' for p in predictions],
45
+ 'Probability': probabilities,
46
+ })
47
+
48
+ # Combine with input features for display
49
+ display_data = pd.concat([user_input[['age', 'sex', 'cp', 'trestbps', 'chol']], results], axis=1)
50
+
51
+ return results, display_data
52
+
53
+ except Exception as e:
54
+ st.error(f"Prediction error: {e}")
55
+ return None, None
56
+
57
+
58
+ # Main app interface
59
+ st.title("❤️ Heart Disease Prediction")
60
+
61
+ # Create tabs
62
+ tab1, tab2 ,tab3= st.tabs(["Single Prediction", "Batch Prediction","Data & Model Info"])
63
+
64
+ with tab1:
65
+ st.header("Single Patient Prediction")
66
+
67
+ # Input form
68
+ with st.form("prediction_form"):
69
+ col1, col2 = st.columns(2)
70
+
71
+ with col1:
72
+ st.subheader("Patient Information")
73
+ age = st.slider("Age", 18, 100, 50)
74
+ sex = st.radio("Sex", ["Male (1)", "Female (0)"], index=0)
75
+ cp = st.selectbox("Chest Pain Type",
76
+ ["Typical angina (1)", "Atypical angina (2)",
77
+ "Non-anginal pain (3)", "Asymptomatic (4)"])
78
+ trestbps = st.slider("Resting Blood Pressure (mmHg)", 90, 200, 120)
79
+ chol = st.slider("Serum Cholesterol (mg/dl)", 150, 350, 200)
80
+
81
+ with col2:
82
+ st.subheader("Clinical Measurements")
83
+ fbs = st.radio("Fasting Blood Sugar > 120 mg/dl", ["Yes (1)", "No (0)"], index=1)
84
+ restecg = st.selectbox("Resting ECG Results",
85
+ ["Normal (0)", "ST-T wave abnormality (1)",
86
+ "Left ventricular hypertrophy (2)"])
87
+ thalach = st.slider("Maximum Heart Rate Achieved (bpm)", 60, 200, 150)
88
+ exang = st.radio("Exercise Induced Angina", ["Yes (1)", "No (0)"], index=1)
89
+ oldpeak = st.slider("ST Depression Induced by Exercise", 0.0, 6.0, 1.0, step=0.1)
90
+ slope = st.selectbox("Slope of Peak Exercise ST Segment",
91
+ ["Upsloping (1)", "Flat (2)", "Downsloping (3)"])
92
+ ca = st.slider("Number of Major Vessels", 0, 4, 0)
93
+ thal = st.selectbox("Thalassemia",
94
+ ["Normal (3)", "Fixed defect (6)", "Reversible defect (7)"])
95
+
96
+ submitted = st.form_submit_button("Predict Heart Disease Risk")
97
+
98
+ if submitted:
99
+ # Preprocess inputs
100
+ user_input = pd.DataFrame({
101
+ 'age': [age],
102
+ 'sex': [1 if sex.startswith("Male") else 0],
103
+ 'cp': [int(cp.split("(")[1].strip(")"))],
104
+ 'trestbps': [trestbps],
105
+ 'chol': [chol],
106
+ 'fbs': [1 if fbs.startswith("Yes") else 0],
107
+ 'restecg': [int(restecg.split("(")[1].strip(")"))],
108
+ 'thalach': [thalach],
109
+ 'exang': [1 if exang.startswith("Yes") else 0],
110
+ 'oldpeak': [oldpeak],
111
+ 'slope': [int(slope.split("(")[1].strip(")"))],
112
+ 'ca': [ca],
113
+ 'thal': [int(thal.split("(")[1].strip(")"))],
114
+ })
115
+
116
+ # Get predictions
117
+ results, display_data = predict_heart_disease(user_input)
118
+
119
+ if results is not None:
120
+ st.subheader("Prediction Results")
121
+
122
+ # Display the formatted results
123
+ st.markdown(f"""
124
+ ### Heart Disease Prediction Results
125
+ **Using threshold:** {optimal_threshold:.3f}
126
+ """)
127
+
128
+ # Show detailed results in expandable section
129
+ with st.expander("View Detailed Results"):
130
+ st.dataframe(display_data)
131
+
132
+ # Show risk assessment
133
+ probability = results['Probability'].iloc[0]
134
+ prediction = results['Diagnosis'].iloc[0]
135
+
136
+ if probability > 0.7:
137
+ risk_level = "High"
138
+ recommendation = "Immediate consultation with cardiologist recommended"
139
+ color = "red"
140
+ elif probability > 0.4:
141
+ risk_level = "Medium"
142
+ recommendation = "Further tests recommended"
143
+ color = "orange"
144
+ else:
145
+ risk_level = "Low"
146
+ recommendation = "No immediate concerns, maintain regular checkups"
147
+ color = "green"
148
+
149
+ # Display metrics in columns
150
+ col1, col2, col3 = st.columns(3)
151
+ with col1:
152
+ st.metric("Prediction", prediction)
153
+ with col2:
154
+ st.metric("Probability", f"{probability * 100:.2f}%")
155
+ with col3:
156
+ st.metric("Risk Level", risk_level)
157
+
158
+ # Show recommendation
159
+ st.markdown(f"""
160
+ <div style='background-color:#f0f2f6; padding:10px; border-radius:5px;'>
161
+ <h4 style='color:{color};'>Recommendation: {recommendation}</h4>
162
+ </div>
163
+ """, unsafe_allow_html=True)
164
+
165
+ with tab2:
166
+ st.header("Batch Prediction")
167
+
168
+ uploaded_file = st.file_uploader("Upload CSV file with patient data", type=["csv"])
169
+
170
+ if uploaded_file is not None:
171
+ try:
172
+ test_data = pd.read_csv(uploaded_file)
173
+ st.success("File uploaded successfully!")
174
+
175
+ # Check for required columns
176
+ required_cols = ['age', 'sex', 'cp', 'trestbps', 'chol', 'fbs', 'restecg',
177
+ 'thalach', 'exang', 'oldpeak', 'slope', 'ca', 'thal']
178
+
179
+ missing_cols = [col for col in required_cols if col not in test_data.columns]
180
+ if missing_cols:
181
+ st.error(f"Missing required columns: {', '.join(missing_cols)}")
182
+ else:
183
+ # Get predictions
184
+ results, display_data = predict_heart_disease(test_data)
185
+
186
+ if results is not None:
187
+ st.subheader("Prediction Results")
188
+
189
+ # Show summary statistics
190
+ st.markdown(f"""
191
+ ### Batch Prediction Results
192
+ **Using threshold:** {optimal_threshold:.3f}
193
+ """)
194
+
195
+ # Combine results with original data
196
+ full_results = test_data.copy()
197
+ full_results['Probability'] = results['Probability']
198
+ full_results['Prediction'] = results['Prediction']
199
+ full_results['Diagnosis'] = results['Diagnosis']
200
+
201
+ # Show results in expandable section
202
+ with st.expander("View All Predictions"):
203
+ st.dataframe(full_results)
204
+
205
+ # Show statistics
206
+ st.subheader("Statistics")
207
+ col1, col2, col3 = st.columns(3)
208
+ with col1:
209
+ st.metric("Total Patients", len(full_results))
210
+ with col2:
211
+ st.metric("Heart Disease Cases", full_results['Prediction'].sum())
212
+ with col3:
213
+ st.metric("Healthy Cases", len(full_results) - full_results['Prediction'].sum())
214
+
215
+ # Add download button
216
+ csv = full_results.to_csv(index=False)
217
+ st.download_button(
218
+ "Download Results",
219
+ csv,
220
+ "heart_disease_predictions.csv",
221
+ "text/csv"
222
+ )
223
+
224
+ except Exception as e:
225
+ st.error(f"Error processing file: {e}")
226
+
227
+ sample_data = pd.DataFrame({
228
+ 'age': [52, 63, 45, 67, 58],
229
+ 'sex': [1, 1, 0, 0, 1],
230
+ 'cp': [3, 4, 2, 3, 4],
231
+ 'trestbps': [125, 145, 130, 120, 136],
232
+ 'chol': [212, 233, 204, 228, 319],
233
+ 'fbs': [0, 1, 0, 0, 0],
234
+ 'restecg': [0, 1, 0, 1, 0],
235
+ 'thalach': [168, 150, 172, 129, 152],
236
+ 'exang': [0, 0, 0, 1, 0],
237
+ 'oldpeak': [1.0, 2.3, 1.4, 2.6, 0.0],
238
+ 'slope': [2, 3, 1, 2, 1],
239
+ 'ca': [2, 0, 0, 1, 0],
240
+ 'thal': [3, 3, 3, 7, 3]
241
+ })
242
+
243
+ with tab3:
244
+ st.header("Data & Model Information")
245
+
246
+ st.subheader("Dataset Information")
247
+ st.markdown("""
248
+ The model was trained on the UCI Heart Disease Dataset containing the following features:
249
+ - **Demographic**: Age, Sex
250
+ - **Clinical**: Blood Pressure, Cholesterol, etc.
251
+ - **Electrocardiographic**: Resting ECG, Exercise ST segment, etc.
252
+ """)
253
+
254
+ st.subheader("Sample Data")
255
+ st.dataframe(sample_data)
256
+
257
+ st.subheader("Model Performance")
258
+ st.markdown("""
259
+ - **Accuracy**: 85.2% (on test set)
260
+ - **Precision**: 83.1%
261
+ - **Recall**: 87.5%
262
+ - **F1-score**: 85.2%
263
+
264
+ **📈 Additional Metrics:**
265
+ - **ROC AUC:** `0.909`
266
+ - **Sensitivity (Recall):** `0.95` _(for Heart Disease)_
267
+ - **Specificity:** `0.76` _(for Healthy)_
268
+ - **Balanced Accuracy:** `0.855`
269
+ - **False Positive Rate (FPR):** `0.24`
270
+ - **False Negative Rate (FNR):** `0.05`
271
+ - **Precision (Heart Disease):** `0.80`
272
+ - **Precision (Healthy):** `0.95`
273
+ - **F1 Score (Overall):** `0.85`
274
+ - **Support Size:** `46` patients
275
+ """)
276
+
277
+ st.subheader("Risk Interpretation Guide")
278
+ st.markdown("""
279
+ - **High Risk (>70%)**: Strong recommendation for cardiologist consultation
280
+ - **Medium Risk (40-70%)**: Suggest additional tests
281
+ - **Low Risk (<40%)**: Likely healthy, maintain regular checkups
282
+ """)
283
+
284
+ st.subheader("Terms of Use")
285
+ st.markdown("""
286
+ This tool is for informational purposes only and should not replace
287
+ professional medical advice. Always consult a healthcare provider
288
+ for medical diagnosis and treatment.
289
+ """)
290
+
291
+ # Sidebar with info
292
+ with st.sidebar:
293
+ st.title("❤️ Heart Disease Prediction")
294
+ st.markdown("""
295
+ ## About This App
296
+ This application predicts the likelihood of heart disease based on clinical features using a machine learning model.
297
+
298
+ ### Model Information
299
+ - **Algorithm**: Random Forest Classifier
300
+ - **Dataset**: UCI Heart Disease Dataset
301
+ - **Optimal Threshold**: {:.3f}
302
+ - **Version**: 1.1
303
+
304
+ ### How It Works
305
+ 1. Enter patient details
306
+ 2. Click 'Predict' button
307
+ 3. View prediction results
308
+ """.format(optimal_threshold))
309
+
310
+ st.markdown("---")
311
+ st.markdown("""
312
+ ### Feature Descriptions
313
+ - **Age**: Patient's age in years
314
+ - **Sex**: Gender (1 = Male, 0 = Female)
315
+ - **CP**: Chest pain type (1-4)
316
+ - **Trestbps**: Resting blood pressure (mmHg)
317
+ - **Chol**: Serum cholesterol (mg/dl)
318
+ - **FBS**: Fasting blood sugar > 120 mg/dl
319
+ - **Restecg**: Resting ECG results
320
+ - **Thalach**: Maximum heart rate achieved
321
+ - **Exang**: Exercise induced angina
322
+ - **Oldpeak**: ST depression induced by exercise
323
+ - **Slope**: Slope of peak exercise ST segment
324
+ - **CA**: Number of major vessels colored by fluoroscopy
325
+ - **Thal**: Thalassemia (3,6,7)
326
+ """)
327
+ if __name__ == "__main__":
328
+ st.run()
assets/UciClevelandHeartDisease.csv ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ age,sex,cp,trestbps,chol,fbs,restecg,thalach,exang,oldpeak,slope,ca,thal,target
2
+ 63.0,1.0,1.0,145.0,233.0,1.0,2.0,150.0,0.0,2.3,3.0,0.0,6.0,0
3
+ 67.0,1.0,4.0,160.0,286.0,0.0,2.0,108.0,1.0,1.5,2.0,3.0,3.0,2
4
+ 67.0,1.0,4.0,120.0,229.0,0.0,2.0,129.0,1.0,2.6,2.0,2.0,7.0,1
5
+ 37.0,1.0,3.0,130.0,250.0,0.0,0.0,187.0,0.0,3.5,3.0,0.0,3.0,0
6
+ 41.0,0.0,2.0,130.0,204.0,0.0,2.0,172.0,0.0,1.4,1.0,0.0,3.0,0
7
+ 56.0,1.0,2.0,120.0,236.0,0.0,0.0,178.0,0.0,0.8,1.0,0.0,3.0,0
8
+ 62.0,0.0,4.0,140.0,268.0,0.0,2.0,160.0,0.0,3.6,3.0,2.0,3.0,3
9
+ 57.0,0.0,4.0,120.0,354.0,0.0,0.0,163.0,1.0,0.6,1.0,0.0,3.0,0
10
+ 63.0,1.0,4.0,130.0,254.0,0.0,2.0,147.0,0.0,1.4,2.0,1.0,7.0,2
11
+ 53.0,1.0,4.0,140.0,203.0,1.0,2.0,155.0,1.0,3.1,3.0,0.0,7.0,1
12
+ 57.0,1.0,4.0,140.0,192.0,0.0,0.0,148.0,0.0,0.4,2.0,0.0,6.0,0
13
+ 56.0,0.0,2.0,140.0,294.0,0.0,2.0,153.0,0.0,1.3,2.0,0.0,3.0,0
14
+ 56.0,1.0,3.0,130.0,256.0,1.0,2.0,142.0,1.0,0.6,2.0,1.0,6.0,2
15
+ 44.0,1.0,2.0,120.0,263.0,0.0,0.0,173.0,0.0,0.0,1.0,0.0,7.0,0
16
+ 52.0,1.0,3.0,172.0,199.0,1.0,0.0,162.0,0.0,0.5,1.0,0.0,7.0,0
17
+ 57.0,1.0,3.0,150.0,168.0,0.0,0.0,174.0,0.0,1.6,1.0,0.0,3.0,0
18
+ 48.0,1.0,2.0,110.0,229.0,0.0,0.0,168.0,0.0,1.0,3.0,0.0,7.0,1
19
+ 54.0,1.0,4.0,140.0,239.0,0.0,0.0,160.0,0.0,1.2,1.0,0.0,3.0,0
20
+ 48.0,0.0,3.0,130.0,275.0,0.0,0.0,139.0,0.0,0.2,1.0,0.0,3.0,0
21
+ 49.0,1.0,2.0,130.0,266.0,0.0,0.0,171.0,0.0,0.6,1.0,0.0,3.0,0
22
+ 64.0,1.0,1.0,110.0,211.0,0.0,2.0,144.0,1.0,1.8,2.0,0.0,3.0,0
23
+ 58.0,0.0,1.0,150.0,283.0,1.0,2.0,162.0,0.0,1.0,1.0,0.0,3.0,0
24
+ 58.0,1.0,2.0,120.0,284.0,0.0,2.0,160.0,0.0,1.8,2.0,0.0,3.0,1
25
+ 58.0,1.0,3.0,132.0,224.0,0.0,2.0,173.0,0.0,3.2,1.0,2.0,7.0,3
26
+ 60.0,1.0,4.0,130.0,206.0,0.0,2.0,132.0,1.0,2.4,2.0,2.0,7.0,4
27
+ 50.0,0.0,3.0,120.0,219.0,0.0,0.0,158.0,0.0,1.6,2.0,0.0,3.0,0
28
+ 58.0,0.0,3.0,120.0,340.0,0.0,0.0,172.0,0.0,0.0,1.0,0.0,3.0,0
29
+ 66.0,0.0,1.0,150.0,226.0,0.0,0.0,114.0,0.0,2.6,3.0,0.0,3.0,0
30
+ 43.0,1.0,4.0,150.0,247.0,0.0,0.0,171.0,0.0,1.5,1.0,0.0,3.0,0
31
+ 40.0,1.0,4.0,110.0,167.0,0.0,2.0,114.0,1.0,2.0,2.0,0.0,7.0,3
32
+ 69.0,0.0,1.0,140.0,239.0,0.0,0.0,151.0,0.0,1.8,1.0,2.0,3.0,0
33
+ 60.0,1.0,4.0,117.0,230.0,1.0,0.0,160.0,1.0,1.4,1.0,2.0,7.0,2
34
+ 64.0,1.0,3.0,140.0,335.0,0.0,0.0,158.0,0.0,0.0,1.0,0.0,3.0,1
35
+ 59.0,1.0,4.0,135.0,234.0,0.0,0.0,161.0,0.0,0.5,2.0,0.0,7.0,0
36
+ 44.0,1.0,3.0,130.0,233.0,0.0,0.0,179.0,1.0,0.4,1.0,0.0,3.0,0
37
+ 42.0,1.0,4.0,140.0,226.0,0.0,0.0,178.0,0.0,0.0,1.0,0.0,3.0,0
38
+ 43.0,1.0,4.0,120.0,177.0,0.0,2.0,120.0,1.0,2.5,2.0,0.0,7.0,3
39
+ 57.0,1.0,4.0,150.0,276.0,0.0,2.0,112.0,1.0,0.6,2.0,1.0,6.0,1
40
+ 55.0,1.0,4.0,132.0,353.0,0.0,0.0,132.0,1.0,1.2,2.0,1.0,7.0,3
41
+ 61.0,1.0,3.0,150.0,243.0,1.0,0.0,137.0,1.0,1.0,2.0,0.0,3.0,0
42
+ 65.0,0.0,4.0,150.0,225.0,0.0,2.0,114.0,0.0,1.0,2.0,3.0,7.0,4
43
+ 40.0,1.0,1.0,140.0,199.0,0.0,0.0,178.0,1.0,1.4,1.0,0.0,7.0,0
44
+ 71.0,0.0,2.0,160.0,302.0,0.0,0.0,162.0,0.0,0.4,1.0,2.0,3.0,0
45
+ 59.0,1.0,3.0,150.0,212.0,1.0,0.0,157.0,0.0,1.6,1.0,0.0,3.0,0
46
+ 61.0,0.0,4.0,130.0,330.0,0.0,2.0,169.0,0.0,0.0,1.0,0.0,3.0,1
47
+ 58.0,1.0,3.0,112.0,230.0,0.0,2.0,165.0,0.0,2.5,2.0,1.0,7.0,4
48
+ 51.0,1.0,3.0,110.0,175.0,0.0,0.0,123.0,0.0,0.6,1.0,0.0,3.0,0
49
+ 50.0,1.0,4.0,150.0,243.0,0.0,2.0,128.0,0.0,2.6,2.0,0.0,7.0,4
50
+ 65.0,0.0,3.0,140.0,417.0,1.0,2.0,157.0,0.0,0.8,1.0,1.0,3.0,0
51
+ 53.0,1.0,3.0,130.0,197.0,1.0,2.0,152.0,0.0,1.2,3.0,0.0,3.0,0
52
+ 41.0,0.0,2.0,105.0,198.0,0.0,0.0,168.0,0.0,0.0,1.0,1.0,3.0,0
53
+ 65.0,1.0,4.0,120.0,177.0,0.0,0.0,140.0,0.0,0.4,1.0,0.0,7.0,0
54
+ 44.0,1.0,4.0,112.0,290.0,0.0,2.0,153.0,0.0,0.0,1.0,1.0,3.0,2
55
+ 44.0,1.0,2.0,130.0,219.0,0.0,2.0,188.0,0.0,0.0,1.0,0.0,3.0,0
56
+ 60.0,1.0,4.0,130.0,253.0,0.0,0.0,144.0,1.0,1.4,1.0,1.0,7.0,1
57
+ 54.0,1.0,4.0,124.0,266.0,0.0,2.0,109.0,1.0,2.2,2.0,1.0,7.0,1
58
+ 50.0,1.0,3.0,140.0,233.0,0.0,0.0,163.0,0.0,0.6,2.0,1.0,7.0,1
59
+ 41.0,1.0,4.0,110.0,172.0,0.0,2.0,158.0,0.0,0.0,1.0,0.0,7.0,1
60
+ 54.0,1.0,3.0,125.0,273.0,0.0,2.0,152.0,0.0,0.5,3.0,1.0,3.0,0
61
+ 51.0,1.0,1.0,125.0,213.0,0.0,2.0,125.0,1.0,1.4,1.0,1.0,3.0,0
62
+ 51.0,0.0,4.0,130.0,305.0,0.0,0.0,142.0,1.0,1.2,2.0,0.0,7.0,2
63
+ 46.0,0.0,3.0,142.0,177.0,0.0,2.0,160.0,1.0,1.4,3.0,0.0,3.0,0
64
+ 58.0,1.0,4.0,128.0,216.0,0.0,2.0,131.0,1.0,2.2,2.0,3.0,7.0,1
65
+ 54.0,0.0,3.0,135.0,304.0,1.0,0.0,170.0,0.0,0.0,1.0,0.0,3.0,0
66
+ 54.0,1.0,4.0,120.0,188.0,0.0,0.0,113.0,0.0,1.4,2.0,1.0,7.0,2
67
+ 60.0,1.0,4.0,145.0,282.0,0.0,2.0,142.0,1.0,2.8,2.0,2.0,7.0,2
68
+ 60.0,1.0,3.0,140.0,185.0,0.0,2.0,155.0,0.0,3.0,2.0,0.0,3.0,1
69
+ 54.0,1.0,3.0,150.0,232.0,0.0,2.0,165.0,0.0,1.6,1.0,0.0,7.0,0
70
+ 59.0,1.0,4.0,170.0,326.0,0.0,2.0,140.0,1.0,3.4,3.0,0.0,7.0,2
71
+ 46.0,1.0,3.0,150.0,231.0,0.0,0.0,147.0,0.0,3.6,2.0,0.0,3.0,1
72
+ 65.0,0.0,3.0,155.0,269.0,0.0,0.0,148.0,0.0,0.8,1.0,0.0,3.0,0
73
+ 67.0,1.0,4.0,125.0,254.0,1.0,0.0,163.0,0.0,0.2,2.0,2.0,7.0,3
74
+ 62.0,1.0,4.0,120.0,267.0,0.0,0.0,99.0,1.0,1.8,2.0,2.0,7.0,1
75
+ 65.0,1.0,4.0,110.0,248.0,0.0,2.0,158.0,0.0,0.6,1.0,2.0,6.0,1
76
+ 44.0,1.0,4.0,110.0,197.0,0.0,2.0,177.0,0.0,0.0,1.0,1.0,3.0,1
77
+ 65.0,0.0,3.0,160.0,360.0,0.0,2.0,151.0,0.0,0.8,1.0,0.0,3.0,0
78
+ 60.0,1.0,4.0,125.0,258.0,0.0,2.0,141.0,1.0,2.8,2.0,1.0,7.0,1
79
+ 51.0,0.0,3.0,140.0,308.0,0.0,2.0,142.0,0.0,1.5,1.0,1.0,3.0,0
80
+ 48.0,1.0,2.0,130.0,245.0,0.0,2.0,180.0,0.0,0.2,2.0,0.0,3.0,0
81
+ 58.0,1.0,4.0,150.0,270.0,0.0,2.0,111.0,1.0,0.8,1.0,0.0,7.0,3
82
+ 45.0,1.0,4.0,104.0,208.0,0.0,2.0,148.0,1.0,3.0,2.0,0.0,3.0,0
83
+ 53.0,0.0,4.0,130.0,264.0,0.0,2.0,143.0,0.0,0.4,2.0,0.0,3.0,0
84
+ 39.0,1.0,3.0,140.0,321.0,0.0,2.0,182.0,0.0,0.0,1.0,0.0,3.0,0
85
+ 68.0,1.0,3.0,180.0,274.0,1.0,2.0,150.0,1.0,1.6,2.0,0.0,7.0,3
86
+ 52.0,1.0,2.0,120.0,325.0,0.0,0.0,172.0,0.0,0.2,1.0,0.0,3.0,0
87
+ 44.0,1.0,3.0,140.0,235.0,0.0,2.0,180.0,0.0,0.0,1.0,0.0,3.0,0
88
+ 47.0,1.0,3.0,138.0,257.0,0.0,2.0,156.0,0.0,0.0,1.0,0.0,3.0,0
89
+ 53.0,0.0,3.0,128.0,216.0,0.0,2.0,115.0,0.0,0.0,1.0,0.0,?,0
90
+ 53.0,0.0,4.0,138.0,234.0,0.0,2.0,160.0,0.0,0.0,1.0,0.0,3.0,0
91
+ 51.0,0.0,3.0,130.0,256.0,0.0,2.0,149.0,0.0,0.5,1.0,0.0,3.0,0
92
+ 66.0,1.0,4.0,120.0,302.0,0.0,2.0,151.0,0.0,0.4,2.0,0.0,3.0,0
93
+ 62.0,0.0,4.0,160.0,164.0,0.0,2.0,145.0,0.0,6.2,3.0,3.0,7.0,3
94
+ 62.0,1.0,3.0,130.0,231.0,0.0,0.0,146.0,0.0,1.8,2.0,3.0,7.0,0
95
+ 44.0,0.0,3.0,108.0,141.0,0.0,0.0,175.0,0.0,0.6,2.0,0.0,3.0,0
96
+ 63.0,0.0,3.0,135.0,252.0,0.0,2.0,172.0,0.0,0.0,1.0,0.0,3.0,0
97
+ 52.0,1.0,4.0,128.0,255.0,0.0,0.0,161.0,1.0,0.0,1.0,1.0,7.0,1
98
+ 59.0,1.0,4.0,110.0,239.0,0.0,2.0,142.0,1.0,1.2,2.0,1.0,7.0,2
99
+ 60.0,0.0,4.0,150.0,258.0,0.0,2.0,157.0,0.0,2.6,2.0,2.0,7.0,3
100
+ 52.0,1.0,2.0,134.0,201.0,0.0,0.0,158.0,0.0,0.8,1.0,1.0,3.0,0
101
+ 48.0,1.0,4.0,122.0,222.0,0.0,2.0,186.0,0.0,0.0,1.0,0.0,3.0,0
102
+ 45.0,1.0,4.0,115.0,260.0,0.0,2.0,185.0,0.0,0.0,1.0,0.0,3.0,0
103
+ 34.0,1.0,1.0,118.0,182.0,0.0,2.0,174.0,0.0,0.0,1.0,0.0,3.0,0
104
+ 57.0,0.0,4.0,128.0,303.0,0.0,2.0,159.0,0.0,0.0,1.0,1.0,3.0,0
105
+ 71.0,0.0,3.0,110.0,265.0,1.0,2.0,130.0,0.0,0.0,1.0,1.0,3.0,0
106
+ 49.0,1.0,3.0,120.0,188.0,0.0,0.0,139.0,0.0,2.0,2.0,3.0,7.0,3
107
+ 54.0,1.0,2.0,108.0,309.0,0.0,0.0,156.0,0.0,0.0,1.0,0.0,7.0,0
108
+ 59.0,1.0,4.0,140.0,177.0,0.0,0.0,162.0,1.0,0.0,1.0,1.0,7.0,2
109
+ 57.0,1.0,3.0,128.0,229.0,0.0,2.0,150.0,0.0,0.4,2.0,1.0,7.0,1
110
+ 61.0,1.0,4.0,120.0,260.0,0.0,0.0,140.0,1.0,3.6,2.0,1.0,7.0,2
111
+ 39.0,1.0,4.0,118.0,219.0,0.0,0.0,140.0,0.0,1.2,2.0,0.0,7.0,3
112
+ 61.0,0.0,4.0,145.0,307.0,0.0,2.0,146.0,1.0,1.0,2.0,0.0,7.0,1
113
+ 56.0,1.0,4.0,125.0,249.0,1.0,2.0,144.0,1.0,1.2,2.0,1.0,3.0,1
114
+ 52.0,1.0,1.0,118.0,186.0,0.0,2.0,190.0,0.0,0.0,2.0,0.0,6.0,0
115
+ 43.0,0.0,4.0,132.0,341.0,1.0,2.0,136.0,1.0,3.0,2.0,0.0,7.0,2
116
+ 62.0,0.0,3.0,130.0,263.0,0.0,0.0,97.0,0.0,1.2,2.0,1.0,7.0,2
117
+ 41.0,1.0,2.0,135.0,203.0,0.0,0.0,132.0,0.0,0.0,2.0,0.0,6.0,0
118
+ 58.0,1.0,3.0,140.0,211.0,1.0,2.0,165.0,0.0,0.0,1.0,0.0,3.0,0
119
+ 35.0,0.0,4.0,138.0,183.0,0.0,0.0,182.0,0.0,1.4,1.0,0.0,3.0,0
120
+ 63.0,1.0,4.0,130.0,330.0,1.0,2.0,132.0,1.0,1.8,1.0,3.0,7.0,3
121
+ 65.0,1.0,4.0,135.0,254.0,0.0,2.0,127.0,0.0,2.8,2.0,1.0,7.0,2
122
+ 48.0,1.0,4.0,130.0,256.0,1.0,2.0,150.0,1.0,0.0,1.0,2.0,7.0,3
123
+ 63.0,0.0,4.0,150.0,407.0,0.0,2.0,154.0,0.0,4.0,2.0,3.0,7.0,4
124
+ 51.0,1.0,3.0,100.0,222.0,0.0,0.0,143.0,1.0,1.2,2.0,0.0,3.0,0
125
+ 55.0,1.0,4.0,140.0,217.0,0.0,0.0,111.0,1.0,5.6,3.0,0.0,7.0,3
126
+ 65.0,1.0,1.0,138.0,282.0,1.0,2.0,174.0,0.0,1.4,2.0,1.0,3.0,1
127
+ 45.0,0.0,2.0,130.0,234.0,0.0,2.0,175.0,0.0,0.6,2.0,0.0,3.0,0
128
+ 56.0,0.0,4.0,200.0,288.0,1.0,2.0,133.0,1.0,4.0,3.0,2.0,7.0,3
129
+ 54.0,1.0,4.0,110.0,239.0,0.0,0.0,126.0,1.0,2.8,2.0,1.0,7.0,3
130
+ 44.0,1.0,2.0,120.0,220.0,0.0,0.0,170.0,0.0,0.0,1.0,0.0,3.0,0
131
+ 62.0,0.0,4.0,124.0,209.0,0.0,0.0,163.0,0.0,0.0,1.0,0.0,3.0,0
132
+ 54.0,1.0,3.0,120.0,258.0,0.0,2.0,147.0,0.0,0.4,2.0,0.0,7.0,0
133
+ 51.0,1.0,3.0,94.0,227.0,0.0,0.0,154.0,1.0,0.0,1.0,1.0,7.0,0
134
+ 29.0,1.0,2.0,130.0,204.0,0.0,2.0,202.0,0.0,0.0,1.0,0.0,3.0,0
135
+ 51.0,1.0,4.0,140.0,261.0,0.0,2.0,186.0,1.0,0.0,1.0,0.0,3.0,0
136
+ 43.0,0.0,3.0,122.0,213.0,0.0,0.0,165.0,0.0,0.2,2.0,0.0,3.0,0
137
+ 55.0,0.0,2.0,135.0,250.0,0.0,2.0,161.0,0.0,1.4,2.0,0.0,3.0,0
138
+ 70.0,1.0,4.0,145.0,174.0,0.0,0.0,125.0,1.0,2.6,3.0,0.0,7.0,4
139
+ 62.0,1.0,2.0,120.0,281.0,0.0,2.0,103.0,0.0,1.4,2.0,1.0,7.0,3
140
+ 35.0,1.0,4.0,120.0,198.0,0.0,0.0,130.0,1.0,1.6,2.0,0.0,7.0,1
141
+ 51.0,1.0,3.0,125.0,245.0,1.0,2.0,166.0,0.0,2.4,2.0,0.0,3.0,0
142
+ 59.0,1.0,2.0,140.0,221.0,0.0,0.0,164.0,1.0,0.0,1.0,0.0,3.0,0
143
+ 59.0,1.0,1.0,170.0,288.0,0.0,2.0,159.0,0.0,0.2,2.0,0.0,7.0,1
144
+ 52.0,1.0,2.0,128.0,205.0,1.0,0.0,184.0,0.0,0.0,1.0,0.0,3.0,0
145
+ 64.0,1.0,3.0,125.0,309.0,0.0,0.0,131.0,1.0,1.8,2.0,0.0,7.0,1
146
+ 58.0,1.0,3.0,105.0,240.0,0.0,2.0,154.0,1.0,0.6,2.0,0.0,7.0,0
147
+ 47.0,1.0,3.0,108.0,243.0,0.0,0.0,152.0,0.0,0.0,1.0,0.0,3.0,1
148
+ 57.0,1.0,4.0,165.0,289.0,1.0,2.0,124.0,0.0,1.0,2.0,3.0,7.0,4
149
+ 41.0,1.0,3.0,112.0,250.0,0.0,0.0,179.0,0.0,0.0,1.0,0.0,3.0,0
150
+ 45.0,1.0,2.0,128.0,308.0,0.0,2.0,170.0,0.0,0.0,1.0,0.0,3.0,0
151
+ 60.0,0.0,3.0,102.0,318.0,0.0,0.0,160.0,0.0,0.0,1.0,1.0,3.0,0
152
+ 52.0,1.0,1.0,152.0,298.0,1.0,0.0,178.0,0.0,1.2,2.0,0.0,7.0,0
153
+ 42.0,0.0,4.0,102.0,265.0,0.0,2.0,122.0,0.0,0.6,2.0,0.0,3.0,0
154
+ 67.0,0.0,3.0,115.0,564.0,0.0,2.0,160.0,0.0,1.6,2.0,0.0,7.0,0
155
+ 55.0,1.0,4.0,160.0,289.0,0.0,2.0,145.0,1.0,0.8,2.0,1.0,7.0,4
156
+ 64.0,1.0,4.0,120.0,246.0,0.0,2.0,96.0,1.0,2.2,3.0,1.0,3.0,3
157
+ 70.0,1.0,4.0,130.0,322.0,0.0,2.0,109.0,0.0,2.4,2.0,3.0,3.0,1
158
+ 51.0,1.0,4.0,140.0,299.0,0.0,0.0,173.0,1.0,1.6,1.0,0.0,7.0,1
159
+ 58.0,1.0,4.0,125.0,300.0,0.0,2.0,171.0,0.0,0.0,1.0,2.0,7.0,1
160
+ 60.0,1.0,4.0,140.0,293.0,0.0,2.0,170.0,0.0,1.2,2.0,2.0,7.0,2
161
+ 68.0,1.0,3.0,118.0,277.0,0.0,0.0,151.0,0.0,1.0,1.0,1.0,7.0,0
162
+ 46.0,1.0,2.0,101.0,197.0,1.0,0.0,156.0,0.0,0.0,1.0,0.0,7.0,0
163
+ 77.0,1.0,4.0,125.0,304.0,0.0,2.0,162.0,1.0,0.0,1.0,3.0,3.0,4
164
+ 54.0,0.0,3.0,110.0,214.0,0.0,0.0,158.0,0.0,1.6,2.0,0.0,3.0,0
165
+ 58.0,0.0,4.0,100.0,248.0,0.0,2.0,122.0,0.0,1.0,2.0,0.0,3.0,0
166
+ 48.0,1.0,3.0,124.0,255.0,1.0,0.0,175.0,0.0,0.0,1.0,2.0,3.0,0
167
+ 57.0,1.0,4.0,132.0,207.0,0.0,0.0,168.0,1.0,0.0,1.0,0.0,7.0,0
168
+ 52.0,1.0,3.0,138.0,223.0,0.0,0.0,169.0,0.0,0.0,1.0,?,3.0,0
169
+ 54.0,0.0,2.0,132.0,288.0,1.0,2.0,159.0,1.0,0.0,1.0,1.0,3.0,0
170
+ 35.0,1.0,4.0,126.0,282.0,0.0,2.0,156.0,1.0,0.0,1.0,0.0,7.0,1
171
+ 45.0,0.0,2.0,112.0,160.0,0.0,0.0,138.0,0.0,0.0,2.0,0.0,3.0,0
172
+ 70.0,1.0,3.0,160.0,269.0,0.0,0.0,112.0,1.0,2.9,2.0,1.0,7.0,3
173
+ 53.0,1.0,4.0,142.0,226.0,0.0,2.0,111.0,1.0,0.0,1.0,0.0,7.0,0
174
+ 59.0,0.0,4.0,174.0,249.0,0.0,0.0,143.0,1.0,0.0,2.0,0.0,3.0,1
175
+ 62.0,0.0,4.0,140.0,394.0,0.0,2.0,157.0,0.0,1.2,2.0,0.0,3.0,0
176
+ 64.0,1.0,4.0,145.0,212.0,0.0,2.0,132.0,0.0,2.0,2.0,2.0,6.0,4
177
+ 57.0,1.0,4.0,152.0,274.0,0.0,0.0,88.0,1.0,1.2,2.0,1.0,7.0,1
178
+ 52.0,1.0,4.0,108.0,233.0,1.0,0.0,147.0,0.0,0.1,1.0,3.0,7.0,0
179
+ 56.0,1.0,4.0,132.0,184.0,0.0,2.0,105.0,1.0,2.1,2.0,1.0,6.0,1
180
+ 43.0,1.0,3.0,130.0,315.0,0.0,0.0,162.0,0.0,1.9,1.0,1.0,3.0,0
181
+ 53.0,1.0,3.0,130.0,246.0,1.0,2.0,173.0,0.0,0.0,1.0,3.0,3.0,0
182
+ 48.0,1.0,4.0,124.0,274.0,0.0,2.0,166.0,0.0,0.5,2.0,0.0,7.0,3
183
+ 56.0,0.0,4.0,134.0,409.0,0.0,2.0,150.0,1.0,1.9,2.0,2.0,7.0,2
184
+ 42.0,1.0,1.0,148.0,244.0,0.0,2.0,178.0,0.0,0.8,1.0,2.0,3.0,0
185
+ 59.0,1.0,1.0,178.0,270.0,0.0,2.0,145.0,0.0,4.2,3.0,0.0,7.0,0
186
+ 60.0,0.0,4.0,158.0,305.0,0.0,2.0,161.0,0.0,0.0,1.0,0.0,3.0,1
187
+ 63.0,0.0,2.0,140.0,195.0,0.0,0.0,179.0,0.0,0.0,1.0,2.0,3.0,0
188
+ 42.0,1.0,3.0,120.0,240.0,1.0,0.0,194.0,0.0,0.8,3.0,0.0,7.0,0
189
+ 66.0,1.0,2.0,160.0,246.0,0.0,0.0,120.0,1.0,0.0,2.0,3.0,6.0,2
190
+ 54.0,1.0,2.0,192.0,283.0,0.0,2.0,195.0,0.0,0.0,1.0,1.0,7.0,1
191
+ 69.0,1.0,3.0,140.0,254.0,0.0,2.0,146.0,0.0,2.0,2.0,3.0,7.0,2
192
+ 50.0,1.0,3.0,129.0,196.0,0.0,0.0,163.0,0.0,0.0,1.0,0.0,3.0,0
193
+ 51.0,1.0,4.0,140.0,298.0,0.0,0.0,122.0,1.0,4.2,2.0,3.0,7.0,3
194
+ 43.0,1.0,4.0,132.0,247.0,1.0,2.0,143.0,1.0,0.1,2.0,?,7.0,1
195
+ 62.0,0.0,4.0,138.0,294.0,1.0,0.0,106.0,0.0,1.9,2.0,3.0,3.0,2
196
+ 68.0,0.0,3.0,120.0,211.0,0.0,2.0,115.0,0.0,1.5,2.0,0.0,3.0,0
197
+ 67.0,1.0,4.0,100.0,299.0,0.0,2.0,125.0,1.0,0.9,2.0,2.0,3.0,3
198
+ 69.0,1.0,1.0,160.0,234.0,1.0,2.0,131.0,0.0,0.1,2.0,1.0,3.0,0
199
+ 45.0,0.0,4.0,138.0,236.0,0.0,2.0,152.0,1.0,0.2,2.0,0.0,3.0,0
200
+ 50.0,0.0,2.0,120.0,244.0,0.0,0.0,162.0,0.0,1.1,1.0,0.0,3.0,0
201
+ 59.0,1.0,1.0,160.0,273.0,0.0,2.0,125.0,0.0,0.0,1.0,0.0,3.0,1
202
+ 50.0,0.0,4.0,110.0,254.0,0.0,2.0,159.0,0.0,0.0,1.0,0.0,3.0,0
203
+ 64.0,0.0,4.0,180.0,325.0,0.0,0.0,154.0,1.0,0.0,1.0,0.0,3.0,0
204
+ 57.0,1.0,3.0,150.0,126.0,1.0,0.0,173.0,0.0,0.2,1.0,1.0,7.0,0
205
+ 64.0,0.0,3.0,140.0,313.0,0.0,0.0,133.0,0.0,0.2,1.0,0.0,7.0,0
206
+ 43.0,1.0,4.0,110.0,211.0,0.0,0.0,161.0,0.0,0.0,1.0,0.0,7.0,0
207
+ 45.0,1.0,4.0,142.0,309.0,0.0,2.0,147.0,1.0,0.0,2.0,3.0,7.0,3
208
+ 58.0,1.0,4.0,128.0,259.0,0.0,2.0,130.0,1.0,3.0,2.0,2.0,7.0,3
209
+ 50.0,1.0,4.0,144.0,200.0,0.0,2.0,126.0,1.0,0.9,2.0,0.0,7.0,3
210
+ 55.0,1.0,2.0,130.0,262.0,0.0,0.0,155.0,0.0,0.0,1.0,0.0,3.0,0
211
+ 62.0,0.0,4.0,150.0,244.0,0.0,0.0,154.0,1.0,1.4,2.0,0.0,3.0,1
212
+ 37.0,0.0,3.0,120.0,215.0,0.0,0.0,170.0,0.0,0.0,1.0,0.0,3.0,0
213
+ 38.0,1.0,1.0,120.0,231.0,0.0,0.0,182.0,1.0,3.8,2.0,0.0,7.0,4
214
+ 41.0,1.0,3.0,130.0,214.0,0.0,2.0,168.0,0.0,2.0,2.0,0.0,3.0,0
215
+ 66.0,0.0,4.0,178.0,228.0,1.0,0.0,165.0,1.0,1.0,2.0,2.0,7.0,3
216
+ 52.0,1.0,4.0,112.0,230.0,0.0,0.0,160.0,0.0,0.0,1.0,1.0,3.0,1
217
+ 56.0,1.0,1.0,120.0,193.0,0.0,2.0,162.0,0.0,1.9,2.0,0.0,7.0,0
218
+ 46.0,0.0,2.0,105.0,204.0,0.0,0.0,172.0,0.0,0.0,1.0,0.0,3.0,0
219
+ 46.0,0.0,4.0,138.0,243.0,0.0,2.0,152.0,1.0,0.0,2.0,0.0,3.0,0
220
+ 64.0,0.0,4.0,130.0,303.0,0.0,0.0,122.0,0.0,2.0,2.0,2.0,3.0,0
221
+ 59.0,1.0,4.0,138.0,271.0,0.0,2.0,182.0,0.0,0.0,1.0,0.0,3.0,0
222
+ 41.0,0.0,3.0,112.0,268.0,0.0,2.0,172.0,1.0,0.0,1.0,0.0,3.0,0
223
+ 54.0,0.0,3.0,108.0,267.0,0.0,2.0,167.0,0.0,0.0,1.0,0.0,3.0,0
224
+ 39.0,0.0,3.0,94.0,199.0,0.0,0.0,179.0,0.0,0.0,1.0,0.0,3.0,0
225
+ 53.0,1.0,4.0,123.0,282.0,0.0,0.0,95.0,1.0,2.0,2.0,2.0,7.0,3
226
+ 63.0,0.0,4.0,108.0,269.0,0.0,0.0,169.0,1.0,1.8,2.0,2.0,3.0,1
227
+ 34.0,0.0,2.0,118.0,210.0,0.0,0.0,192.0,0.0,0.7,1.0,0.0,3.0,0
228
+ 47.0,1.0,4.0,112.0,204.0,0.0,0.0,143.0,0.0,0.1,1.0,0.0,3.0,0
229
+ 67.0,0.0,3.0,152.0,277.0,0.0,0.0,172.0,0.0,0.0,1.0,1.0,3.0,0
230
+ 54.0,1.0,4.0,110.0,206.0,0.0,2.0,108.0,1.0,0.0,2.0,1.0,3.0,3
231
+ 66.0,1.0,4.0,112.0,212.0,0.0,2.0,132.0,1.0,0.1,1.0,1.0,3.0,2
232
+ 52.0,0.0,3.0,136.0,196.0,0.0,2.0,169.0,0.0,0.1,2.0,0.0,3.0,0
233
+ 55.0,0.0,4.0,180.0,327.0,0.0,1.0,117.0,1.0,3.4,2.0,0.0,3.0,2
234
+ 49.0,1.0,3.0,118.0,149.0,0.0,2.0,126.0,0.0,0.8,1.0,3.0,3.0,1
235
+ 74.0,0.0,2.0,120.0,269.0,0.0,2.0,121.0,1.0,0.2,1.0,1.0,3.0,0
236
+ 54.0,0.0,3.0,160.0,201.0,0.0,0.0,163.0,0.0,0.0,1.0,1.0,3.0,0
237
+ 54.0,1.0,4.0,122.0,286.0,0.0,2.0,116.0,1.0,3.2,2.0,2.0,3.0,3
238
+ 56.0,1.0,4.0,130.0,283.0,1.0,2.0,103.0,1.0,1.6,3.0,0.0,7.0,2
239
+ 46.0,1.0,4.0,120.0,249.0,0.0,2.0,144.0,0.0,0.8,1.0,0.0,7.0,1
240
+ 49.0,0.0,2.0,134.0,271.0,0.0,0.0,162.0,0.0,0.0,2.0,0.0,3.0,0
241
+ 42.0,1.0,2.0,120.0,295.0,0.0,0.0,162.0,0.0,0.0,1.0,0.0,3.0,0
242
+ 41.0,1.0,2.0,110.0,235.0,0.0,0.0,153.0,0.0,0.0,1.0,0.0,3.0,0
243
+ 41.0,0.0,2.0,126.0,306.0,0.0,0.0,163.0,0.0,0.0,1.0,0.0,3.0,0
244
+ 49.0,0.0,4.0,130.0,269.0,0.0,0.0,163.0,0.0,0.0,1.0,0.0,3.0,0
245
+ 61.0,1.0,1.0,134.0,234.0,0.0,0.0,145.0,0.0,2.6,2.0,2.0,3.0,2
246
+ 60.0,0.0,3.0,120.0,178.0,1.0,0.0,96.0,0.0,0.0,1.0,0.0,3.0,0
247
+ 67.0,1.0,4.0,120.0,237.0,0.0,0.0,71.0,0.0,1.0,2.0,0.0,3.0,2
248
+ 58.0,1.0,4.0,100.0,234.0,0.0,0.0,156.0,0.0,0.1,1.0,1.0,7.0,2
249
+ 47.0,1.0,4.0,110.0,275.0,0.0,2.0,118.0,1.0,1.0,2.0,1.0,3.0,1
250
+ 52.0,1.0,4.0,125.0,212.0,0.0,0.0,168.0,0.0,1.0,1.0,2.0,7.0,3
251
+ 62.0,1.0,2.0,128.0,208.0,1.0,2.0,140.0,0.0,0.0,1.0,0.0,3.0,0
252
+ 57.0,1.0,4.0,110.0,201.0,0.0,0.0,126.0,1.0,1.5,2.0,0.0,6.0,0
253
+ 58.0,1.0,4.0,146.0,218.0,0.0,0.0,105.0,0.0,2.0,2.0,1.0,7.0,1
254
+ 64.0,1.0,4.0,128.0,263.0,0.0,0.0,105.0,1.0,0.2,2.0,1.0,7.0,0
255
+ 51.0,0.0,3.0,120.0,295.0,0.0,2.0,157.0,0.0,0.6,1.0,0.0,3.0,0
256
+ 43.0,1.0,4.0,115.0,303.0,0.0,0.0,181.0,0.0,1.2,2.0,0.0,3.0,0
257
+ 42.0,0.0,3.0,120.0,209.0,0.0,0.0,173.0,0.0,0.0,2.0,0.0,3.0,0
258
+ 67.0,0.0,4.0,106.0,223.0,0.0,0.0,142.0,0.0,0.3,1.0,2.0,3.0,0
259
+ 76.0,0.0,3.0,140.0,197.0,0.0,1.0,116.0,0.0,1.1,2.0,0.0,3.0,0
260
+ 70.0,1.0,2.0,156.0,245.0,0.0,2.0,143.0,0.0,0.0,1.0,0.0,3.0,0
261
+ 57.0,1.0,2.0,124.0,261.0,0.0,0.0,141.0,0.0,0.3,1.0,0.0,7.0,1
262
+ 44.0,0.0,3.0,118.0,242.0,0.0,0.0,149.0,0.0,0.3,2.0,1.0,3.0,0
263
+ 58.0,0.0,2.0,136.0,319.0,1.0,2.0,152.0,0.0,0.0,1.0,2.0,3.0,3
264
+ 60.0,0.0,1.0,150.0,240.0,0.0,0.0,171.0,0.0,0.9,1.0,0.0,3.0,0
265
+ 44.0,1.0,3.0,120.0,226.0,0.0,0.0,169.0,0.0,0.0,1.0,0.0,3.0,0
266
+ 61.0,1.0,4.0,138.0,166.0,0.0,2.0,125.0,1.0,3.6,2.0,1.0,3.0,4
267
+ 42.0,1.0,4.0,136.0,315.0,0.0,0.0,125.0,1.0,1.8,2.0,0.0,6.0,2
268
+ 52.0,1.0,4.0,128.0,204.0,1.0,0.0,156.0,1.0,1.0,2.0,0.0,?,2
269
+ 59.0,1.0,3.0,126.0,218.0,1.0,0.0,134.0,0.0,2.2,2.0,1.0,6.0,2
270
+ 40.0,1.0,4.0,152.0,223.0,0.0,0.0,181.0,0.0,0.0,1.0,0.0,7.0,1
271
+ 42.0,1.0,3.0,130.0,180.0,0.0,0.0,150.0,0.0,0.0,1.0,0.0,3.0,0
272
+ 61.0,1.0,4.0,140.0,207.0,0.0,2.0,138.0,1.0,1.9,1.0,1.0,7.0,1
273
+ 66.0,1.0,4.0,160.0,228.0,0.0,2.0,138.0,0.0,2.3,1.0,0.0,6.0,0
274
+ 46.0,1.0,4.0,140.0,311.0,0.0,0.0,120.0,1.0,1.8,2.0,2.0,7.0,2
275
+ 71.0,0.0,4.0,112.0,149.0,0.0,0.0,125.0,0.0,1.6,2.0,0.0,3.0,0
276
+ 59.0,1.0,1.0,134.0,204.0,0.0,0.0,162.0,0.0,0.8,1.0,2.0,3.0,1
277
+ 64.0,1.0,1.0,170.0,227.0,0.0,2.0,155.0,0.0,0.6,2.0,0.0,7.0,0
278
+ 66.0,0.0,3.0,146.0,278.0,0.0,2.0,152.0,0.0,0.0,2.0,1.0,3.0,0
279
+ 39.0,0.0,3.0,138.0,220.0,0.0,0.0,152.0,0.0,0.0,2.0,0.0,3.0,0
280
+ 57.0,1.0,2.0,154.0,232.0,0.0,2.0,164.0,0.0,0.0,1.0,1.0,3.0,1
281
+ 58.0,0.0,4.0,130.0,197.0,0.0,0.0,131.0,0.0,0.6,2.0,0.0,3.0,0
282
+ 57.0,1.0,4.0,110.0,335.0,0.0,0.0,143.0,1.0,3.0,2.0,1.0,7.0,2
283
+ 47.0,1.0,3.0,130.0,253.0,0.0,0.0,179.0,0.0,0.0,1.0,0.0,3.0,0
284
+ 55.0,0.0,4.0,128.0,205.0,0.0,1.0,130.0,1.0,2.0,2.0,1.0,7.0,3
285
+ 35.0,1.0,2.0,122.0,192.0,0.0,0.0,174.0,0.0,0.0,1.0,0.0,3.0,0
286
+ 61.0,1.0,4.0,148.0,203.0,0.0,0.0,161.0,0.0,0.0,1.0,1.0,7.0,2
287
+ 58.0,1.0,4.0,114.0,318.0,0.0,1.0,140.0,0.0,4.4,3.0,3.0,6.0,4
288
+ 58.0,0.0,4.0,170.0,225.0,1.0,2.0,146.0,1.0,2.8,2.0,2.0,6.0,2
289
+ 58.0,1.0,2.0,125.0,220.0,0.0,0.0,144.0,0.0,0.4,2.0,?,7.0,0
290
+ 56.0,1.0,2.0,130.0,221.0,0.0,2.0,163.0,0.0,0.0,1.0,0.0,7.0,0
291
+ 56.0,1.0,2.0,120.0,240.0,0.0,0.0,169.0,0.0,0.0,3.0,0.0,3.0,0
292
+ 67.0,1.0,3.0,152.0,212.0,0.0,2.0,150.0,0.0,0.8,2.0,0.0,7.0,1
293
+ 55.0,0.0,2.0,132.0,342.0,0.0,0.0,166.0,0.0,1.2,1.0,0.0,3.0,0
294
+ 44.0,1.0,4.0,120.0,169.0,0.0,0.0,144.0,1.0,2.8,3.0,0.0,6.0,2
295
+ 63.0,1.0,4.0,140.0,187.0,0.0,2.0,144.0,1.0,4.0,1.0,2.0,7.0,2
296
+ 63.0,0.0,4.0,124.0,197.0,0.0,0.0,136.0,1.0,0.0,2.0,0.0,3.0,1
297
+ 41.0,1.0,2.0,120.0,157.0,0.0,0.0,182.0,0.0,0.0,1.0,0.0,3.0,0
298
+ 59.0,1.0,4.0,164.0,176.0,1.0,2.0,90.0,0.0,1.0,2.0,2.0,6.0,3
299
+ 57.0,0.0,4.0,140.0,241.0,0.0,0.0,123.0,1.0,0.2,2.0,0.0,7.0,1
300
+ 45.0,1.0,1.0,110.0,264.0,0.0,0.0,132.0,0.0,1.2,2.0,0.0,7.0,1
301
+ 68.0,1.0,4.0,144.0,193.0,1.0,0.0,141.0,0.0,3.4,2.0,2.0,7.0,2
302
+ 57.0,1.0,4.0,130.0,131.0,0.0,0.0,115.0,1.0,1.2,2.0,1.0,7.0,3
303
+ 57.0,0.0,2.0,130.0,236.0,0.0,2.0,174.0,0.0,0.0,2.0,1.0,3.0,1
304
+ 38.0,1.0,3.0,138.0,175.0,0.0,0.0,173.0,0.0,0.0,1.0,?,3.0,0
assets/banner.png ADDED

Git LFS Details

  • SHA256: 1942c8587f7d5a5c8a4c0c286e5159b735d46b5c0ca60efc3311858db0a93168
  • Pointer size: 132 Bytes
  • Size of remote file: 1.72 MB
assets/test_data.csv ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ age,sex,cp,trestbps,chol,fbs,restecg,thalach,exang,oldpeak,slope,ca,thal
2
+ 29,1,1,120,180,0,0,170,0,0.0,1,0,3
3
+ 34,0,2,130,200,1,1,160,1,0.5,2,1,6
4
+ 37,1,3,110,220,0,0,150,0,1.0,1,0,7
5
+ 41,0,4,140,240,1,1,140,1,1.5,2,1,3
6
+ 44,1,1,150,260,0,0,130,0,2.0,1,2,6
7
+ 47,0,2,160,280,1,1,120,1,2.5,2,0,7
8
+ 52,1,3,125,300,0,0,170,0,3.0,1,1,3
9
+ 52,0,4,135,320,1,1,160,1,3.5,2,2,6
10
+ 54,1,1,145,180,0,0,150,0,0.0,1,3,7
11
+ 56,0,2,155,200,1,1,140,1,0.5,2,0,3
12
+ 58,1,3,165,220,0,0,130,0,1.0,1,1,6
13
+ 58,0,4,175,240,1,1,120,1,1.5,2,2,7
14
+ 59,1,1,185,260,0,0,170,0,2.0,1,3,3
15
+ 60,0,2,110,280,1,1,160,1,2.5,2,4,6
16
+ 61,1,3,120,300,0,0,150,0,3.0,1,0,7
17
+ 62,0,4,130,320,1,1,140,1,3.5,2,1,3
18
+ 63,1,1,140,180,0,0,130,0,0.0,1,2,6
19
+ 63,0,2,150,200,1,1,120,1,0.5,2,3,7
20
+ 64,1,3,160,220,0,0,170,0,1.0,1,4,3
21
+ 65,0,4,170,240,1,1,160,1,1.5,2,0,6
22
+ 66,1,1,180,260,0,0,150,0,2.0,1,1,7
23
+ 67,0,2,190,280,1,1,140,1,2.5,2,2,3
24
+ 68,1,3,200,300,0,0,130,0,3.0,1,3,6
25
+ 68,0,4,110,320,1,1,120,1,3.5,2,4,7
26
+ 69,1,1,120,180,0,0,170,0,0.0,1,0,3
27
+ 70,0,2,130,200,1,1,160,1,0.5,2,1,6
28
+ 71,1,3,140,220,0,0,150,0,1.0,1,2,7
29
+ 71,0,4,150,240,1,1,140,1,1.5,2,3,3
30
+ 72,1,1,160,260,0,0,130,0,2.0,1,4,6
31
+ 74,0,2,170,280,1,1,120,1,2.5,2,0,7
32
+ 76,1,3,180,300,0,0,170,0,3.0,1,1,3
33
+ 77,0,4,190,320,1,1,160,1,3.5,2,2,6
34
+ 77,1,1,90,150,0,0,150,0,0.1,1,3,7
35
+ 78,0,2,100,170,1,1,140,1,0.6,2,4,3
36
+ 79,1,3,110,190,0,0,130,0,1.1,1,0,6
37
+ 35,1,4,120,210,1,1,120,1,1.6,2,1,7
38
+ 45,1,3,130,230,0,0,170,0,2.1,1,2,3
39
+ 55,1,2,140,250,1,1,160,1,2.6,2,3,6
40
+ 65,1,1,150,270,0,0,150,0,3.1,1,4,7
41
+ 75,1,4,160,290,1,1,140,1,3.6,2,0,3
42
+ 30,0,1,170,310,0,0,130,0,0.2,1,1,6
43
+ 40,0,2,180,330,1,1,120,1,0.7,2,2,7
44
+ 50,0,3,190,350,0,0,170,0,1.2,1,3,3
45
+ 60,0,4,200,370,1,1,160,1,1.7,2,4,6
46
+ 70,0,1,210,390,0,0,150,0,2.2,1,0,7
47
+ 80,0,2,95,140,1,1,140,1,2.7,2,1,3
48
+ 25,1,3,105,160,0,0,130,0,3.2,1,2,6
49
+ 35,0,4,115,180,1,1,120,1,3.7,2,3,7
50
+ 45,1,1,125,200,0,0,170,0,0.3,1,4,3
51
+ 55,0,2,135,220,1,1,160,1,0.8,2,0,6
52
+ 52,1,3,125,212,0,0,168,0,1.0,2,0,3
53
+ 63,0,2,140,268,1,1,160,1,2.3,1,2,6
54
+ 45,1,1,128,204,0,0,172,0,0.8,2,0,3
55
+ 58,0,4,138,242,0,1,152,1,3.1,1,1,7
56
+ 49,1,2,130,225,0,0,158,0,1.5,2,0,3
models/uci_heart_disease_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:50ed19a94320cb3c8425310a7bf884281c148fd586cf10f3bf0fb8d6025a5021
3
+ size 443747
models/uci_heart_disease_pipeline.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8080a241474239ba64182d50ca9024547c00a4baca440c491e9ea224090db534
3
+ size 442735
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ pandas==2.0.3
2
+ numpy==1.24.3
3
+ scikit-learn==1.6.1
4
+ xgboost==2.1.4
5
+ joblib==1.3.2
6
+ matplotlib==3.7.2
7
+ seaborn==0.12.2
8
+ streamlit==1.44.1
9
+
test_model.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import joblib
3
+
4
+ def test_heart_disease_model(test_data):
5
+ """
6
+ Function to test the trained heart disease prediction model.
7
+ Loads the model and makes predictions on a sample dataset.
8
+ """
9
+ try:
10
+ # model loading
11
+ production_model = joblib.load('models/uci_heart_disease_model.pkl')
12
+ model = production_model['model']
13
+ optimal_threshold = production_model['metadata']['threshold']
14
+
15
+
16
+
17
+ # engineered features to match training data
18
+ test_data['hr_age_ratio'] = test_data['thalach'] / (test_data['age'] + 1e-5)
19
+ test_data['bp_oldpeak'] = test_data['trestbps'] * (test_data['oldpeak'] + 1)
20
+ test_data['risk_score'] = (test_data['age']/50 + test_data['chol']/200 + test_data['trestbps']/140)
21
+
22
+ # Make predictions
23
+ probabilities = model.predict_proba(test_data)[:, 1]
24
+ predictions = (probabilities >= optimal_threshold).astype(int)
25
+
26
+ # results DataFrame
27
+ results = pd.DataFrame({
28
+ 'Prediction': predictions,
29
+ 'Diagnosis': ['Heart Disease' if p == 1 else 'Healthy' for p in predictions],
30
+ 'Probability': probabilities,
31
+ })
32
+
33
+ # data for display
34
+ display_data = pd.concat([test_data[['age', 'sex', 'cp', 'trestbps', 'chol']], results], axis=1)
35
+
36
+ print("=== Heart Disease Prediction Results ===")
37
+ print(f"Using threshold: {optimal_threshold:.3f}\n")
38
+ print(display_data.to_string(index=False))
39
+
40
+ return results
41
+
42
+ except Exception as e:
43
+ print(f"Error testing model: {str(e)}")
44
+ return None
45
+
46
+
47
+ # pf =pd.read_csv('dataset/test_data.csv')
48
+ # test_results = test_heart_disease_model(pf)