sashpol commited on
Commit
c97e168
·
1 Parent(s): 0d89491

add data pipeline, baseline, and XGBoost model

Browse files
data/Wellbeing_and_lifestyle_data_Kaggle.csv ADDED
The diff for this file is too large to render. See raw diff
 
notebooks/01_eda.ipynb ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "e5589eb3",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "ename": "",
11
+ "evalue": "",
12
+ "output_type": "error",
13
+ "traceback": [
14
+ "\u001b[1;31mFailed to start the Kernel. \n",
15
+ "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
16
+ ]
17
+ }
18
+ ],
19
+ "source": [
20
+ "import pandas as pd\n",
21
+ "import matplotlib.pyplot as plt\n",
22
+ "import seaborn as sns\n",
23
+ "\n",
24
+ "df = pd.read_csv('../data/Wellbeing_and_lifestyle_data_Kaggle.csv')\n",
25
+ "print(df.shape)\n",
26
+ "print(df.dtypes)\n",
27
+ "df.head()"
28
+ ]
29
+ },
30
+ {
31
+ "cell_type": "code",
32
+ "execution_count": null,
33
+ "id": "01e7fd72",
34
+ "metadata": {},
35
+ "outputs": [],
36
+ "source": []
37
+ }
38
+ ],
39
+ "metadata": {
40
+ "kernelspec": {
41
+ "display_name": "Python 3 (ipykernel)",
42
+ "language": "python",
43
+ "name": "python3"
44
+ }
45
+ },
46
+ "nbformat": 4,
47
+ "nbformat_minor": 5
48
+ }
src/__pycache__/data_loader.cpython-310.pyc ADDED
Binary file (1.93 kB). View file
 
