Course project for Machine Learning and Data Mining (2024/2025), by Davide Leone and Filippo Camossi.
The project works on the Global Coffee Health Dataset (10,000 people, 16 columns) and asks two questions:
- Can we classify a person's stress level (Low, Medium, High) from health metrics, demographics and coffee habits?
- Do people fall into natural behavioral groups, and how does stress differ between them?
Models are trained on a stratified 60/20/20 split (2,000 test samples) and tuned for macro-F1. Scores below are 5-fold cross-validation on train and validation (8,000 samples), run in MLDM_Project_Improved.ipynb.
| Model | Test accuracy | Test macro-F1 | F1 on High | CV macro-F1 |
|---|---|---|---|---|
| Decision Tree | 87.05% | 0.672 | 0.33 | 0.659 |
| XGBoost | 88.65% | 0.659 | 0.23 | 0.655 |
| SVM (RBF) | 86.65% | 0.663 | 0.29 | 0.646 |
| Bagging | 89.65% | 0.638 | 0.13 | 0.626 |
| Stacking | 90.35% | 0.603 | 0.00 | 0.603 |
| Random Forest | 90.10% | 0.604 | 0.01 | 0.600 |
The full table, with AdaBoost, Gradient Boosting and the neural network, is in the notebook.
What the analysis found:
- Accuracy and macro-F1 rank the models in opposite order. About 70% of the test set is Low stress and about 10% is High. Stacking, Random Forest and the neural network reach the highest accuracy (up to 90.35%) but almost never predict High, while the tuned Decision Tree and XGBoost have the best macro-F1. The top five models by macro-F1 sit within one standard deviation of each other.
- Health status predicts stress.
Health_Issuescarries most of the feature importance in the tree-based models (66% to 91% depending on the model), andHealth_Risk_Score, an engineered score built from four risk factors, adds up to about 16%. Direct caffeine features stay under 5%. A Random Forest trained without the two health features drops from 0.60 to 0.34 macro-F1, close to chance for three classes. - Caffeine shapes the clusters. K-Means with k=3, chosen with the elbow method and silhouette analysis, splits people into heavy consumers (50.0% of the data), moderate consumers (44.4%) and near non-consumers (5.7%).
Caffeine_per_Servingaccounts for 53.2% of the importance in separating them. - The two views fit together. Caffeine is a weak direct predictor, but the consumption profiles differ in their share of High stress: 12.1% for heavy consumers, 7.3% for moderate ones and 6.4% for non-consumers. The data is observational, so this shows an association and says nothing about cause.
Note
One feature, Health_Issues, drives most predictions. Treat the absolute scores as properties of this dataset and not as a claim about how well stress can be predicted in general.
- EDA: target distribution and class imbalance, correlation heatmaps, ANOVA and chi-square tests.
- Feature engineering:
Caffeine_per_Serving(zero-division safe) andHealth_Risk_Score. - Preprocessing: label and one-hot encoding, standard scaling, stratified split.
- Classification: decision tree, random forest, bagging, AdaBoost, gradient boosting, XGBoost, stacking, SVM (linear, RBF, sigmoid) and a scikit-learn MLP.
- Tuning: grid search for the tree, ensemble and SVM models, Optuna (Bayesian optimization) for the neural network.
- Clustering: K-Means, PCA visualization, profiling with scaled deviation heatmaps.
| File | Content |
|---|---|
| MLDM_Project_Improved.ipynb | Final analysis. Start here. |
| archive/MLDM_Project_v1.ipynb | First version. Tunes for accuracy, removes outliers with IQR, trains an unweighted SVM. |
| archive/MLDM_Presentazione.pdf | Course presentation. It reports the v1 results (for example Bagging 90.35%, SVM 87.80%), which differ from the numbers above. |
| global_coffee_health_dataset.csv | Dataset. |
The notebooks and the presentation are written in Italian.
git clone https://github.com/SickCiQuattro/MLDM-Coffee-Health.git
cd MLDM-Coffee-Health
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
jupyter labOpen MLDM_Project_Improved.ipynb and run the cells in order. A full run takes under ten minutes on a laptop and reproduces the stored results (fixed seeds, tested with the pinned versions in requirements.txt).


