Abubakari commited on
Commit
0e73bb7
·
verified ·
1 Parent(s): 504a4b3

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +621 -0
app.py ADDED
@@ -0,0 +1,621 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import joblib
4
+ from sklearn.linear_model import LogisticRegression
5
+ from sklearn.ensemble import RandomForestClassifier
6
+ from sklearn.tree import DecisionTreeClassifier
7
+ import time
8
+ import numpy as np
9
+
10
+ import streamlit as st
11
+
12
+ # Using Markdown with custom styles to center the title and add style
13
+ st.markdown("""
14
+ <style>
15
+ .title {
16
+ font-size: 40px;
17
+ font-weight: bold;
18
+ color: #FF4B4B;
19
+ text-align: center;
20
+ margin-bottom: -20px; # Adjusts the spacing below the title
21
+ }
22
+ </style>
23
+ <div class="title">🎓 STUDENT DROPOUT PREDICTION APP 🎓</div>
24
+ """, unsafe_allow_html=True)
25
+
26
+ # Display a banner image
27
+ st.image("banner.webp", use_column_width=True)
28
+
29
+ # Main page description
30
+ st.markdown("""
31
+ This app predicts the likelihood of a student dropping out 🚪.
32
+ Enter the student's details on the left sidebar to see the prediction result.
33
+ The prediction helps in identifying students at risk early, allowing for timely intervention to improve retention rates.
34
+ """)
35
+
36
+ import joblib
37
+
38
+ # Load the models
39
+ decision_tree = joblib.load('age_aware_models/decision_tree_model.joblib')
40
+ logistic_regression = joblib.load('age_aware_models/logistic_regression_model.joblib')
41
+ random_forest = joblib.load('age_aware_models/random_forest_model.joblib')
42
+
43
+ # Define a dictionary of models with their names, actual models, and types
44
+ models = {
45
+ 'Decision Tree': {'model': decision_tree, 'type': 'Decision Tree'},
46
+ 'Logistic Regression': {'model': logistic_regression, 'type': 'Logistic Regression'},
47
+ 'Random Forest': {'model': random_forest, 'type': 'Random Forest'}
48
+ }
49
+
50
+ with st.sidebar:
51
+ # Streamlit UI to select a model
52
+ # Add some design to the header
53
+ st.write("<h2 style='color: #ff5733; text-align: center;'>Select Model</h2>", unsafe_allow_html=True)
54
+
55
+ st.header('')
56
+ # Ensure that this is defined before you try to use `model_name`
57
+ model_name = st.selectbox('Choose a model', list(models.keys()))
58
+
59
+ # Retrieve the selected model and its type from the dictionary after it's been defined
60
+ model = models[model_name]['model']
61
+ model_type = models[model_name]['type']
62
+
63
+ # Additional Streamlit code to display selected model and type or other UI elements
64
+ st.write(f"You have selected: {model_name}")
65
+
66
+
67
+ # Load trained model
68
+ @st.cache_resource
69
+ #def load_model():
70
+ # return LogisticRegression() # Load your trained model here
71
+
72
+ def preprocess_input(input_data, original_feature_names):
73
+ # Create a DataFrame from the input data
74
+ input_df = pd.DataFrame(input_data, index=[0])
75
+
76
+ # Ensure the DataFrame has the correct column structure
77
+ input_df = input_df.reindex(columns=original_feature_names, fill_value=0)
78
+
79
+ return input_df
80
+
81
+ original_feature_names = ['Marital_Status', 'Application_Mode', 'Application_Order', 'Course',
82
+ 'Attendance', 'Previous_Qualification', 'Nationality',
83
+ 'Mother_Qualification', 'Father_Qualification', 'Mother_Occupation',
84
+ 'Father_Occupation', 'Displaced', 'Special_Needs', 'Debtor',
85
+ 'Fees_UpToDate', 'Gender', 'Scholarship_Holder', 'Age', 'International',
86
+ '1st_Sem_Credits', '1st_Sem_Enrolled', '1st_Sem_Evaluations',
87
+ '1st_Sem_Approved', '1st_Sem_Grade', '1st_Sem_No_Evaluations',
88
+ '2nd_Sem_Credits', '2nd_Sem_Enrolled', '2nd_Sem_Evaluations',
89
+ '2nd_Sem_Approved', '2nd_Sem_Grade', '2nd_Sem_No_Evaluations',
90
+ 'Unemployment_Rate', 'Inflation_Rate', 'GDP']
91
+
92
+ def map_and_select(label, mapping_or_value, min_value=None, max_value=None, step=None):
93
+ if isinstance(mapping_or_value, dict):
94
+ # Invert the mapping dictionary
95
+ inverted_mapping = {v: k for k, v in mapping_or_value.items()}
96
+
97
+ # Display the selectbox
98
+ selected_option = st.sidebar.selectbox(label, options=list(inverted_mapping.keys()))
99
+
100
+ # Retrieve numerical value based on the selected option
101
+ selected_value = inverted_mapping[selected_option]
102
+ st.sidebar.write(f"{label} Value:", selected_value)
103
+ return selected_value
104
+ else:
105
+ # Determine the type of input and display accordingly
106
+ if isinstance(mapping_or_value, float):
107
+ # Handle as a slider for float values
108
+ selected_value = st.sidebar.slider(label, min_value=min_value, max_value=max_value, value=mapping_or_value, step=step)
109
+ elif isinstance(mapping_or_value, int):
110
+ # Handle as a number input for int values
111
+ selected_value = st.sidebar.number_input(label, min_value=min_value, max_value=max_value, value=mapping_or_value, step=step)
112
+ else:
113
+ # Display as a text input for non-numeric values
114
+ selected_value = st.sidebar.text_input(label, value=str(mapping_or_value))
115
+
116
+ st.sidebar.write(f"{label}:", selected_value)
117
+ return selected_value
118
+
119
+ def predict_dropout(input_data, model, model_type):
120
+ # Initialize variable to ensure it has a value in all code paths
121
+ dropout_prediction = None
122
+
123
+ # Check the model type to decide on the prediction method
124
+ if model_type == "Logistic Regression" or model_type == "Decision Tree" or model_type == "Random Forest":
125
+ # Use model.predict for predictions
126
+ dropout_prediction = model.predict(input_data)
127
+ else:
128
+ raise ValueError("Unsupported model type.")
129
+
130
+ return dropout_prediction
131
+
132
+ def map_dropout_prediction(prediction):
133
+ if prediction == 1:
134
+ return "Dropout", "🎓", "The model predicts that the student is likely to dropout."
135
+ else:
136
+ return "Not Dropout", "👩‍🎓", "The model predicts that the student is not likely to dropout."
137
+
138
+ marital_mapping = {
139
+ 1: 'Single',
140
+ 2: 'Married',
141
+ 3: 'Widower',
142
+ 4: 'Divorced',
143
+ 5: 'Facto union',
144
+ 6: 'Legally separated'
145
+ }
146
+
147
+
148
+ # Add some design to the header
149
+ st.sidebar.write("<h2 style='color: #ff5733; text-align: center;'>Enter Student Details</h2>", unsafe_allow_html=True)
150
+
151
+
152
+ # Use the map_and_select function to handle mapping and selection for Marital Status
153
+ marital_status = map_and_select('Marital Status', marital_mapping)
154
+
155
+ application_mode_mapping = {
156
+ 1: '1st phase—general contingent',
157
+ 2: 'Ordinance No. 612/93',
158
+ 3: '1st phase—special contingent (Azores Island)',
159
+ 4: 'Holders of other higher courses',
160
+ 5: 'Ordinance No. 854-B/99',
161
+ 6: 'International student (bachelor)',
162
+ 7: '1st phase—special contingent (Madeira Island)',
163
+ 8: '2nd phase—general contingent',
164
+ 9: '3rd phase—general contingent',
165
+ 10: 'Ordinance No. 533-A/99, item b2) (Different Plan)',
166
+ 11: 'Ordinance No. 533-A/99, item b3 (Other Institution)',
167
+ 12: 'Over 23 years old',
168
+ 13: 'Transfer',
169
+ 14: 'Change in course',
170
+ 15: 'Technological specialization diploma holders',
171
+ 16: 'Change in institution/course',
172
+ 17: 'Short cycle diploma holders',
173
+ 18: 'Change in institution/course (International)'
174
+ }
175
+
176
+
177
+ application_mode = map_and_select('Application Mode', application_mode_mapping)
178
+
179
+
180
+ #application_mode = st.sidebar.selectbox('Application Mode', options=range(1, 10)) # Assuming modes 1 through 9
181
+ #st.sidebar.write("application Mode:", application_mode)
182
+
183
+ application_order_mapping = {
184
+ 1: 'First',
185
+ 2: 'Second',
186
+ 3: 'Third',
187
+ 4: 'Fourth',
188
+ 5: 'Fifth',
189
+ 6: 'Sixth',
190
+ 9: 'Ninth',
191
+ 0: 'Zero'
192
+ }
193
+
194
+ application_order = map_and_select('Application Order', application_order_mapping)
195
+
196
+ #application_order = st.sidebar.number_input('Application Order', min_value=0, max_value=10, value=1)
197
+ #st.sidebar.write("application Order:", application_order)
198
+
199
+ courses_mapping = {
200
+ 1: 'Biofuel Production Technologies',
201
+ 2: 'Animation and Multimedia Design',
202
+ 3: 'Social Service (evening attendance)',
203
+ 4: 'Agronomy',
204
+ 5: 'Communication Design',
205
+ 6: 'Veterinary Nursing',
206
+ 7: 'Informatics Engineering',
207
+ 8: 'Equiniculture',
208
+ 9: 'Management',
209
+ 10: 'Social Service',
210
+ 11: 'Tourism',
211
+ 12: 'Nursing',
212
+ 13: 'Oral Hygiene',
213
+ 14: 'Advertising and Marketing Management',
214
+ 15: 'Journalism and Communication',
215
+ 16: 'Basic Education',
216
+ 17: 'Management (evening attendance)'
217
+ }
218
+
219
+ # Use the map_and_select function to handle mapping and selection for Courses
220
+ course = map_and_select('Course', courses_mapping)
221
+
222
+ #course = st.sidebar.selectbox('Course', options=range(1, 100)) # Update range based on actual course codes
223
+ #st.sidebar.write("course:", course)
224
+
225
+ attendance_mapping = {
226
+ 1: 'Daytime',
227
+ 2: 'Evening'
228
+ }
229
+
230
+ # Use the map_and_select function to handle mapping and selection for Daytime/Evening Attendance
231
+ daytime_evening_attendance = map_and_select('Daytime/Evening Attendance', attendance_mapping)
232
+
233
+ #daytime_evening_attendance = st.sidebar.radio('Daytime/Evening Attendance', options=[1, 2], format_func=lambda x: 'Daytime' if x == 1 else 'Evening')
234
+ #st.sidebar.write("Daytime Evening Attendance:", daytime_evening_attendance)
235
+
236
+ previous_qualification_mapping = {
237
+ 1: 'Secondary education',
238
+ 2: 'Higher education—bachelor’s degree',
239
+ 3: 'Higher education—degree',
240
+ 4: 'Higher education—master’s degree',
241
+ 5: 'Higher education—doctorate',
242
+ 6: 'Frequency of higher education',
243
+ 7: '12th year of schooling—not completed',
244
+ 8: '11th year of schooling—not completed',
245
+ 9: 'Other—11th year of schooling',
246
+ 10: '10th year of schooling',
247
+ 11: '10th year of schooling—not completed',
248
+ 12: 'Basic education 3rd cycle (9th/10th/11th year) or equivalent',
249
+ 13: 'Basic education 2nd cycle (6th/7th/8th year) or equivalent',
250
+ 14: 'Technological specialization course',
251
+ 15: 'Higher education—degree (1st cycle)',
252
+ 16: 'Professional higher technical course',
253
+ 17: 'Higher education—master’s degree (2nd cycle)'
254
+ }
255
+
256
+ # Use the map_and_select function to handle mapping and selection for Previous Qualification
257
+ previous_qualification = map_and_select('Previous Qualification', previous_qualification_mapping)
258
+
259
+ ## Output the selected value using st.write
260
+ #st.sidebar.write("Previous Qualification:", selected_previous_qualification_label)
261
+
262
+ #previous_qualification = st.sidebar.selectbox('Previous Qualification', options=range(1, 20)) # Update range based on actual qualifications
263
+ #st.sidebar.write("Previous Qualification:", previous_qualification)
264
+
265
+ nationality_mapping = {
266
+ 1: 'Portuguese', 2: 'German', 3: 'Spanish', 4: 'Italian', 5: 'Dutch', 6: 'English',
267
+ 7: 'Lithuanian', 8: 'Angolan', 9: 'Cape Verdean', 10: 'Guinean', 11: 'Mozambican',
268
+ 12: 'Santomean', 13: 'Turkish', 14: 'Brazilian', 15: 'Romanian', 16: 'Moldova (Republic of)',
269
+ 17: 'Mexican', 18: 'Ukrainian', 19: 'Russian', 20: 'Cuban', 21: 'Colombian'
270
+ }
271
+
272
+ nationality = map_and_select('Nationality', nationality_mapping)
273
+
274
+ #nationality = st.sidebar.selectbox('Nationality', options=range(1, 200)) # Update range based on actual nationality codes
275
+ #st.sidebar.write("nationality:", nationality)
276
+
277
+ qualification_mapping = {
278
+ 1: 'Secondary Education',
279
+ 2: 'Higher Education - Undergraduate',
280
+ 3: 'Higher Education - Undergraduate',
281
+ 4: 'Higher Education - Graduate',
282
+ 5: 'Higher Education - Graduate',
283
+ 6: 'Higher Education - Undergraduate',
284
+ 7: 'Primary Education',
285
+ 8: 'Primary Education',
286
+ 9: 'Primary Education',
287
+ 10: 'Secondary Education',
288
+ 11: 'Secondary Education',
289
+ 12: 'Secondary Education',
290
+ 13: 'Secondary Education',
291
+ 14: 'Secondary Education',
292
+ 15: 'Secondary Education',
293
+ 16: 'Vocational/Technical',
294
+ 17: 'Secondary Education',
295
+ 18: 'Primary Education',
296
+ 19: 'Secondary Education',
297
+ 20: 'Primary Education',
298
+ 21: 'Primary Education',
299
+ 22: 'Secondary Education',
300
+ 23: 'Secondary Education',
301
+ 24: 'Unknown',
302
+ 25: 'Primary Education',
303
+ 26: 'Primary Education',
304
+ 27: 'Primary Education',
305
+ 28: 'Primary Education',
306
+ 29: 'Vocational/Technical',
307
+ 30: 'Higher Education - Undergraduate',
308
+ 31: 'Higher Education - Undergraduate',
309
+ 32: 'Higher Education - Undergraduate',
310
+ 33: 'Higher Education - Graduate',
311
+ 34: 'Higher Education - Graduate'
312
+ }
313
+
314
+ mother_qualification = map_and_select('Mother\'s Qualification', qualification_mapping)
315
+
316
+ #mother_qualification = st.sidebar.selectbox('Mother\'s Qualification', options=range(1, 20))
317
+ #st.sidebar.write("Mother Qualification:", mother_qualification)
318
+
319
+ father_qualification = map_and_select('Father\'s Qualification', qualification_mapping)
320
+
321
+ #father_qualification = st.sidebar.selectbox('Father\'s Qualification', options=range(1, 20))
322
+ #st.sidebar.write("Father Qualification:", father_qualification)
323
+
324
+ occupation_mapping = {
325
+ 1: 'Student',
326
+ 2: 'Representatives of the Legislative Power and Executive Bodies, Directors, Directors and Executive Managers',
327
+ 3: 'Specialists in Intellectual and Scientific Activities',
328
+ 4: 'Intermediate Level Technicians and Professions',
329
+ 5: 'Administrative staff',
330
+ 6: 'Personal Services, Security and Safety Workers, and Sellers',
331
+ 7: 'Farmers and Skilled Workers in Agriculture, Fisheries, and Forestry',
332
+ 8: 'Skilled Workers in Industry, Construction, and Craftsmen',
333
+ 9: 'Installation and Machine Operators and Assembly Workers',
334
+ 10: 'Unskilled Workers',
335
+ 11: 'Armed Forces Professions',
336
+ 12: 'Other Situation',
337
+ 13: '(blank)',
338
+ 14: 'Armed Forces Officers',
339
+ 15: 'Armed Forces Sergeants',
340
+ 16: 'Other Armed Forces personnel',
341
+ 17: 'Directors of administrative and commercial services',
342
+ 18: 'Hotel, catering, trade, and other services directors',
343
+ 19: 'Specialists in the physical sciences, mathematics, engineering, and related techniques',
344
+ 20: 'Health professionals',
345
+ 21: 'Teachers',
346
+ 22: 'Specialists in finance, accounting, administrative organization, and public and commercial relations',
347
+ 23: 'Intermediate level science and engineering technicians and professions',
348
+ 24: 'Technicians and professionals of intermediate level of health',
349
+ 25: 'Intermediate level technicians from legal, social, sports, cultural, and similar services',
350
+ 26: 'Information and communication technology technicians',
351
+ 27: 'Office workers, secretaries in general, and data processing operators',
352
+ 28: 'Data, accounting, statistical, financial services, and registry-related operators',
353
+ 29: 'Other administrative support staff',
354
+ 30: 'Personal service workers',
355
+ 31: 'Sellers',
356
+ 32: 'Personal care workers and the like',
357
+ 33: 'Protection and security services personnel',
358
+ 34: 'Market-oriented farmers and skilled agricultural and animal production workers',
359
+ 35: 'Farmers, livestock keepers, fishermen, hunters and gatherers, and subsistence',
360
+ 36: 'Skilled construction workers and the like, except electricians',
361
+ 37: 'Skilled workers in metallurgy, metalworking, and similar',
362
+ 38: 'Skilled workers in electricity and electronics',
363
+ 39: 'Workers in food processing, woodworking, and clothing and other industries and crafts',
364
+ 40: 'Fixed plant and machine operators',
365
+ 41: 'Assembly workers',
366
+ 42: 'Vehicle drivers and mobile equipment operators',
367
+ 43: 'Unskilled workers in agriculture, animal production, and fisheries and forestry',
368
+ 44: 'Unskilled workers in extractive industry, construction, manufacturing, and transport',
369
+ 45: 'Meal preparation assistants',
370
+ 46: 'Street vendors (except food) and street service providers'
371
+ }
372
+
373
+ mother_occupation = map_and_select('Mother\'s Occupation', occupation_mapping)
374
+
375
+ #mother_occupation = st.sidebar.selectbox('Mother\'s Occupation', options=range(1, 50)) # Update range based on actual occupations
376
+ #st.sidebar.write("Mother Occupation:", mother_occupation)
377
+
378
+ father_occupation = map_and_select('Father\'s Occupation', occupation_mapping)
379
+
380
+ #father_occupation = st.sidebar.selectbox('Father\'s Occupation', options=range(1, 50))
381
+ #st.sidebar.write("Father Occupation:", father_occupation)
382
+
383
+
384
+ displaced_mapping = {
385
+ 1: 'Yes',
386
+ 0: 'No'
387
+ }
388
+
389
+ displaced = map_and_select('Displaced', displaced_mapping)
390
+
391
+ #displaced = st.sidebar.radio('Displaced', options=[0, 1], format_func=lambda x: 'No' if x == 0 else 'Yes')
392
+ #st.sidebar.write("Displaced:", displaced)
393
+
394
+ educational_special_needs_mapping = {
395
+ 1: 'Yes',
396
+ 0: 'No'
397
+ }
398
+
399
+ debtor_mapping = {
400
+ 1: 'Yes',
401
+ 0: 'No'
402
+ }
403
+
404
+ educational_special_needs = map_and_select('Educational Special Needs', educational_special_needs_mapping)
405
+ #st.sidebar.write("Educational Special Needs:", educational_special_needs_mapping[educational_special_needs])
406
+
407
+ debtor = map_and_select('Debtor', debtor_mapping)
408
+ #st.sidebar.write("Debtor:", debtor_mapping[debtor])
409
+
410
+
411
+ #educational_special_needs = st.sidebar.radio('Educational Special Needs', options=[0, 1], format_func=lambda x: 'No' if x == 0 else 'Yes')
412
+ #st.sidebar.write("Educational Special Needs:", educational_special_needs)
413
+
414
+ #debtor = st.sidebar.radio('Debtor', options=[0, 1], format_func=lambda x: 'No' if x == 0 else 'Yes')
415
+ #st.sidebar.write("Debtor:", debtor)
416
+
417
+ # Example usage for single input
418
+
419
+ tuition_fees_up_to_date = map_and_select('Tuition Fees Up to Date', 5000, min_value=0, max_value=10000)
420
+
421
+
422
+ #tuition_fees_up_to_date = st.sidebar.number_input('Tuition Fees Up to Date', min_value=0, max_value=10000, value=5000)
423
+ #st.sidebar.write("tuition_fees_up_to_date:", tuition_fees_up_to_date)
424
+
425
+ # Gender replacement
426
+ gender_mapping = {
427
+ 1: 'male',
428
+ 0: 'female'
429
+ }
430
+
431
+ gender = map_and_select('Gender', gender_mapping)
432
+
433
+ #gender = st.sidebar.radio('Gender', options=[1, 2], format_func=lambda x: 'Male' if x == 1 else 'Female')
434
+ #st.sidebar.write("gender:", gender)
435
+
436
+ scholarship_mapping = {
437
+ 1: 'Yes',
438
+ 0: 'No'
439
+ }
440
+
441
+ scholarship_holder = map_and_select('Scholarship Holder', scholarship_mapping)
442
+ #st.sidebar.write("Scholarship holder:", scholarship_mapping[scholarship_holder])
443
+
444
+ #scholarship_holder = st.sidebar.radio('Scholarship Holder', options=[0, 1], format_func=lambda x: 'No' if x == 0 else 'Yes')
445
+ #st.sidebar.write("Scholarship holder:", scholarship_holder)
446
+
447
+ # Example usage for single input
448
+ age_at_enrollment = map_and_select('Age at Enrollment', 16, min_value=6, max_value=18)
449
+
450
+ #age_at_enrollment = st.sidebar.number_input('Age at Enrollment', min_value=16, max_value=60, value=18)
451
+ #st.sidebar.write("Age at Enrollment:", age_at_enrollment)
452
+
453
+ international_mapping = {
454
+ 1: 'Yes',
455
+ 0: 'No'
456
+ }
457
+
458
+ international = map_and_select('International', international_mapping)
459
+ #st.sidebar.write("International:", international_mapping[international])
460
+
461
+ #international = st.sidebar.radio('International', options=[0, 1], format_func=lambda x: 'No' if x == 0 else 'Yes')
462
+ #st.sidebar.write("International:", international)
463
+
464
+
465
+ unemployment_rate = map_and_select('Unemployment Rate', 10.8, min_value=0.0, max_value=100.0 )
466
+ #st.sidebar.write("unemployment_rate:", unemployment_rate)
467
+
468
+
469
+ #unemployment_rate = st.sidebar.slider('Unemployment Rate', min_value=0.0, max_value=100.0, value=10.8)
470
+ #st.sidebar.write("Unemployment Rate:", unemployment_rate)
471
+
472
+ inflation_rate = map_and_select('Inflation Rate', 1.4, min_value=-10.0, max_value=30.0)
473
+ #st.sidebar.write("inflation_rate:", inflation_rate)
474
+
475
+ # Use map_and_select for the inflation_rate
476
+ #inflation_rate = map_and_select(1, 'Inflation Rate', 1.4)
477
+ #st.sidebar.write("Inflation Rate:", inflation_rate)
478
+
479
+ #inflation_rate = st.sidebar.slider('Inflation Rate', min_value=-10.0, max_value=30.0, value=1.4)
480
+ #st.sidebar.write("Inflation Rate:", inflation_rate)
481
+
482
+ #gdp = st.sidebar.number_input('GDP', min_value=0.0, max_value=100.0, value=1.74)
483
+ #st.sidebar.write("GDP:", gdp)
484
+
485
+ # Use map_and_select for the inflation_rate
486
+ gdp = map_and_select('GDP', 1.74, min_value=0.0, max_value=100.0)
487
+ #st.sidebar.write("Inflation Rate:", gdp)
488
+
489
+ #st.header('Curricular Units 1st Semester')
490
+ #credited_1st_sem = st.sidebar.number_input('Credited Units 1st Semester', min_value=0, step=1)
491
+ #st.sidebar.write("Credited Units 1st Semester:", credited_1st_sem)
492
+ #enrolled_1st_sem = st.sidebar.number_input('Enrolled Units 1st Semester', min_value=0, step=1)
493
+ #st.sidebar.write("Enrolled Units 1st Semester:", enrolled_1st_sem)
494
+ #evaluations_1st_sem = st.sidebar.number_input('Evaluations 1st Semester', min_value=0, step=1)
495
+ #st.sidebar.write("Evaluations 1st Semester:", evaluations_1st_sem)
496
+ #approved_1st_sem = st.sidebar.number_input('Approved Units 1st Semester', min_value=0, step=1)
497
+ #st.sidebar.write("Approved Units 1st Semester:", approved_1st_sem)
498
+ #grade_1st_sem = st.sidebar.number_input('Grade 1st Semester', min_value=0.0, max_value=10.0, step=0.1)
499
+ #st.sidebar.write("Grade 1st Semester:", grade_1st_sem)
500
+ #without_evaluations_1st_sem = st.sidebar.number_input('Units without Evaluations 1st Semester', min_value=0, step=1)
501
+ #st.sidebar.write("GDP:", without_evaluations_1st_sem)
502
+
503
+ # Use map_and_select for the various inputs
504
+ credited_1st_sem = map_and_select('Credited Units 1st Semester', 0, min_value=0, step=1)
505
+ #st.sidebar.write("Credited Units 1st Semester:", credited_1st_sem)
506
+
507
+ enrolled_1st_sem = map_and_select('Enrolled Units 1st Semester', 0, min_value=0, step=1)
508
+ #st.sidebar.write("Enrolled Units 1st Semester:", enrolled_1st_sem)
509
+
510
+ evaluations_1st_sem = map_and_select('Evaluations 1st Semester', 0, min_value=0, step=1)
511
+ #st.sidebar.write("Evaluations 1st Semester:", evaluations_1st_sem)
512
+
513
+ approved_1st_sem = map_and_select('Approved Units 1st Semester', 0, min_value=0, step=1)
514
+ #st.sidebar.write("Approved Units 1st Semester:", approved_1st_sem)
515
+
516
+ grade_1st_sem = map_and_select('Grade 1st Semester', 0.0, min_value=0.0, max_value=10.0, step=0.1)
517
+ #st.sidebar.write("Grade 1st Semester:", grade_1st_sem)
518
+
519
+ without_evaluations_1st_sem = map_and_select('Units without Evaluations 1st Semester', 0, min_value=0, step=1)
520
+ #st.sidebar.write("Units without Evaluations 1st Semester:", without_evaluations_1st_sem)
521
+
522
+
523
+ #st.sidebar.header('Curricular Units 2nd Semester')
524
+ #credited_2nd_sem = st.sidebar.number_input('Credited Units 2nd Semester', min_value=0, step=1)
525
+ #st.sidebar.write("Credited Units 2nd Semester:", credited_2nd_sem)
526
+ #enrolled_2nd_sem = st.sidebar.number_input('Enrolled Units 2nd Semester', min_value=0, step=1)
527
+ #st.sidebar.write("Enrolled Units 2nd Semester:", enrolled_2nd_sem)
528
+ #evaluations_2nd_sem = st.sidebar.number_input('Evaluations 2nd Semester', min_value=0, step=1)
529
+ #st.sidebar.write("Evaluations 2nd Semester:", evaluations_2nd_sem)
530
+ #approved_2nd_sem = st.sidebar.number_input('Approved Units 2nd Semester', min_value=0, step=1)
531
+ #st.sidebar.write("Approved Units 2nd Semester:", approved_2nd_sem)
532
+ #grade_2nd_sem = st.sidebar.number_input('Grade 2nd Semester', min_value=0.0, max_value=10.0, step=0.1)
533
+ #st.sidebar.write("Grade 2nd Semester:", grade_2nd_sem)
534
+ #without_evaluations_2nd_sem = st.sidebar.number_input('Units without Evaluations 2nd Semester', min_value=0, step=1)
535
+ #st.sidebar.write("Units without Evaluations 2nd Semester:", without_evaluations_2nd_sem)
536
+
537
+ # Use map_and_select for the various inputs for the 2nd semester
538
+ credited_2nd_sem = map_and_select('Credited Units 2nd Semester', 0, min_value=0, step=1)
539
+ #st.sidebar.write("Credited Units 2nd Semester:", credited_2nd_sem)
540
+
541
+ enrolled_2nd_sem = map_and_select('Enrolled Units 2nd Semester', 0, min_value=0, step=1)
542
+ #st.sidebar.write("Enrolled Units 2nd Semester:", enrolled_2nd_sem)
543
+
544
+ evaluations_2nd_sem = map_and_select('Evaluations 2nd Semester', 0, min_value=0, step=1)
545
+ #st.sidebar.write("Evaluations 2nd Semester:", evaluations_2nd_sem)
546
+
547
+ approved_2nd_sem = map_and_select('Approved Units 2nd Semester', 0, min_value=0, step=1)
548
+ #st.sidebar.write("Approved Units 2nd Semester:", approved_2nd_sem)
549
+
550
+ grade_2nd_sem = map_and_select('Grade 2nd Semester', 0.0, min_value=0.0, max_value=10.0, step=0.1)
551
+ #st.sidebar.write("Grade 2nd Semester:", grade_2nd_sem)
552
+
553
+ without_evaluations_2nd_sem = map_and_select('Units without Evaluations 2nd Semester', 0, min_value=0, step=1)
554
+ #st.sidebar.write("Units without Evaluations 2nd Semester:", without_evaluations_2nd_sem)
555
+
556
+ input_data = {
557
+ 'Marital_Status': marital_status,
558
+ 'Application_Mode' : application_mode,
559
+ 'Application_Order': application_order,
560
+ 'Course': course,
561
+ 'Attendance': daytime_evening_attendance,
562
+ 'Previous_Qualification': previous_qualification,
563
+ 'Nationality': nationality,
564
+ 'Mother_Qualification': mother_qualification,
565
+ 'Father_Qualification': father_qualification,
566
+ 'Mother_Occupation': mother_occupation,
567
+ 'Father_Occupation': father_occupation,
568
+ 'Displaced': displaced,
569
+ 'Special_Needs': educational_special_needs,
570
+ 'Debtor': debtor,
571
+ 'Fees_UpToDate':tuition_fees_up_to_date,
572
+ 'Gender': gender,
573
+ 'Scholarship_Holder': scholarship_holder,
574
+ 'Age': age_at_enrollment,
575
+ 'International': international,
576
+ '1st_Sem_Credits': credited_1st_sem,
577
+ '1st_Sem_Enrolled': enrolled_1st_sem,
578
+ '1st_Sem_Evaluations': evaluations_1st_sem,
579
+ '1st_Sem_Approved': approved_1st_sem,
580
+ '1st_Sem_Grade': grade_1st_sem,
581
+ '1st_Sem_No_Evaluations': without_evaluations_1st_sem,
582
+ '2nd_Sem_Credits': credited_2nd_sem,
583
+ '2nd_Sem_Enrolled': enrolled_2nd_sem,
584
+ '2nd_Sem_Evaluations': evaluations_2nd_sem,
585
+ '2nd_Sem_Approved': approved_2nd_sem,
586
+ '2nd_Sem_Grade': grade_2nd_sem,
587
+ '2nd_Sem_No_Evaluations': without_evaluations_2nd_sem,
588
+ 'Unemployment_Rate': unemployment_rate,
589
+ 'Inflation_Rate': inflation_rate,
590
+ 'GDP':gdp
591
+ }
592
+
593
+ if st.sidebar.button('Predict Dropout'):
594
+ try:
595
+ with st.spinner("Predicting..."):
596
+ # Simulate a long-running prediction process
597
+ progress_bar = st.progress(0)
598
+ for i in range(5): # Simulate progress
599
+ time.sleep(0.1) # Sleep for a short period to simulate work
600
+ progress_bar.progress((i + 1) * 20)
601
+
602
+ # Convert input dictionary to a 2D array
603
+ input_array = np.array(list(input_data.values())).reshape(1, -1)
604
+
605
+ # Perform prediction
606
+ dropout_label = predict_dropout(input_array, model, model_type)
607
+ dropout_label, emoji, explanation = map_dropout_prediction(dropout_label)
608
+
609
+ # Display the prediction result
610
+ st.success("Prediction complete!")
611
+ st.write(f"Prediction: {dropout_label} {emoji}")
612
+ st.write(explanation)
613
+
614
+ # Display images
615
+ if dropout_label == "Dropout":
616
+ st.image("dropout_image.webp", caption="Image representing a dropout student", use_column_width=True)
617
+ else:
618
+ st.image("not_dropout_image.webp", caption="Image representing a non-dropout student", use_column_width=True)
619
+
620
+ except Exception as e:
621
+ st.error(f"An error occurred: {str(e)}")