sashpol commited on
Commit
baadd65
·
1 Parent(s): c6e3694

add requirements and app for HF Spaces deployment

Browse files
Files changed (3) hide show
  1. app.py +141 -0
  2. app/app.py +141 -0
  3. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ import numpy as np
4
+ import sys
5
+ sys.path.insert(0, '.')
6
+ from src.data_loader import load_data, preprocess, split_and_scale
7
+ from src.llm_advisor import get_burnout_advice, get_burnout_chat_response
8
+
9
+ # Load models
10
+ @st.cache_resource
11
+ def load_models():
12
+ xgb_model = joblib.load('models/xgboost_model.pkl')
13
+ scaler = joblib.load('models/scaler.pkl')
14
+ feature_cols = joblib.load('models/feature_cols.pkl')
15
+ return xgb_model, scaler, feature_cols
16
+
17
+ def get_top_risk_factors(user_input, feature_cols, model):
18
+ importance = model.feature_importances_
19
+ user_values = [user_input[f] for f in feature_cols]
20
+
21
+ # Weight importance by how extreme the value is (normalized 0-10)
22
+ risk_factors = {}
23
+ for i, col in enumerate(feature_cols):
24
+ val = user_values[i]
25
+ imp = importance[i]
26
+ # Higher stress/shouting/lost vacation = bad, higher sleep/flow = good
27
+ bad_features = ['DAILY_STRESS', 'LOST_VACATION', 'DAILY_SHOUTING', 'BMI_RANGE']
28
+ if col in bad_features:
29
+ score = imp * (val / 10)
30
+ else:
31
+ score = imp * (1 - val / 10)
32
+ risk_factors[col] = score
33
+
34
+ top = sorted(risk_factors.items(), key=lambda x: x[1], reverse=True)[:3]
35
+ return {k: f"score {user_input[k]}/10" for k, _ in top}
36
+
37
+ def main():
38
+ st.set_page_config(page_title="Burnout Tracker", page_icon="🔥", layout="wide")
39
+
40
+ st.title("🔥 Burnout Risk Tracker")
41
+ st.markdown("*Predict your burnout risk and get personalized advice*")
42
+
43
+ xgb_model, scaler, feature_cols = load_models()
44
+
45
+ # Initialize session state
46
+ if 'conversation_history' not in st.session_state:
47
+ st.session_state.conversation_history = []
48
+ if 'risk_score' not in st.session_state:
49
+ st.session_state.risk_score = None
50
+ if 'advice' not in st.session_state:
51
+ st.session_state.advice = None
52
+
53
+ col1, col2 = st.columns([1, 1])
54
+
55
+ with col1:
56
+ st.subheader("Your Daily Lifestyle Inputs")
57
+
58
+ user_input = {}
59
+ user_input['DAILY_STRESS'] = st.slider("Daily Stress Level", 0, 10, 5)
60
+ user_input['SLEEP_HOURS'] = st.slider("Sleep Hours", 0, 10, 7)
61
+ user_input['LOST_VACATION'] = st.slider("Unused Vacation Days", 0, 10, 2)
62
+ user_input['TODO_COMPLETED'] = st.slider("Tasks Completed Today", 0, 10, 5)
63
+ user_input['FLOW'] = st.slider("Flow State at Work", 0, 10, 5)
64
+ user_input['TIME_FOR_PASSION'] = st.slider("Time for Passions", 0, 10, 3)
65
+ user_input['WEEKLY_MEDITATION'] = st.slider("Weekly Meditation Sessions", 0, 10, 2)
66
+ user_input['DAILY_SHOUTING'] = st.slider("Daily Emotional Outbursts", 0, 10, 1)
67
+ user_input['FRUITS_VEGGIES'] = st.slider("Fruits & Veggies Servings", 0, 10, 5)
68
+ user_input['DAILY_STEPS'] = st.slider("Daily Steps (thousands)", 0, 10, 5)
69
+ user_input['SUFFICIENT_INCOME'] = st.slider("Income Sufficiency", 0, 10, 5)
70
+ user_input['SOCIAL_NETWORK'] = st.slider("Social Network Strength", 0, 10, 5)
71
+ user_input['ACHIEVEMENT'] = st.slider("Sense of Achievement", 0, 10, 5)
72
+ user_input['SUPPORTING_OTHERS'] = st.slider("Supporting Others", 0, 10, 5)
73
+ user_input['PLACES_VISITED'] = st.slider("New Places Visited", 0, 10, 3)
74
+ user_input['CORE_CIRCLE'] = st.slider("Close Relationships", 0, 10, 5)
75
+ user_input['PERSONAL_AWARDS'] = st.slider("Personal Awards/Recognition", 0, 10, 3)
76
+ user_input['DONATION'] = st.slider("Charitable Giving", 0, 10, 2)
77
+ user_input['BMI_RANGE'] = st.slider("BMI Range (1=underweight, 4=obese)", 1, 4, 2)
78
+ user_input['LIVE_VISION'] = st.slider("Life Vision Clarity", 0, 10, 5)
79
+ user_input['AGE'] = st.selectbox("Age Range", [0, 1, 2, 3],
80
+ format_func=lambda x: ['<20', '21-35', '36-50', '51+'][x])
81
+ user_input['GENDER'] = st.selectbox("Gender", [0, 1],
82
+ format_func=lambda x: ['Female', 'Male'][x])
83
+
84
+ if st.button("🔍 Assess My Burnout Risk", type="primary"):
85
+ input_array = np.array([[user_input[f] for f in feature_cols]])
86
+ input_scaled = scaler.transform(input_array)
87
+
88
+ risk_score = xgb_model.predict_proba(input_scaled)[0][1]
89
+ st.session_state.risk_score = risk_score
90
+ st.session_state.conversation_history = []
91
+
92
+ top_risk_factors = get_top_risk_factors(user_input, feature_cols, xgb_model)
93
+
94
+ with st.spinner("Getting personalized advice from AI coach..."):
95
+ advice = get_burnout_advice(risk_score, top_risk_factors, user_input)
96
+ st.session_state.advice = advice
97
+ st.session_state.risk_context = f"Risk score: {risk_score:.1%}, Top factors: {top_risk_factors}"
98
+
99
+ with col2:
100
+ if st.session_state.risk_score is not None:
101
+ risk_score = st.session_state.risk_score
102
+
103
+ # Risk meter
104
+ st.subheader("Your Burnout Risk")
105
+ if risk_score > 0.7:
106
+ st.error(f"🚨 High Risk: {risk_score:.1%}")
107
+ elif risk_score > 0.4:
108
+ st.warning(f"⚠️ Moderate Risk: {risk_score:.1%}")
109
+ else:
110
+ st.success(f"✅ Low Risk: {risk_score:.1%}")
111
+
112
+ st.progress(float(risk_score))
113
+
114
+ # AI advice
115
+ st.subheader("AI Coach Advice")
116
+ st.markdown(st.session_state.advice)
117
+
118
+ st.divider()
119
+
120
+ # Chat
121
+ st.subheader("💬 Chat with Your AI Coach")
122
+
123
+ for msg in st.session_state.conversation_history:
124
+ if msg['role'] == 'user':
125
+ st.chat_message("user").write(msg['content'])
126
+ else:
127
+ st.chat_message("assistant").write(msg['content'])
128
+
129
+ if prompt := st.chat_input("Ask your coach anything..."):
130
+ st.chat_message("user").write(prompt)
131
+ with st.spinner("Thinking..."):
132
+ response, st.session_state.conversation_history = get_burnout_chat_response(
133
+ st.session_state.conversation_history,
134
+ prompt,
135
+ st.session_state.risk_context
136
+ )
137
+ st.chat_message("assistant").write(response)
138
+ st.rerun()
139
+
140
+ if __name__ == '__main__':
141
+ main()
app/app.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ import numpy as np
4
+ import sys
5
+ sys.path.insert(0, '.')
6
+ from src.data_loader import load_data, preprocess, split_and_scale
7
+ from src.llm_advisor import get_burnout_advice, get_burnout_chat_response
8
+
9
+ # Load models
10
+ @st.cache_resource
11
+ def load_models():
12
+ xgb_model = joblib.load('models/xgboost_model.pkl')
13
+ scaler = joblib.load('models/scaler.pkl')
14
+ feature_cols = joblib.load('models/feature_cols.pkl')
15
+ return xgb_model, scaler, feature_cols
16
+
17
+ def get_top_risk_factors(user_input, feature_cols, model):
18
+ importance = model.feature_importances_
19
+ user_values = [user_input[f] for f in feature_cols]
20
+
21
+ # Weight importance by how extreme the value is (normalized 0-10)
22
+ risk_factors = {}
23
+ for i, col in enumerate(feature_cols):
24
+ val = user_values[i]
25
+ imp = importance[i]
26
+ # Higher stress/shouting/lost vacation = bad, higher sleep/flow = good
27
+ bad_features = ['DAILY_STRESS', 'LOST_VACATION', 'DAILY_SHOUTING', 'BMI_RANGE']
28
+ if col in bad_features:
29
+ score = imp * (val / 10)
30
+ else:
31
+ score = imp * (1 - val / 10)
32
+ risk_factors[col] = score
33
+
34
+ top = sorted(risk_factors.items(), key=lambda x: x[1], reverse=True)[:3]
35
+ return {k: f"score {user_input[k]}/10" for k, _ in top}
36
+
37
+ def main():
38
+ st.set_page_config(page_title="Burnout Tracker", page_icon="🔥", layout="wide")
39
+
40
+ st.title("🔥 Burnout Risk Tracker")
41
+ st.markdown("*Predict your burnout risk and get personalized advice*")
42
+
43
+ xgb_model, scaler, feature_cols = load_models()
44
+
45
+ # Initialize session state
46
+ if 'conversation_history' not in st.session_state:
47
+ st.session_state.conversation_history = []
48
+ if 'risk_score' not in st.session_state:
49
+ st.session_state.risk_score = None
50
+ if 'advice' not in st.session_state:
51
+ st.session_state.advice = None
52
+
53
+ col1, col2 = st.columns([1, 1])
54
+
55
+ with col1:
56
+ st.subheader("Your Daily Lifestyle Inputs")
57
+
58
+ user_input = {}
59
+ user_input['DAILY_STRESS'] = st.slider("Daily Stress Level", 0, 10, 5)
60
+ user_input['SLEEP_HOURS'] = st.slider("Sleep Hours", 0, 10, 7)
61
+ user_input['LOST_VACATION'] = st.slider("Unused Vacation Days", 0, 10, 2)
62
+ user_input['TODO_COMPLETED'] = st.slider("Tasks Completed Today", 0, 10, 5)
63
+ user_input['FLOW'] = st.slider("Flow State at Work", 0, 10, 5)
64
+ user_input['TIME_FOR_PASSION'] = st.slider("Time for Passions", 0, 10, 3)
65
+ user_input['WEEKLY_MEDITATION'] = st.slider("Weekly Meditation Sessions", 0, 10, 2)
66
+ user_input['DAILY_SHOUTING'] = st.slider("Daily Emotional Outbursts", 0, 10, 1)
67
+ user_input['FRUITS_VEGGIES'] = st.slider("Fruits & Veggies Servings", 0, 10, 5)
68
+ user_input['DAILY_STEPS'] = st.slider("Daily Steps (thousands)", 0, 10, 5)
69
+ user_input['SUFFICIENT_INCOME'] = st.slider("Income Sufficiency", 0, 10, 5)
70
+ user_input['SOCIAL_NETWORK'] = st.slider("Social Network Strength", 0, 10, 5)
71
+ user_input['ACHIEVEMENT'] = st.slider("Sense of Achievement", 0, 10, 5)
72
+ user_input['SUPPORTING_OTHERS'] = st.slider("Supporting Others", 0, 10, 5)
73
+ user_input['PLACES_VISITED'] = st.slider("New Places Visited", 0, 10, 3)
74
+ user_input['CORE_CIRCLE'] = st.slider("Close Relationships", 0, 10, 5)
75
+ user_input['PERSONAL_AWARDS'] = st.slider("Personal Awards/Recognition", 0, 10, 3)
76
+ user_input['DONATION'] = st.slider("Charitable Giving", 0, 10, 2)
77
+ user_input['BMI_RANGE'] = st.slider("BMI Range (1=underweight, 4=obese)", 1, 4, 2)
78
+ user_input['LIVE_VISION'] = st.slider("Life Vision Clarity", 0, 10, 5)
79
+ user_input['AGE'] = st.selectbox("Age Range", [0, 1, 2, 3],
80
+ format_func=lambda x: ['<20', '21-35', '36-50', '51+'][x])
81
+ user_input['GENDER'] = st.selectbox("Gender", [0, 1],
82
+ format_func=lambda x: ['Female', 'Male'][x])
83
+
84
+ if st.button("🔍 Assess My Burnout Risk", type="primary"):
85
+ input_array = np.array([[user_input[f] for f in feature_cols]])
86
+ input_scaled = scaler.transform(input_array)
87
+
88
+ risk_score = xgb_model.predict_proba(input_scaled)[0][1]
89
+ st.session_state.risk_score = risk_score
90
+ st.session_state.conversation_history = []
91
+
92
+ top_risk_factors = get_top_risk_factors(user_input, feature_cols, xgb_model)
93
+
94
+ with st.spinner("Getting personalized advice from AI coach..."):
95
+ advice = get_burnout_advice(risk_score, top_risk_factors, user_input)
96
+ st.session_state.advice = advice
97
+ st.session_state.risk_context = f"Risk score: {risk_score:.1%}, Top factors: {top_risk_factors}"
98
+
99
+ with col2:
100
+ if st.session_state.risk_score is not None:
101
+ risk_score = st.session_state.risk_score
102
+
103
+ # Risk meter
104
+ st.subheader("Your Burnout Risk")
105
+ if risk_score > 0.7:
106
+ st.error(f"🚨 High Risk: {risk_score:.1%}")
107
+ elif risk_score > 0.4:
108
+ st.warning(f"⚠️ Moderate Risk: {risk_score:.1%}")
109
+ else:
110
+ st.success(f"✅ Low Risk: {risk_score:.1%}")
111
+
112
+ st.progress(float(risk_score))
113
+
114
+ # AI advice
115
+ st.subheader("AI Coach Advice")
116
+ st.markdown(st.session_state.advice)
117
+
118
+ st.divider()
119
+
120
+ # Chat
121
+ st.subheader("💬 Chat with Your AI Coach")
122
+
123
+ for msg in st.session_state.conversation_history:
124
+ if msg['role'] == 'user':
125
+ st.chat_message("user").write(msg['content'])
126
+ else:
127
+ st.chat_message("assistant").write(msg['content'])
128
+
129
+ if prompt := st.chat_input("Ask your coach anything..."):
130
+ st.chat_message("user").write(prompt)
131
+ with st.spinner("Thinking..."):
132
+ response, st.session_state.conversation_history = get_burnout_chat_response(
133
+ st.session_state.conversation_history,
134
+ prompt,
135
+ st.session_state.risk_context
136
+ )
137
+ st.chat_message("assistant").write(response)
138
+ st.rerun()
139
+
140
+ if __name__ == '__main__':
141
+ main()
requirements.txt CHANGED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ xgboost
3
+ scikit-learn
4
+ pandas
5
+ numpy
6
+ groq
7
+ python-dotenv
8
+ joblib