Spaces:
Runtime error
Runtime error
add data pipeline, baseline, and XGBoost model
Browse files- data/Wellbeing_and_lifestyle_data_Kaggle.csv +0 -0
- notebooks/01_eda.ipynb +48 -0
- src/__pycache__/data_loader.cpython-310.pyc +0 -0
- src/baseline.py +27 -0
- src/data_loader.py +53 -0
- src/train_xgboost.py +50 -0
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/")
|