Repository navigation
Home
Multiclass wine-quality prediction (3–9) from 11 physicochemical attributes, on the combined UCI Wine Quality dataset (red + white, 6,497 samples).
Classification experiments comparing KNN, SVM, and Decision Tree baselines against GridSearchCV-tuned versions of the same models plus a tuned Random Forest.
winequality-red.csv + winequality-white.csv (Cortez et al., 2009, Vinho Verde wine samples), concatenated with a binary type indicator and modeled jointly as one multiclass quality-prediction problem. Stratified 80/20 train/test split, random_state=42.
Class imbalance (test set, n=1,300): quality 3 has 6 samples, quality 9 has 1 sample, while qualities 5 and 6 together account for 995 of 1,300 (77%). This makes macro-averaged metrics far more informative than raw accuracy for judging performance on the tails — see Model Comparison & Evaluation Methodology for why accuracy alone is a misleading headline number here.
| Model | Accuracy | Macro F1 | Weighted F1 |
|---|---|---|---|
| KNN (baseline) | 0.559 | 0.28 | 0.55 |
| SVM (baseline) | 0.572 | 0.24 | 0.54 |
| Decision Tree (baseline) | 0.595 | 0.33 | 0.59 |
| Tuned SVM | 0.585 | 0.29 | 0.57 |
| Tuned Decision Tree | 0.595 | 0.33 | 0.59 |
| Tuned KNN | 0.670 | 0.39 | 0.66 |
| Tuned Random Forest | 0.692 | 0.39 | 0.68 |
Tuned Random Forest wins on both accuracy and macro-F1, but macro-F1 (0.39) is far below its accuracy (0.69) — it's essentially unable to classify the rarest classes (quality 3: precision/recall/F1 all 0.00; quality 9: 0.00, n=1). Tuning materially helped every model family except Decision Tree, which was already at its ceiling with default hyperparameters (identical 0.595 before and after tuning).
Best-performing model — note the near-complete inability to classify quality 3, 4, and 9 despite strong performance on 5-7.
Baseline decision tree — identical accuracy before and after GridSearchCV tuning.
Which physicochemical attributes drive the decision tree's splits.
flowchart TD
Red["winequality-red.csv"] --> Combine["main.py — concat + type flag"]
White["winequality-white.csv"] --> Combine
Combine --> Split["Stratified train/test split 80/20 + StandardScaler"]
Split --> Baseline["Baseline: KNN / SVM / Decision Tree"]
Split --> Tuned["GridSearchCV-tuned: Random Forest / KNN / SVM / Decision Tree"]
Baseline --> Tables["Tables/ — classification reports"]
Tuned --> Tables
Baseline --> Plots["Plots/ — confusion matrices + feature importance"]
Tuned --> Plots