File size: 5,877 Bytes
64999ea
fa307e3
64999ea
 
 
 
 
 
 
 
 
fa307e3
 
 
 
 
 
 
 
 
 
64999ea
fa307e3
 
 
 
64999ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c2c75a9
 
 
 
 
64999ea
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import pandas as pd
import joblib
import json
import numpy as np
import os
import streamlit as st

def predict():
#Load model dan metadata
    @st.cache_resource
    def load_model():
        """try:
            with open('src/health_risk_model.pkl', "rb") as f1:
                model = cloudpickle.load(f1)
            with open('src/model_metadata.json', "r") as f:
                metadata = json.load(f)
            return model, metadata
        except Exception as e:
            st.error(f"Error loading model: {str(e)}")
            return None, None"""
        
        try:
            model_path = os.path.join(os.path.dirname(__file__), "..", "src/health_risk_model.pkl")
            with open(model_path, "rb") as f:
                model = joblib.load(f)
            with open('src/model_metadata.json', "r") as f:
                metadata = json.load(f)
            return model, metadata
        except Exception as e:
            st.error(f"Error loading model: {str(e)}")
            return None, None

    model, metadata = load_model()

    # Fungsi prediksi
    def predict_health_risk(input_data: dict) -> dict:
        try:
            if model is None or metadata is None:
                raise ValueError("Model not loaded")
                
            # Konversi ke DataFrame
            input_df = pd.DataFrame([input_data])
            
            # Validasi fitur
            required_features = metadata['feature_names']
            missing_features = [f for f in required_features if f not in input_df.columns]
            if missing_features:
                raise ValueError(f"Missing features: {', '.join(missing_features)}")
            
            # Pastikan urutan kolom
            input_df = input_df[required_features]
            
            # Prediksi
            prediction = model.predict(input_df)[0]
            probabilities = model.predict_proba(input_df)[0]
            
            # Konversi tipe data
            if isinstance(prediction, np.bool_):
                prediction = int(prediction)
            elif isinstance(prediction, bool):
                prediction = 1 if prediction else 0
            
            # Mapping hasil
            # prediction_label = metadata['target_mapping'].get(str(prediction), "unknown")
            if probabilities[1] > 0.2:
                prediction_label = "IYA"
            else :
                prediction_label = "TIDAK"
            return {
                'prediction': prediction_label,
                'prob_ya': float(probabilities[1]),
                'prob_tidak': float(probabilities[0]),
                'success': True
            }
        except Exception as e:
            return {
                'error': str(e),
                'success': False
            }

    # UI Streamlit
    st.title('Prediksi Risiko Kesehatan 🩺')
    st.markdown("""
    Aplikasi ini memprediksi risiko masalah kesehatan berdasarkan profil Anda.
    Silakan isi form di bawah ini:
    """)

    with st.form("prediction_form"):
        col1, col2 = st.columns(2)
        
        with col1:
            st.subheader("Data Demografis")
            age = st.slider("Usia", 18, 100, 40)
            gender = st.selectbox("Jenis Kelamin", ["Male", "Female"])
            annual_income = st.number_input("Pendapatan Tahunan (USD)", 0, 500000, 50000)
        
        with col2:
            st.subheader("Gaya Hidup")
            smokes_per_day = st.slider("Rokok per Hari", 0, 40, 0)
            drinks_per_week = st.slider("Minuman Alkohol per Minggu", 0, 50, 0)
            mental_health = st.selectbox("Status Kesehatan Mental", 
                                        ["Stable", "Unstable", "Critical"])
            social_support = st.selectbox("Dukungan Sosial", 
                                        ["Weak", "Moderate", "Strong"])
        
        submitted = st.form_submit_button("Prediksi Risiko Kesehatan")
        
        if submitted:
            input_data = {
                'age': age,
                'gender': gender,
                'annual_income_usd': annual_income,
                'smokes_per_day': smokes_per_day,
                'drinks_per_week': drinks_per_week,
                'mental_health_status': mental_health,
                'social_support': social_support
            }
            
            with st.spinner('Menganalisis data...'):
                result = predict_health_risk(input_data)
            
            if result.get('success', False):
                st.success("Prediksi Berhasil!")
                
                # Tampilkan hasil
                st.subheader("Hasil Prediksi")
                
                # Progress bar untuk probabilitas
                prob_ya = result['prob_ya']
                col_res1, col_res2 = st.columns(2)
                
                with col_res1:
                    st.metric("Status Risiko Kesehatan", 
                            result['prediction'].upper(),
                            "YA" if result['prediction'] == 'ya' else "TIDAK")
                    
                with col_res2:
                    st.metric("Probabilitas Risiko YA", 
                            f"{prob_ya:.2%}")
                
                # Visualisasi probabilitas
                st.progress(prob_ya, text="Tingkat Risiko Kesehatan")
                
                # Detail input
                st.divider()
                st.subheader("Detail Input Anda")
                input_df = pd.DataFrame([input_data])
                st.dataframe(input_df.T.rename(columns={0: 'Nilai'}), hide_index=True)
                
            else:
                st.error(f"Prediksi gagal: {result.get('error', 'Unknown error')}")

    # Footer
    st.divider()
    st.caption("© 2025 Health Risk Prediction App - Powered by Hugging Face Spaces")

    if __name__ == "main":
        predict()