src/baseline.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from sklearn.dummy import DummyClassifier
3
+ from sklearn.metrics import accuracy_score, f1_score, roc_auc_score
4
+ import sys
5
+ sys.path.insert(0, '.')
6
+ from src.data_loader import load_data, preprocess, split_and_scale
7
+
8
+ def evaluate(model, X, y, split_name):
9
+ preds = model.predict(X)
10
+ proba = model.predict_proba(X)[:, 1]
11
+ acc = accuracy_score(y, preds)
12
+ f1 = f1_score(y, preds, zero_division=0)
13
+ auc = roc_auc_score(y, proba)
14
+ print(f"{split_name} — Accuracy: {acc:.3f} | F1: {f1:.3f} | AUC: {auc:.3f}")
15
+
16
+ if __name__ == '__main__':
17
+ df = load_data()
18
+ X, y, feature_cols = preprocess(df)
19
+ X_train, X_val, X_test, y_train, y_val, y_test, scaler = split_and_scale(X, y)
20
+
21
+ # Majority class baseline
22
+ dummy = DummyClassifier(strategy='most_frequent')
23
+ dummy.fit(X_train, y_train)
24
+ print("=== Baseline (majority class) ===")
25
+ evaluate(dummy, X_train, y_train, "Train")
26
+ evaluate(dummy, X_val, y_val, "Val")
27
+ evaluate(dummy, X_test, y_test, "Test")
src/data_loader.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import numpy as np
3
+ from sklearn.model_selection import train_test_split
4
+ from sklearn.preprocessing import StandardScaler
5
+
6
+ def load_data(path='data/Wellbeing_and_lifestyle_data_Kaggle.csv'):
7
+ df = pd.read_csv(path)
8
+ return df
9
+
10
+ def preprocess(df):
11
+ # Drop timestamp
12
+ df = df.drop(columns=['Timestamp'])
13
+
14
+ # Encode categorical columns
15
+ df['GENDER'] = df['GENDER'].map({'Female': 0, 'Male': 1})
16
+ age_map = {'Less than 20': 0, '21 to 35': 1, '36 to 50': 2, '51 or more': 3}
17
+ df['AGE'] = df['AGE'].map(age_map)
18
+
19
+ # Keep only numeric columns
20
+ df = df.apply(pd.to_numeric, errors='coerce')
21
+
22
+ # Drop rows with nulls
23
+ df = df.dropna()
24
+
25
+ # Create burnout label: bottom 25% of work-life balance = high burnout risk
26
+ threshold = df['WORK_LIFE_BALANCE_SCORE'].quantile(0.25)
27
+ df['BURNOUT_RISK'] = (df['WORK_LIFE_BALANCE_SCORE'] <= threshold).astype(int)
28
+
29
+ # Features and target
30
+ feature_cols = [c for c in df.columns if c not in ['WORK_LIFE_BALANCE_SCORE', 'BURNOUT_RISK']]
31
+ X = df[feature_cols]
32
+ y = df['BURNOUT_RISK']
33
+
34
+ return X, y, feature_cols
35
+
36
+ def split_and_scale(X, y):
37
+ X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)
38
+ X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
39
+
40
+ scaler = StandardScaler()
41
+ X_train = scaler.fit_transform(X_train)
42
+ X_val = scaler.transform(X_val)
43
+ X_test = scaler.transform(X_test)
44
+
45
+ print(f"Train: {X_train.shape}, Val: {X_val.shape}, Test: {X_test.shape}")
46
+ return X_train, X_val, X_test, y_train, y_val, y_test, scaler
47
+
48
+ if __name__ == '__main__':
49
+ df = load_data()
50
+ X, y, feature_cols = preprocess(df)
51
+ X_train, X_val, X_test, y_train, y_val, y_test, scaler = split_and_scale(X, y)
52
+ print(f"Burnout rate: {y.mean():.2%}")
53
+ print(f"Features: {feature_cols}")
src/train_xgboost.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import joblib
3
+ from xgboost import XGBClassifier
4
+ from sklearn.metrics import accuracy_score, f1_score, roc_auc_score
5
+ import sys
6
+ sys.path.insert(0, '.')
7
+ from src.data_loader import load_data, preprocess, split_and_scale
8
+
9
+ def evaluate(model, X, y, split_name):
10
+ preds = model.predict(X)
11
+ proba = model.predict_proba(X)[:, 1]
12
+ acc = accuracy_score(y, preds)
13
+ f1 = f1_score(y, preds)
14
+ auc = roc_auc_score(y, proba)
15
+ print(f"{split_name} — Accuracy: {acc:.3f} | F1: {f1:.3f} | AUC: {auc:.3f}")
16
+ return acc, f1, auc
17
+
18
+ if __name__ == '__main__':
19
+ df = load_data()
20
+ X, y, feature_cols = preprocess(df)
21
+ X_train, X_val, X_test, y_train, y_val, y_test, scaler = split_and_scale(X, y)
22
+
23
+ model = XGBClassifier(
24
+ n_estimators=200,
25
+ max_depth=6,
26
+ learning_rate=0.1,
27
+ subsample=0.8,
28
+ colsample_bytree=0.8,
29
+ use_label_encoder=False,
30
+ eval_metric='logloss',
31
+ early_stopping_rounds=20,
32
+ random_state=42
33
+ )
34
+
35
+ model.fit(
36
+ X_train, y_train,
37
+ eval_set=[(X_val, y_val)],
38
+ verbose=10
39
+ )
40
+
41
+ print("\n=== XGBoost Results ===")
42
+ evaluate(model, X_train, y_train, "Train")
43
+ evaluate(model, X_val, y_val, "Val")
44
+ evaluate(model, X_test, y_test, "Test")
45
+
46
+ # Save model and scaler
47
+ joblib.dump(model, 'models/xgboost_model.pkl')
48
+ joblib.dump(scaler, 'models/scaler.pkl')
49
+ joblib.dump(feature_cols, 'models/feature_cols.pkl')
50
+ print("\nModel saved to models/")